From b36fec7ba18d3015344d91859f02050395b04938 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Thu, 25 Apr 2024 00:02:48 -0400 Subject: [PATCH] add triangles filled --- src/main.c | 26 +++++++++-------- src/triangle.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++- src/triangle.h | 4 +++ 3 files changed, 94 insertions(+), 13 deletions(-) diff --git a/src/main.c b/src/main.c index 3672d56..c804756 100644 --- a/src/main.c +++ b/src/main.c @@ -7,9 +7,7 @@ #include "array.h" - - -triangle_t* triangles_to_render = NULL; +triangle_t *triangles_to_render = NULL; vec3_t camera_position = {0, 0, 0}; float fov_factor = 640; @@ -73,11 +71,12 @@ float check_backface_culling(const vec3_t *transformed_vertices) {// Check backf // Get vector subtraction of B-A and C-A vec3_t vector_ab = vec3_sub(vector_b, vector_a); vec3_t vector_ac = vec3_sub(vector_c, vector_a); + vec3_normalize(&vector_ab); + vec3_normalize(&vector_ac); // Get cross product to get the Normal N (to find perpendicular) // This is because left-handed coordinate system vec3_t normal = vec3_cross(vector_ab, vector_ac); // CLOCKWISE so A-B then A-C - // normalize the Face Normal vec3_normalize(&normal); @@ -145,24 +144,27 @@ void update(void) { } -void render(void) { -// draw_grid(); - //triangle array size +void render(void) { + draw_grid(); + +// triangle array size int num_triangles = array_length(triangles_to_render); for (int i = 0; i < num_triangles; i++) { triangle_t triangle = triangles_to_render[i]; uint32_t color = 0xFFFFFF00; - for (int j = 0; j < 3; j++) { - draw_rect(triangle.points[j].x, triangle.points[j].y, 3, 3, color); - } - draw_triangle(triangle.points[0].x, triangle.points[0].y, + draw_filled_triangle(triangle.points[0].x, triangle.points[0].y, triangle.points[1].x, triangle.points[1].y, triangle.points[2].x, triangle.points[2].y, color); - + draw_triangle(triangle.points[0].x, triangle.points[0].y, + triangle.points[1].x, triangle.points[1].y, + triangle.points[2].x, triangle.points[2].y, + 0xFF000000); } + + render_color_buffer(); clear_color_buffer(0xFF000000); diff --git a/src/triangle.c b/src/triangle.c index 07025ac..9171530 100644 --- a/src/triangle.c +++ b/src/triangle.c @@ -1,3 +1,78 @@ #include "triangle.h" +#include "display.h" -// TODO \ No newline at end of file + +void int_swap(int *a, int *b) { + int tmp = *a; + *a = *b; + *b = tmp; +} + +void fill_flat_bottom_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) { + // Start from top (x0, y0) + // calculate slope 1 and slope 2 + // Y is independent as we loop over Y, we want the delta X change. + float inv_slope_1 = (float) (x1 - x0) / (float) (y1 - y0); + float inv_slope_2 = (float) (x2 - x0) / (float) (y2 - y0); + + // start x_start and x_end from top vertex (x0,y0); + float x_start = x0; + float x_end = x0; + // loop all scan lines from y0 to y2 + for (int y = y0; y <= y2; y++) { + draw_line( + x_start, y, + x_end, y, + color); + x_start += inv_slope_1; + x_end += inv_slope_2; + } +} + +void fill_flat_top_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) { + // start from bottom + // calculate slope 1 and slope 2 + // Y is independent as we loop over Y, we want the delta X change. + float inv_slope_1 = (float) (x2 - x0) / (float) (y2 - y0); + float inv_slope_2 = (float) (x2 - x1) / (float) (y2 - y1); + + // start x_start and x_end from top vertex (x0,y0); + float x_start = x2; + float x_end = x2; + // loop all scan lines from y0 to y2 + for (int y = y2; y >= y0; y--) { + draw_line( + x_start, y, + x_end, y, + color); + x_start -= inv_slope_1; + x_end -= inv_slope_2; + } +} + +void draw_filled_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) { + //we need to sort the y coords (y0 < y1 < y2) + if (y0 > y1) { + int_swap(&y0, &y1); + int_swap(&x0, &x1); + } + if (y1 > y2) { + int_swap(&y1, &y2); + int_swap(&x1, &x2); + } + if (y0 > y1) { + int_swap(&y0, &y1); + int_swap(&x0, &x1); + } + + if (y1 == y2) { + fill_flat_bottom_triangle(x0, y0, x1, y1, x2, y2, color); + } else if (y0 == y2) { + fill_flat_top_triangle(x0, y0, x1, x1, x2, y2, color); + } else { + int My = y1; + int Mx = ((float) ((x2 - x0) * (y1 - y0)) / (float) (y2 - y0)) + (float) x0; + fill_flat_bottom_triangle(x0, y0, x1, y1, Mx, My, color); + fill_flat_top_triangle(x1, y1, Mx, My, x2, y2, color); + } +} \ No newline at end of file diff --git a/src/triangle.h b/src/triangle.h index 4592cba..94caa49 100644 --- a/src/triangle.h +++ b/src/triangle.h @@ -2,6 +2,7 @@ #define RENDERER_TRIANGLE_H #include "vector.h" +#include typedef struct { int a; @@ -13,4 +14,7 @@ typedef struct { vec2_t points[3]; } triangle_t; +void draw_filled_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color); + + #endif //RENDERER_TRIANGLE_H