From 57699deea973a72a6ab2d2eec8bfc7936c67d561 Mon Sep 17 00:00:00 2001 From: jb Date: Wed, 9 Jul 2025 23:45:32 -0700 Subject: [PATCH] render and culling options --- scripts/display.h | 12 +++++++ scripts/main.c | 89 ++++++++++++++++++++++++++++++++++------------- scripts/mesh.c | 2 +- 3 files changed, 78 insertions(+), 25 deletions(-) diff --git a/scripts/display.h b/scripts/display.h index 49b3e57..6119f44 100644 --- a/scripts/display.h +++ b/scripts/display.h @@ -17,6 +17,18 @@ extern SDL_Texture* color_buffer_texture; extern int window_width; extern int window_height; +enum render_methods { + RENDER_WIRE_VERTEX, + RENDER_WIRE, + RENDER_FILL_TRIANGLE, + RENDER_FILL_TRIANGLE_LINE, +}; + +enum cull_methods { + CULL_NONE, + CULL_BACKFACE, +}; + bool initialize_window(void); void draw_grid(void); void draw_pixel(int x, int y, uint32_t color); diff --git a/scripts/main.c b/scripts/main.c index 23dce4e..f145fde 100644 --- a/scripts/main.c +++ b/scripts/main.c @@ -33,6 +33,10 @@ vec3_t camera_position = { 0, 0, 0 }; float fov_factor = 640; bool is_running = false; + +int cull_method = CULL_BACKFACE; +int render_method = RENDER_WIRE_VERTEX; + uint32_t previous_frame_time = 0; void setup(void) { @@ -72,6 +76,26 @@ void process_input(void) { if (event.key.keysym.sym == SDLK_RIGHT) mesh.rotation.y += STEP; break; + case SDL_KEYUP: + SDL_Keycode key = event.key.keysym.sym; + if (key == SDLK_c) { + cull_method = !cull_method; + } + + if (key == SDLK_1) { + render_method = RENDER_WIRE_VERTEX; + } + if (key == SDLK_2) { + render_method = RENDER_WIRE; + } + if (key == SDLK_3) { + render_method = RENDER_FILL_TRIANGLE; + } + if (key == SDLK_4) { + render_method = RENDER_FILL_TRIANGLE_LINE; + } + + break; @@ -132,29 +156,31 @@ void update(void) { transformed_vertices[j] = transformed_vertex; } - // check backface culling - vec3_t vector_a = transformed_vertices[0]; /* A */ - vec3_t vector_b = transformed_vertices[1]; /* / \ */ - vec3_t vector_c = transformed_vertices[2]; /* C---B */ + if (cull_method == CULL_BACKFACE) { + // check backface culling + vec3_t vector_a = transformed_vertices[0]; /* A */ + vec3_t vector_b = transformed_vertices[1]; /* / \ */ + vec3_t vector_c = transformed_vertices[2]; /* C---B */ - // get the vector subtraction of B-A and C-A - vec3_t vector_ab = vec3_subtract(vector_b, vector_a); - vec3_t vector_ac = vec3_subtract(vector_c, vector_a); - vec3_normalize(&vector_ab); - vec3_normalize(&vector_ac); + // get the vector subtraction of B-A and C-A + vec3_t vector_ab = vec3_subtract(vector_b, vector_a); + vec3_t vector_ac = vec3_subtract(vector_c, vector_a); + vec3_normalize(&vector_ab); + vec3_normalize(&vector_ac); - // compute the face normal using the cross product to find perpindicular - vec3_t normal = vec3_cross(vector_ab, vector_ac); - vec3_normalize(&normal); + // compute the face normal using the cross product to find perpindicular + vec3_t normal = vec3_cross(vector_ab, vector_ac); + vec3_normalize(&normal); - // find the vector between a point in the triangle and the camera origin - vec3_t camera_ray = vec3_subtract(camera_position, vector_a); + // find the vector between a point in the triangle and the camera origin + vec3_t camera_ray = vec3_subtract(camera_position, vector_a); - // calculate how aligned the camera ray is with the face normal - float dot_normal_camera = vec3_dot(normal, camera_ray); + // calculate how aligned the camera ray is with the face normal + float dot_normal_camera = vec3_dot(normal, camera_ray); - if (dot_normal_camera < 0) { - continue; + if (dot_normal_camera < 0) { + continue; + } } triangle_t projected_triangle; @@ -188,13 +214,28 @@ void render(void) { for (int i = 0; i < array_length(triangles_to_render); i++) { triangle_t triangle = triangles_to_render[i]; - draw_filled_triangle(triangle, 0xFF00FF00); - draw_triangle(triangle, 0x0000ff); - //draw_triangle(triangle, 0xFFFF0000); - //draw_rect(triangle.points[0].x, triangle.points[0].y, 3, 3, 0xFFFFFF00); - //draw_rect(triangle.points[1].x, triangle.points[1].y, 3, 3, 0xFFFFFF00); - //draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00); + switch (render_method) { + case RENDER_WIRE: + draw_triangle(triangle, 0x0000ff); + break; + case RENDER_WIRE_VERTEX: + draw_triangle(triangle, 0x000055); + draw_rect(triangle.points[0].x, triangle.points[0].y, 3, 3, 0xFFFFFF00); + draw_rect(triangle.points[1].x, triangle.points[1].y, 3, 3, 0xFFFFFF00); + draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00); + break; + case RENDER_FILL_TRIANGLE: + draw_filled_triangle(triangle, 0x0000ff); + break; + case RENDER_FILL_TRIANGLE_LINE: + draw_filled_triangle(triangle, 0xff00); + draw_triangle(triangle, 0x0000ff); + break; + default: + break; + } + } //vec2_t m = triangle_midpoint(t); diff --git a/scripts/mesh.c b/scripts/mesh.c index 931b457..c80558b 100644 --- a/scripts/mesh.c +++ b/scripts/mesh.c @@ -75,7 +75,7 @@ void load_file(void) { FILE* fp; char* tok; - fp = fopen("..\\assets\\cube.obj", "r"); + fp = fopen("..\\assets\\f22.obj", "r"); if (fp == NULL) { exit(EXIT_FAILURE);