Guest User

Untitled

a guest
Jul 4th, 2026
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.99 KB | None | 0 0
  1. #include <renderkid/rasterization.hpp>
  2. #include <renderkid/vertex_stage.hpp>
  3.  
  4. #define GLM_ENABLE_EXPERIMENTAL
  5.  
  6. #include <glm/gtx/string_cast.hpp>
  7. #include <glm/ext/scalar_common.hpp>
  8. #include <glm/vec4.hpp>
  9. #include <raylib.h>
  10. #include <utility>
  11. #include <cstdint>
  12. #include <memory>
  13. #include <vector>
  14. #include <cmath>
  15.  
  16. std::allocator<float> depth_buffer_allocator;
  17.  
  18.  
  19. inline float determinant(const glm::vec4 &a, const glm::vec4 &b, const glm::vec4 &c) {
  20. glm::vec4 ab = glm::vec4(b);
  21. glm::vec4 ac = glm::vec4(c);
  22.  
  23. ab -= a;
  24. ac -= a;
  25.  
  26. return ab.y * ac.x - ab.x * ac.y;
  27. }
  28.  
  29.  
  30. _raster::Rasterizer::Rasterizer(int width, int height) {
  31. this->width = width;
  32. this->height = height;
  33.  
  34. int depth_buffer_size = width * height;
  35.  
  36. depth_buffer = depth_buffer_allocator.allocate(depth_buffer_size);
  37.  
  38. for (int i = 0; i < depth_buffer_size; ++i) {
  39. depth_buffer[i] = INFINITY;
  40. }
  41.  
  42. framebuffer = GenImageColor(width, height, BLACK);
  43. texture = LoadTextureFromImage(framebuffer);
  44. }
  45.  
  46.  
  47. inline bool is_left_or_top_edge(const glm::vec4 &start, const glm::vec4 &end) {
  48. glm::vec4 edge = end;
  49. edge -= start;
  50.  
  51. return (edge.y > 0) || (edge.y == 0 && edge.x < 0);
  52. }
  53.  
  54.  
  55. glm::vec4 gen_frag_color_from_vertex_color(const glm::vec3 &frag_coord,
  56. const glm::vec4 &a_color,
  57. const glm::vec4 &b_color,
  58. const glm::vec4 &c_color) {
  59. glm::vec4 lambda = glm::vec4(frag_coord, 0.0f);
  60. glm::vec4 color = a_color * lambda.x + b_color * lambda.y + c_color * lambda.z;
  61.  
  62. float color_a = glm::max(0, glm::min(255, (int)glm::floor(color.x * 256.0f)));
  63. float color_b = glm::max(0, glm::min(255, (int)glm::floor(color.y * 256.0f)));
  64. float color_c = glm::max(0, glm::min(255, (int)glm::floor(color.z * 256.0f)));
  65.  
  66. return glm::vec4(color_a, color_b, color_c, 255.0);
  67. }
  68.  
  69.  
  70. void _raster::Rasterizer::raster_triangle(const _vertex::Primitive &triangle) {
  71. glm::vec4 a = triangle.triangle_coords[0];
  72. glm::vec4 b = triangle.triangle_coords[1];
  73. glm::vec4 c = triangle.triangle_coords[2];
  74.  
  75. const float xmin = glm::fmin(a.x, b.x, c.x);
  76. const float ymin = glm::fmin(a.y, b.y, c.y);
  77. const float xmax = glm::fmax(a.x, b.x, c.x);
  78. const float ymax = glm::fmax(a.y, b.y, c.y);
  79.  
  80. for (float y = ymin; y <= ymax; ++y) {
  81. for (float x = xmin; x <= xmax; ++x) {
  82. glm::vec4 pixel = glm::vec4(x, y, 0.0f, 0.0f);
  83.  
  84. float area = determinant(a, b, c);
  85. bool clockwise = false;
  86.  
  87. if (area < 0) {
  88. std::swap(b, c);
  89. area = -area;
  90. clockwise = true;
  91. }
  92.  
  93. float w0 = determinant(b, c, pixel);
  94. float w1 = determinant(c, a, pixel);
  95. float w2 = determinant(a, b, pixel);
  96.  
  97. if (is_left_or_top_edge(b, c)) {
  98. --w0;
  99. }
  100.  
  101. if (is_left_or_top_edge(c, a)) {
  102. --w1;
  103. }
  104.  
  105. if (is_left_or_top_edge(a, b)) {
  106. --w2;
  107. }
  108.  
  109. if (w0 >= 0 && w1 >= 0 && w2 >= 0) {
  110. glm::vec3 bary_coords = glm::vec3((w0 + 1) / area,(w1 + 1) / area, (w2 + 1) / area);
  111. float frag_z = (1 / a.z) * bary_coords.x + (1 / b.z) * bary_coords.y + (1 / c.z) * bary_coords.z;
  112. frag_z = 1 / frag_z;
  113. glm::vec4 frag_color;
  114.  
  115. if (!clockwise) {
  116. frag_color = gen_frag_color_from_vertex_color(
  117. bary_coords,
  118. triangle.triangle_colors[0],
  119. triangle.triangle_colors[2],
  120. triangle.triangle_colors[1]
  121. );
  122. } else {
  123. frag_color = gen_frag_color_from_vertex_color(
  124. bary_coords,
  125. triangle.triangle_colors[0],
  126. triangle.triangle_colors[1],
  127. triangle.triangle_colors[2]
  128. );
  129. }
  130.  
  131. int buffer_index = ((int)y) * width + ((int)x);
  132. float previous_z = depth_buffer[buffer_index];
  133.  
  134. if (frag_z < previous_z) {
  135. depth_buffer[buffer_index] = frag_z;
  136.  
  137. ImageDrawPixel(&framebuffer, x, y, (Color){
  138. static_cast<uint8_t>(frag_color.x),
  139. static_cast<uint8_t>(frag_color.y),
  140. static_cast<uint8_t>(frag_color.z),
  141. static_cast<uint8_t>(frag_color.w)
  142. });
  143. }
  144. }
  145. }
  146. }
  147. }
  148.  
  149.  
  150. void _raster::Rasterizer::draw_framebuffer() {
  151. UpdateTexture(texture, framebuffer.data);
  152. DrawTexture(texture, 0, 0, WHITE);
  153. }
  154.  
  155.  
  156. void _raster::Rasterizer::clear_framebuffer() {
  157. ImageClearBackground(&framebuffer, BLACK);
  158. UpdateTexture(texture, framebuffer.data);
  159. }
  160.  
  161.  
  162. void _raster::Rasterizer::draw_primitives(uint8_t primitive_type, const std::vector<_vertex::Primitive> &primitives) {
  163. BeginDrawing();
  164. clear_framebuffer();
  165. ClearBackground(BLACK);
  166. int depth_buffer_size = width * height;
  167.  
  168. for (int i = 0; i < depth_buffer_size; ++i) {
  169. depth_buffer[i] = INFINITY;
  170. }
  171.  
  172. for (const _vertex::Primitive &primitive : primitives) {
  173. raster_triangle(primitive);
  174. }
  175.  
  176. draw_framebuffer();
  177. EndDrawing();
  178. }
  179.  
Advertisement
Add Comment
Please, Sign In to add comment