backface culling

This commit is contained in:
Tyrel Souza 2024-04-23 23:09:13 -04:00
parent 648d1662c4
commit bf2cf4ef01
3 changed files with 135 additions and 58 deletions

View File

@ -11,7 +11,7 @@
triangle_t* triangles_to_render = NULL;
vec3_t camera_position = {0, 0, -5};
vec3_t camera_position = {0, 0, 0};
float fov_factor = 640;
bool is_running = false;
uint32_t previous_frame_time = 0;
@ -33,8 +33,8 @@ void setup(void) {
);
// load cube vertices into mesh data
// load_obj_file_data("../assets/cube.obj");
load_obj_file_data("../assets/teapot.obj");
load_obj_file_data("../assets/cube.obj");
// load_obj_file_data("../assets/teapot.obj");
// load_cube_mesh_data();
}
@ -65,6 +65,30 @@ vec2_t project(vec3_t point) {
return projected_point;
}
float check_backface_culling(const vec3_t *transformed_vertices) {// 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 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);
// 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);
// Find vector between a point in the triangle and the camera origin
vec3_t camera_ray = vec3_sub(camera_position, vector_a);
//calculate how aligned the face is
float dot_normal_camera = vec3_dot(normal, camera_ray);
return dot_normal_camera;
}
void update(void) {
// lock execution to the next tick
uint32_t time_to_wait = FRAME_TARGET_TIME - (SDL_GetTicks() - previous_frame_time);
@ -78,29 +102,41 @@ void update(void) {
mesh.rotation.x += .01f;
mesh.rotation.y += .01f;
mesh.rotation.z += .02f;
mesh.rotation.z += .01f;
int num_faces = array_length(mesh.faces);
for (int i = 0; i < num_faces; i++) {
face_t mesh_face = mesh.faces[i];
for (int f = 0; f < num_faces; f++) { // each face
face_t mesh_face = mesh.faces[f];
vec3_t face_vertices[3];
face_vertices[0] = mesh.vertices[mesh_face.a - 1];
face_vertices[1] = mesh.vertices[mesh_face.b - 1];
face_vertices[2] = mesh.vertices[mesh_face.c - 1];
//loop all three vertices
triangle_t projected_triangle;
for (int j = 0; j < 3; j++) {
vec3_t transformed_vertex = face_vertices[j];
vec3_t transformed_vertices[3];
for (int v = 0; v < 3; v++) { // each vertex
vec3_t transformed_vertex = face_vertices[v];
transformed_vertex = vec3_rotate_y(transformed_vertex, mesh.rotation.y);
transformed_vertex = vec3_rotate_x(transformed_vertex, mesh.rotation.x);
transformed_vertex = vec3_rotate_z(transformed_vertex, mesh.rotation.z);
transformed_vertex.z -= camera_position.z;
vec2_t projected_point = project(transformed_vertex);
transformed_vertex.z += 8;
transformed_vertices[v] = transformed_vertex;
}
if (check_backface_culling(transformed_vertices) < 0) {
continue;
}
triangle_t projected_triangle;
// loop all three vertices to perform projection
for (int v = 0; v < 3; v++) {
vec2_t projected_point = project(transformed_vertices[v]);
projected_point.x += (window_width / 2);
projected_point.y += (window_height / 2);
projected_triangle.points[j] = projected_point;
projected_triangle.points[v] = projected_point;
}
// save projected triangle in array of triangles to render
array_push(triangles_to_render, projected_triangle);

View File

@ -7,6 +7,7 @@
float vec2_length(vec2_t v) {
return sqrt(v.x * v.x + v.y * v.y);
}
vec2_t vec2_add(vec2_t a, vec2_t b) {
vec2_t result = {
.x = a.x + b.x,
@ -14,6 +15,7 @@ vec2_t vec2_add(vec2_t a, vec2_t b) {
};
return result;
}
vec2_t vec2_sub(vec2_t a, vec2_t b) {
vec2_t result = {
.x = a.x - b.x,
@ -21,6 +23,7 @@ vec2_t vec2_sub(vec2_t a, vec2_t b) {
};
return result;
}
vec2_t vec2_mul(vec2_t a, float factor) {
vec2_t result = {
.x = a.x * factor,
@ -28,6 +31,7 @@ vec2_t vec2_mul(vec2_t a, float factor) {
};
return result;
}
vec2_t vec2_div(vec2_t a, float factor) {
vec2_t result = {
.x = a.x / factor,
@ -48,6 +52,7 @@ vec3_t vec3_rotate_x(vec3_t v, float angle){
};
return rotated_vector;
}
vec3_t vec3_rotate_y(vec3_t v, float angle) {
vec3_t rotated_vector = {
.x = v.x * cos(angle) - v.z * sin(angle),
@ -56,6 +61,7 @@ vec3_t vec3_rotate_y(vec3_t v, float angle) {
};
return rotated_vector;
}
vec3_t vec3_rotate_z(vec3_t v, float angle) {
vec3_t rotated_vector = {
.x = v.x * cos(angle) - v.y * sin(angle),
@ -64,6 +70,7 @@ vec3_t vec3_rotate_z(vec3_t v, float angle) {
};
return rotated_vector;
}
float vec3_length(vec3_t v) {
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
@ -95,6 +102,7 @@ vec3_t vec3_mul(vec3_t a, float factor) {
};
return result;
}
vec3_t vec3_div(vec3_t a, float factor) {
vec3_t result = {
.x = a.x / factor,
@ -103,3 +111,34 @@ vec3_t vec3_div(vec3_t a, float factor){
};
return result;
}
vec3_t vec3_cross(vec3_t a, vec3_t b) {
vec3_t result = {
.x = a.y * b.z - a.z * b.y,
.y = a.z * b.x - a.x * b.z,
.z = a.x * b.y - a.y * b.x
};
return result;
}
float vec3_dot(vec3_t a, vec3_t b) {
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
float vec2_dot(vec2_t a, vec2_t b) {
return (a.x * b.x) + (a.y * b.y);
}
void vec3_normalize(vec3_t *v) {
float length = sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z));
v->x /= length;
v->y /= length;
v->z /= length;
}
void vec2_normalize(vec2_t *v) {
float length = sqrt((v->x * v->x) + (v->y * v->y));
v->x /= length;
v->y /= length;
}

View File

@ -18,7 +18,8 @@ vec2_t vec2_add(vec2_t a, vec2_t b);
vec2_t vec2_sub(vec2_t a, vec2_t b);
vec2_t vec2_mul(vec2_t a, float factor);
vec2_t vec2_div(vec2_t a, float factor);
float vec2_dot(vec2_t a, vec2_t b);
void vec2_normalize(vec2_t *v);
/////
// Vec 3d
@ -31,9 +32,10 @@ vec3_t vec3_add(vec3_t a, vec3_t b);
vec3_t vec3_sub(vec3_t a, vec3_t b);
vec3_t vec3_mul(vec3_t a, float factor);
vec3_t vec3_div(vec3_t a, float factor);
vec3_t vec3_cross(vec3_t a, vec3_t b);
float vec3_dot(vec3_t a, vec3_t b);
// Normalizing
void vec3_normalize(vec3_t *v);
#endif