triangle3dTex.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #define VC_TERM_SCALE_DOWN_FACTOR 10
  2. #include "vc.c"
  3. #include "./assets/tsodinPog.c"
  4. #include "./assets/oldstone.c"
  5. #include "./assets/lavastone.c"
  6. #define WIDTH 960
  7. #define HEIGHT 720
  8. static uint32_t pixels1[WIDTH*HEIGHT];
  9. static float zbuffer1[WIDTH*HEIGHT];
  10. static uint32_t pixels2[WIDTH*HEIGHT];
  11. static float zbuffer2[WIDTH*HEIGHT];
  12. typedef struct {
  13. float x, y;
  14. } Vector2;
  15. static Vector2 make_vector2(float x, float y)
  16. {
  17. Vector2 v2;
  18. v2.x = x;
  19. v2.y = y;
  20. return v2;
  21. }
  22. typedef struct {
  23. float x, y, z;
  24. } Vector3;
  25. static Vector3 make_vector3(float x, float y, float z)
  26. {
  27. Vector3 v3;
  28. v3.x = x;
  29. v3.y = y;
  30. v3.z = z;
  31. return v3;
  32. }
  33. static Vector2 project_3d_2d(Vector3 v3)
  34. {
  35. return make_vector2(v3.x / v3.z, v3.y / v3.z);
  36. }
  37. static Vector2 project_2d_scr(Vector2 v2)
  38. {
  39. return make_vector2((v2.x + 1)/2*WIDTH, (1 - (v2.y + 1)/2)*HEIGHT);
  40. }
  41. static float global_time = 1.0;
  42. #define PI 3.14159265359
  43. float sinf(float);
  44. float cosf(float);
  45. Olivec_Canvas vc_render(float dt)
  46. {
  47. global_time += dt;
  48. Olivec_Canvas oc1 = olivec_canvas(pixels1, WIDTH, HEIGHT, WIDTH);
  49. olivec_fill(oc1, 0xFF181818);
  50. Olivec_Canvas zb1 = olivec_canvas((uint32_t*)zbuffer1, WIDTH, HEIGHT, WIDTH);
  51. olivec_fill(zb1, 0);
  52. Olivec_Canvas oldstone = olivec_canvas(oldstone_pixels, oldstone_width, oldstone_height, oldstone_width);
  53. Olivec_Canvas lavastone = olivec_canvas(lavastone_pixels, lavastone_width, lavastone_height, lavastone_width);
  54. float z = 1.5;
  55. float t = 0.75;
  56. {
  57. Vector3 v1 = make_vector3(cosf(global_time)*t, -t, z + sinf(global_time)*t);
  58. Vector3 v2 = make_vector3(cosf(global_time + PI)*t, -t, z + sinf(global_time + PI)*t);
  59. Vector3 v3 = make_vector3(0, t, z);
  60. Vector2 p1 = project_2d_scr(project_3d_2d(v1));
  61. Vector2 p2 = project_2d_scr(project_3d_2d(v2));
  62. Vector2 p3 = project_2d_scr(project_3d_2d(v3));
  63. olivec_triangle3uv_bilinear(
  64. oc1,
  65. p1.x, p1.y, p2.x, p2.y, p3.x, p3.y,
  66. 0/v1.z, 1/v1.z,
  67. 1/v2.z, 1/v2.z,
  68. 0.5/v3.z, 0/v3.z,
  69. 1/v1.z, 1/v2.z, 1/v3.z,
  70. oldstone
  71. );
  72. olivec_triangle3z(zb1, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 1.0f/v1.z, 1.0f/v2.z, 1.0f/v3.z);
  73. }
  74. Olivec_Canvas oc2 = olivec_canvas(pixels2, WIDTH, HEIGHT, WIDTH);
  75. olivec_fill(oc2, 0xFF181818);
  76. Olivec_Canvas zb2 = olivec_canvas((uint32_t*)zbuffer2, WIDTH, HEIGHT, WIDTH);
  77. olivec_fill(zb2, 0);
  78. {
  79. Vector3 v1 = make_vector3(cosf(global_time + PI/2)*t, -t, z + sinf(global_time + PI/2)*t);
  80. Vector3 v2 = make_vector3(cosf(global_time + PI + PI/2)*t, -t, z + sinf(global_time + PI + PI/2)*t);
  81. Vector3 v3 = make_vector3(0, t, z);
  82. Vector2 p1 = project_2d_scr(project_3d_2d(v1));
  83. Vector2 p2 = project_2d_scr(project_3d_2d(v2));
  84. Vector2 p3 = project_2d_scr(project_3d_2d(v3));
  85. olivec_triangle3uv_bilinear(
  86. oc2,
  87. p1.x, p1.y, p2.x, p2.y, p3.x, p3.y,
  88. 0/v1.z, 1/v1.z,
  89. 1/v2.z, 1/v2.z,
  90. 0.5/v3.z, 0/v3.z,
  91. 1/v1.z, 1/v2.z, 1/v3.z,
  92. lavastone
  93. );
  94. olivec_triangle3z(zb2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 1.0f/v1.z, 1.0f/v2.z, 1.0f/v3.z);
  95. }
  96. for (size_t y = 0; y < HEIGHT; ++y) {
  97. for (size_t x = 0; x < WIDTH; ++x) {
  98. float z1 = *(float*)&OLIVEC_PIXEL(zb1, x, y);
  99. float z2 = *(float*)&OLIVEC_PIXEL(zb2, x, y);
  100. if (z1 < z2) {
  101. OLIVEC_PIXEL(oc1, x, y) = OLIVEC_PIXEL(oc2, x, y);
  102. z1 = z2;
  103. }
  104. z1 = 1.0f/z1;
  105. if (z1 >= 1.0) {
  106. z1 -= 1.0;
  107. uint32_t v = z1*255;
  108. if (v > 255) v = 255;
  109. olivec_blend_color(&OLIVEC_PIXEL(oc1, x, y), (v<<(3*8)));
  110. }
  111. }
  112. }
  113. return oc1;
  114. }