diff --git a/src/main.c b/src/main.c index 7bbf969..3672d56 100644 --- a/src/main.c +++ b/src/main.c @@ -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); diff --git a/src/vector.c b/src/vector.c index c4deb79..0450a23 100644 --- a/src/vector.c +++ b/src/vector.c @@ -5,8 +5,9 @@ /// Vec 2d //////////////////////////////////////////////////////////////////// float vec2_length(vec2_t v) { - return sqrt(v.x * v.x + v.y *v.y); + 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,24 +15,27 @@ 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, - .y = a.y - b.y, + .x = a.x - b.x, + .y = a.y - b.y, }; return result; } + vec2_t vec2_mul(vec2_t a, float factor) { vec2_t result = { - .x = a.x * factor, - .y = a.y * factor, + .x = a.x * factor, + .y = a.y * factor, }; return result; } -vec2_t vec2_div(vec2_t a, float factor){ + +vec2_t vec2_div(vec2_t a, float factor) { vec2_t result = { - .x = a.x / factor, - .y = a.y / factor, + .x = a.x / factor, + .y = a.y / factor, }; return result; } @@ -40,66 +44,101 @@ vec2_t vec2_div(vec2_t a, float factor){ //////////////////////////////////////////////////////////////////// // Vec 3d //////////////////////////////////////////////////////////////////// -vec3_t vec3_rotate_x(vec3_t v, float angle){ - vec3_t rotated_vector = { - .x = v.x, - .y = v.y * cos(angle) - v.z * sin(angle), - .z = v.y * sin(angle) + v.z * cos(angle) - }; - return rotated_vector; +vec3_t vec3_rotate_x(vec3_t v, float angle) { + vec3_t rotated_vector = { + .x = v.x, + .y = v.y * cos(angle) - v.z * sin(angle), + .z = v.y * sin(angle) + v.z * cos(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), - .y = v.y, - .z = v.x * sin(angle) + v.z * cos(angle) - }; - return rotated_vector; + vec3_t rotated_vector = { + .x = v.x * cos(angle) - v.z * sin(angle), + .y = v.y, + .z = v.x * sin(angle) + v.z * cos(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), - .y = v.x * sin(angle) + v.y * cos(angle), - .z = v.z - }; - return rotated_vector; + vec3_t rotated_vector = { + .x = v.x * cos(angle) - v.y * sin(angle), + .y = v.x * sin(angle) + v.y * cos(angle), + .z = v.z + }; + return rotated_vector; } + float vec3_length(vec3_t v) { - return sqrt(v.x * v.x + v.y *v.y + v.z *v.z); + return sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } vec3_t vec3_add(vec3_t a, vec3_t b) { vec3_t result = { - .x = a.x + b.x, - .y = a.y + b.y, - .z = a.z + b.z, + .x = a.x + b.x, + .y = a.y + b.y, + .z = a.z + b.z, }; return result; } vec3_t vec3_sub(vec3_t a, vec3_t b) { vec3_t result = { - .x = a.x - b.x, - .y = a.y - b.y, - .z = a.z - b.z, + .x = a.x - b.x, + .y = a.y - b.y, + .z = a.z - b.z, }; return result; } vec3_t vec3_mul(vec3_t a, float factor) { vec3_t result = { - .x = a.x * factor, - .y = a.y * factor, - .z = a.z * factor, + .x = a.x * factor, + .y = a.y * factor, + .z = a.z * factor, }; return result; } -vec3_t vec3_div(vec3_t a, float factor){ + +vec3_t vec3_div(vec3_t a, float factor) { vec3_t result = { - .x = a.x / factor, - .y = a.y / factor, - .z = a.z / factor, + .x = a.x / factor, + .y = a.y / factor, + .z = a.z / factor, }; return result; -} \ No newline at end of file +} + +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; +} diff --git a/src/vector.h b/src/vector.h index 3b99320..0562e0c 100644 --- a/src/vector.h +++ b/src/vector.h @@ -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