triangle3d.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // TODO: we have too many triangle examples.
  2. // Let's squash most of them into a single one
  3. #include "vc.c"
  4. #define WIDTH 960
  5. #define HEIGHT 720
  6. static uint32_t pixels1[WIDTH*HEIGHT];
  7. static float zbuffer1[WIDTH*HEIGHT];
  8. static uint32_t pixels2[WIDTH*HEIGHT];
  9. static float zbuffer2[WIDTH*HEIGHT];
  10. typedef struct {
  11. float x, y;
  12. } Vector2;
  13. Vector2 make_vector2(float x, float y)
  14. {
  15. Vector2 v2;
  16. v2.x = x;
  17. v2.y = y;
  18. return v2;
  19. }
  20. typedef struct {
  21. float x, y, z;
  22. } Vector3;
  23. static Vector3 make_vector3(float x, float y, float z)
  24. {
  25. Vector3 v3;
  26. v3.x = x;
  27. v3.y = y;
  28. v3.z = z;
  29. return v3;
  30. }
  31. static Vector2 project_3d_2d(Vector3 v3)
  32. {
  33. return make_vector2(v3.x / v3.z, v3.y / v3.z);
  34. }
  35. static Vector2 project_2d_scr(Vector2 v2)
  36. {
  37. return make_vector2((v2.x + 1)/2*WIDTH, (1 - (v2.y + 1)/2)*HEIGHT);
  38. }
  39. static float global_time = 1.0;
  40. #define PI 3.14159265359
  41. float sinf(float);
  42. float cosf(float);
  43. Olivec_Canvas vc_render(float dt)
  44. {
  45. global_time += dt;
  46. Olivec_Canvas oc1 = olivec_canvas(pixels1, WIDTH, HEIGHT, WIDTH);
  47. olivec_fill(oc1, 0xFF181818);
  48. Olivec_Canvas zb1 = olivec_canvas((uint32_t*)zbuffer1, WIDTH, HEIGHT, WIDTH);
  49. olivec_fill(zb1, 0);
  50. float z = 1.5;
  51. float t = 0.75;
  52. {
  53. Vector3 v1 = make_vector3(cosf(global_time)*t, -t, z + sinf(global_time)*t);
  54. Vector3 v2 = make_vector3(cosf(global_time + PI)*t, -t, z + sinf(global_time + PI)*t);
  55. Vector3 v3 = make_vector3(0, t, z);
  56. Vector2 p1 = project_2d_scr(project_3d_2d(v1));
  57. Vector2 p2 = project_2d_scr(project_3d_2d(v2));
  58. Vector2 p3 = project_2d_scr(project_3d_2d(v3));
  59. 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);
  60. olivec_triangle3c(oc1, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 0xFF1818FF, 0xFF18FF18, 0xFFFF1818);
  61. }
  62. Olivec_Canvas oc2 = olivec_canvas(pixels2, WIDTH, HEIGHT, WIDTH);
  63. olivec_fill(oc2, 0xFF181818);
  64. Olivec_Canvas zb2 = olivec_canvas((uint32_t*)zbuffer2, WIDTH, HEIGHT, WIDTH);
  65. olivec_fill(zb2, 0);
  66. {
  67. Vector3 v1 = make_vector3(cosf(global_time + PI/2)*t, -t, z + sinf(global_time + PI/2)*t);
  68. Vector3 v2 = make_vector3(cosf(global_time + PI + PI/2)*t, -t, z + sinf(global_time + PI + PI/2)*t);
  69. Vector3 v3 = make_vector3(0, t, z);
  70. Vector2 p1 = project_2d_scr(project_3d_2d(v1));
  71. Vector2 p2 = project_2d_scr(project_3d_2d(v2));
  72. Vector2 p3 = project_2d_scr(project_3d_2d(v3));
  73. 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);
  74. olivec_triangle3c(oc2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, 0xFF1818FF, 0xFF18FF18, 0xFFFF1818);
  75. }
  76. for (size_t y = 0; y < HEIGHT; ++y) {
  77. for (size_t x = 0; x < WIDTH; ++x) {
  78. float z1 = *(float*)&OLIVEC_PIXEL(zb1, x, y);
  79. float z2 = *(float*)&OLIVEC_PIXEL(zb2, x, y);
  80. if (z1 < z2) {
  81. OLIVEC_PIXEL(oc1, x, y) = OLIVEC_PIXEL(oc2, x, y);
  82. z1 = z2;
  83. }
  84. z1 = 1.0f/z1;
  85. if (z1 >= 1.0) {
  86. z1 -= 1.0;
  87. uint32_t v = z1*255;
  88. if (v > 255) v = 255;
  89. olivec_blend_color(&OLIVEC_PIXEL(oc1, x, y), (v<<(3*8)));
  90. }
  91. }
  92. }
  93. return oc1;
  94. }