diff --git a/scripts/main.c b/scripts/main.c index f9bdbff..bbb473f 100644 --- a/scripts/main.c +++ b/scripts/main.c @@ -30,8 +30,7 @@ triangle_t* triangles_to_render = NULL; //[N_MESH_FACES]; vec3_t camera_position = { 0, 0, 0 }; -float fov_factor = 640; - +mat4_t proj_matrix; bool is_running = false; int cull_method = CULL_BACKFACE; @@ -53,6 +52,12 @@ void setup(void) { window_height ); + float fov = M_PI / 3; + float aspect = (float)window_height / (float)window_width; + float znear = 0.0f; + float zfar = 100.0f; + proj_matrix = mat4_make_perspective(fov, aspect, znear, zfar); + // load cube mesh data //load_file("..\\assets\\tank.obj"); load_cube_mesh_data(); @@ -112,6 +117,7 @@ void process_input(void) { // Function that receives a 3D vector and returns a projected 2D point //////////////////////////////////////////////////////////////////////////////// vec2_t project(vec3_t point) { + float fov_factor = 1; // placeholder vec2_t projected_point = { .x = roundf((fov_factor * point.x) / point.z), .y = roundf((fov_factor * point.y) / point.z), @@ -153,10 +159,12 @@ void update(void) { mat4_t rotation_matrix_z = mat4_make_rotation_z(mesh.rotation.z); // create world matrix - mat4_t world_matrix = mat4_mul_mat4(&scale_matrix, &translation_matrix); - world_matrix = mat4_mul_mat4(&world_matrix, &rotation_matrix_x); - world_matrix = mat4_mul_mat4(&world_matrix, &rotation_matrix_y); - world_matrix = mat4_mul_mat4(&world_matrix, &rotation_matrix_z); + mat4_t world_matrix = mat4_identity(); + world_matrix = mat4_mul_mat4(&scale_matrix, &world_matrix); + world_matrix = mat4_mul_mat4(&rotation_matrix_x, &world_matrix); + world_matrix = mat4_mul_mat4(&rotation_matrix_y, &world_matrix); + world_matrix = mat4_mul_mat4(&rotation_matrix_z, &world_matrix); + world_matrix = mat4_mul_mat4(&translation_matrix, &world_matrix); triangles_to_render = NULL; @@ -209,23 +217,36 @@ void update(void) { } } - triangle_t projected_triangle; + vec4_t projected_points[3]; for (int j = 0; j < 3; j++) { // project the current vertex - vec2_t projected_point = project(vec3_from_vec4(transformed_vertices[j])); + projected_points[j] = mat4_mul_vec4_project(proj_matrix, transformed_vertices[j]); - // scale and translate the projected points to the center of the screen - projected_point.x += (window_width / 2); - projected_point.y += (window_height / 2); + // Scale into the view + projected_points[j].x *= roundf(window_width / 2.0); + projected_points[j].y *= roundf(window_height / 2.0); - projected_triangle.points[j] = projected_point; + // Translate the projected points to the middle of the screen + projected_points[j].x += roundf(window_width / 2.0); + projected_points[j].y += roundf(window_height / 2.0); + + //projected_triangle.points[j] = projected_point; } // calculate the average depth of the triangle - projected_triangle.average_depth = (transformed_vertices[0].z + transformed_vertices[1].z + transformed_vertices[2].z) / 3.0f; + float avg_depth = (transformed_vertices[0].z + transformed_vertices[1].z + transformed_vertices[2].z) / 3.0f; + + triangle_t projected_triangle = { + .points = { + { projected_points[0].x, projected_points[0].y }, + { projected_points[1].x, projected_points[1].y }, + { projected_points[2].x, projected_points[2].y }, + }, + .color = mesh_face.color, + .average_depth = avg_depth, + }; - projected_triangle.color = mesh_face.color;// | 0xFF00FF00; //vec2_t midpoint = triangle_midpoint(projected_triangle); //draw_rect(midpoint.x, midpoint.y, 10, 10, 0xFFFF0000); diff --git a/scripts/matrix.c b/scripts/matrix.c index cded963..dd981c3 100644 --- a/scripts/matrix.c +++ b/scripts/matrix.c @@ -113,3 +113,27 @@ mat4_t mat4_mul_mat4(mat4_t* a, mat4_t* b) { return ret; } + +mat4_t mat4_make_perspective(float fov, float aspect, float znear, float zfar) { + mat4_t m = {{{ 0 }}}; + m.m[0][0] = aspect * (1 / tanf(fov / 2)); + m.m[1][1] = 1 / tanf(fov / 2); + m.m[2][2] = zfar / (zfar - znear); + m.m[2][3] = (-zfar * znear) / (zfar - znear); + m.m[3][2] = 1.0f; + return m; +} + +vec4_t mat4_mul_vec4_project(mat4_t mat_proj, vec4_t v) { + // multiply the projection matrix by our original vector + vec4_t result = mat4_multiply_vec4(mat_proj, v); + + // perform perspective divide with original z-value + if (result.w != 0.0) { + result.x /= result.w; + result.y /= result.w; + result.z /= result.w; + } + + return result; +} \ No newline at end of file diff --git a/scripts/matrix.h b/scripts/matrix.h index 1d3c55f..79a789d 100644 --- a/scripts/matrix.h +++ b/scripts/matrix.h @@ -16,7 +16,8 @@ mat4_t mat4_make_rotation_x(float ra); mat4_t mat4_make_rotation_y(float ra); mat4_t mat4_make_rotation_z(float ra); mat4_t mat4_mul_mat4(mat4_t* a, mat4_t* b); - vec4_t mat4_multiply_vec4(mat4_t m, vec4_t v); +mat4_t mat4_make_perspective(float fov, float aspect, float znear, float zfar); +vec4_t mat4_mul_vec4_project(mat4_t mat_proj, vec4_t v); #endif \ No newline at end of file