triangle3d.c 3.2 KB

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