Guest User

Untitled

a guest
Jul 4th, 2026
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.71 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. #define PIXEL_WIDTH 1
  17. #define PIXEL_HEIGHT 1
  18.  
  19. std::allocator<float> depth_buffer_allocator;
  20. std::allocator<uint8_t> framebuffer_allocator;
  21.  
  22.  
  23. inline float determinant(const glm::vec4 &a, const glm::vec4 &b, const glm::vec4 &c) {
  24. glm::vec4 ab = glm::vec4(b);
  25. glm::vec4 ac = glm::vec4(c);
  26.  
  27. ab -= a;
  28. ac -= a;
  29.  
  30. return ab.y * ac.x - ab.x * ac.y;
  31. }
  32.  
  33.  
  34. _raster::Rasterizer::Rasterizer(int width, int height) {
  35. this->width = width;
  36. this->height = height;
  37.  
  38. int depth_buffer_size = width * height;
  39.  
  40. depth_buffer = depth_buffer_allocator.allocate(depth_buffer_size);
  41.  
  42. for (int i = 0; i < depth_buffer_size; ++i) {
  43. depth_buffer[i] = INFINITY;
  44. }
  45.  
  46. int framebuffer_size = 4 * width * height;
  47.  
  48. framebuffer = framebuffer_allocator.allocate(framebuffer_size);
  49. memset(framebuffer, 0xFF, framebuffer_size);
  50. }
  51.  
  52.  
  53. inline bool is_left_or_top_edge(const glm::vec4 &start, const glm::vec4 &end) {
  54. glm::vec4 edge = end;
  55. edge -= start;
  56.  
  57. return (edge.y > 0) || (edge.y == 0 && edge.x < 0);
  58. }
  59.  
  60.  
  61. glm::vec4 gen_frag_color_from_vertex_color(const glm::vec3 &frag_coord,
  62. const glm::vec4 &a_color,
  63. const glm::vec4 &b_color,
  64. const glm::vec4 &c_color) {
  65. glm::vec4 lambda = glm::vec4(frag_coord, 0.0f);
  66. glm::vec4 color = a_color * lambda.x + b_color * lambda.y + c_color * lambda.z;
  67.  
  68. float color_a = glm::max(0, glm::min(255, (int)glm::floor(color.x * 256.0f)));
  69. float color_b = glm::max(0, glm::min(255, (int)glm::floor(color.y * 256.0f)));
  70. float color_c = glm::max(0, glm::min(255, (int)glm::floor(color.z * 256.0f)));
  71.  
  72. return glm::vec4(color_a, color_b, color_c, 255.0);
  73. }
  74.  
  75.  
  76. void _raster::Rasterizer::raster_triangle(const _vertex::Primitive &triangle) {
  77. glm::vec4 a = triangle.triangle_coords[0];
  78. glm::vec4 b = triangle.triangle_coords[1];
  79. glm::vec4 c = triangle.triangle_coords[2];
  80.  
  81. const float xmin = glm::fmin(a.x, b.x, c.x);
  82. const float ymin = glm::fmin(a.y, b.y, c.y);
  83. const float xmax = glm::fmax(a.x, b.x, c.x);
  84. const float ymax = glm::fmax(a.y, b.y, c.y);
  85.  
  86. for (float y = ymin; y <= ymax; ++y) {
  87. for (float x = xmin; x <= xmax; ++x) {
  88. glm::vec4 pixel = glm::vec4(x, y, 0.0f, 0.0f);
  89.  
  90. float area = determinant(a, b, c);
  91. bool clockwise = false;
  92.  
  93. if (area < 0) {
  94. std::swap(b, c);
  95. area = -area;
  96. clockwise = true;
  97. }
  98.  
  99. float w0 = determinant(b, c, pixel);
  100. float w1 = determinant(c, a, pixel);
  101. float w2 = determinant(a, b, pixel);
  102.  
  103. if (is_left_or_top_edge(b, c)) {
  104. --w0;
  105. }
  106.  
  107. if (is_left_or_top_edge(c, a)) {
  108. --w1;
  109. }
  110.  
  111. if (is_left_or_top_edge(a, b)) {
  112. --w2;
  113. }
  114.  
  115. if (w0 >= 0 && w1 >= 0 && w2 >= 0) {
  116. glm::vec3 bary_coords = glm::vec3((w0 + 1) / area,(w1 + 1) / area, (w2 + 1) / area);
  117. float frag_z = (1 / a.z) * bary_coords.x + (1 / b.z) * bary_coords.y + (1 / c.z) * bary_coords.z;
  118. frag_z = 1 / frag_z;
  119. glm::vec4 frag_color;
  120.  
  121. if (!clockwise) {
  122. frag_color = gen_frag_color_from_vertex_color(
  123. bary_coords,
  124. triangle.triangle_colors[0],
  125. triangle.triangle_colors[2],
  126. triangle.triangle_colors[1]
  127. );
  128. } else {
  129. frag_color = gen_frag_color_from_vertex_color(
  130. bary_coords,
  131. triangle.triangle_colors[0],
  132. triangle.triangle_colors[1],
  133. triangle.triangle_colors[2]
  134. );
  135. }
  136.  
  137. int buffer_index = ((int)y) * width + ((int)x);
  138. float previous_z = depth_buffer[buffer_index];
  139.  
  140. if (frag_z < previous_z) {
  141. int pixel_idx = buffer_index * 4;
  142.  
  143. depth_buffer[buffer_index] = frag_z;
  144. framebuffer[pixel_idx] = static_cast<uint8_t>(frag_color.x);
  145. framebuffer[pixel_idx + 1] = static_cast<uint8_t>(frag_color.y);
  146. framebuffer[pixel_idx + 2] = static_cast<uint8_t>(frag_color.z);
  147. framebuffer[pixel_idx + 3] = static_cast<uint8_t>(frag_color.w);
  148. }
  149. }
  150. }
  151. }
  152. }
  153.  
  154.  
  155. void _raster::Rasterizer::draw_framebuffer() {
  156. for (int y = 0; y < height; y += 1) {
  157. for (int x = 0; x < width; x += 1) {
  158. int pixel_idx = (y * width + x) * 4;
  159. DrawRectangle(
  160. x,
  161. y,
  162. PIXEL_WIDTH,
  163. PIXEL_HEIGHT,
  164. (Color){
  165. framebuffer[pixel_idx],
  166. framebuffer[pixel_idx + 1],
  167. framebuffer[pixel_idx + 2],
  168. framebuffer[pixel_idx + 3]
  169. }
  170. );
  171. }
  172. }
  173. }
  174.  
  175.  
  176. void _raster::Rasterizer::clear_framebuffer() {
  177. for (int y = 0; y < height; y += 1) {
  178. for (int x = 0; x < width; x += 1) {
  179. int pixel_idx = (y * width + x) * 4;
  180. framebuffer[pixel_idx] = 0;
  181. framebuffer[pixel_idx + 1] = 0;
  182. framebuffer[pixel_idx + 2] = 0;
  183. framebuffer[pixel_idx + 3] = 255;
  184. }
  185. }
  186. }
  187.  
  188.  
  189. void _raster::Rasterizer::draw_primitives(uint8_t primitive_type, const std::vector<_vertex::Primitive> &primitives) {
  190. BeginDrawing();
  191. int depth_buffer_size = width * height;
  192. clear_framebuffer();
  193.  
  194. for (int i = 0; i < depth_buffer_size; ++i) {
  195. depth_buffer[i] = INFINITY;
  196. }
  197.  
  198. for (const _vertex::Primitive &primitive : primitives) {
  199. raster_triangle(primitive);
  200. }
  201.  
  202. draw_framebuffer();
  203. EndDrawing();
  204. }
  205.  
Advertisement
Add Comment
Please, Sign In to add comment