using projection matrix, but there are rounding errors

This commit is contained in:
jb 2025-07-13 14:40:58 -07:00
parent 17e5ad9b85
commit 28c30a7fcf
3 changed files with 61 additions and 15 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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