diff --git a/assets/cube.obj b/assets/cube.obj new file mode 100644 index 0000000..c786c1e --- /dev/null +++ b/assets/cube.obj @@ -0,0 +1,46 @@ +# Blender v2.76 (sub 0) OBJ File: '' +# www.blender.org +mtllib cube.mtl +o Cube +v 1.000000 -1.000000 -1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +v -1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 -0.999999 +v 0.999999 1.000000 1.000001 +v -1.000000 1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +vt 1.000000 0.333333 +vt 1.000000 0.666667 +vt 0.666667 0.666667 +vt 0.666667 0.333333 +vt 0.666667 0.000000 +vt 0.000000 0.333333 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.333333 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.666667 +vt 0.333333 0.333333 +vt 0.333333 0.666667 +vt 1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn -0.000000 0.000000 1.000000 +vn -1.000000 -0.000000 -0.000000 +vn 0.000000 0.000000 -1.000000 +usemtl Material +s off +f 2/1/1 3/2/1 4/3/1 +f 8/1/2 7/4/2 6/5/2 +f 5/6/3 6/7/3 2/8/3 +f 6/8/4 7/5/4 3/4/4 +f 3/9/5 7/10/5 8/11/5 +f 1/12/6 4/13/6 8/11/6 +f 1/4/1 2/1/1 4/3/1 +f 5/14/2 8/1/2 6/5/2 +f 1/12/3 5/6/3 2/8/3 +f 2/12/4 6/8/4 3/4/4 +f 4/13/5 3/9/5 8/11/5 +f 5/6/6 1/12/6 8/11/6 \ No newline at end of file diff --git a/scripts/main.c b/scripts/main.c index a8cf5ef..68abd5c 100644 --- a/scripts/main.c +++ b/scripts/main.c @@ -11,7 +11,7 @@ triangle_t* triangles_to_render = NULL; //[N_MESH_FACES]; -vec3_t camera_position = { .x = 0, .y = 0, .z = -5 }; +vec3_t camera_position = { 0, 0, 0 }; float fov_factor = 640; @@ -84,9 +84,9 @@ void update(void) { previous_frame_time = SDL_GetTicks(); - //mesh.rotation.y += 0.01; + mesh.rotation.y += 0.01; mesh.rotation.x -= 0.01; - //mesh.rotation.z += 0.01; + mesh.rotation.z += 0.01; triangles_to_render = NULL; @@ -94,25 +94,57 @@ void update(void) { for (int i = 0; i < num_faces; i++) { face_t mesh_face = mesh.faces[i]; - vec3_t face_verticies[3]; - face_verticies[0] = mesh.vertices[mesh_face.a - 1]; - face_verticies[1] = mesh.vertices[mesh_face.b - 1]; - face_verticies[2] = mesh.vertices[mesh_face.c - 1]; + 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]; - triangle_t projected_triangle; + vec3_t transformed_vertices[3]; for (int j = 0; j < 3; j++) { - vec3_t transformed_vertex = face_verticies[j]; + vec3_t transformed_vertex = face_vertices[j]; transformed_vertex = vec3_rotate_x(transformed_vertex, mesh.rotation.x); transformed_vertex = vec3_rotate_y(transformed_vertex, mesh.rotation.y); transformed_vertex = vec3_rotate_z(transformed_vertex, mesh.rotation.z); // translate away from camera in z - transformed_vertex.z -= camera_position.z; + transformed_vertex.z += 5; + // save translated vertex in the array of transformed vertices + 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 */ + + // 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); + + // 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); + + if (dot_normal_camera < 0) { + continue; + } + + triangle_t projected_triangle; + + for (int j = 0; j < 3; j++) { // project the current vertex - vec2_t projected_point = project(transformed_vertex); + vec2_t projected_point = project(transformed_vertices[j]); // scale and translate the projected points to the center of the screen projected_point.x += (window_width / 2); @@ -124,6 +156,21 @@ void update(void) { // save the projected triangle in the array of triangles array_push(triangles_to_render, projected_triangle); + triangle_t normal_triangle; + + for (int j = 0; j < 3; j++) { + // project the current vertex + vec2_t projected_point = project(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); + + normal_triangle.points[j] = projected_point; + } + + array_push(triangles_to_render, normal_triangle); + } } diff --git a/scripts/mesh.c b/scripts/mesh.c index c80558b..931b457 100644 --- a/scripts/mesh.c +++ b/scripts/mesh.c @@ -75,7 +75,7 @@ void load_file(void) { FILE* fp; char* tok; - fp = fopen("..\\assets\\f22.obj", "r"); + fp = fopen("..\\assets\\cube.obj", "r"); if (fp == NULL) { exit(EXIT_FAILURE); diff --git a/scripts/mesh.h b/scripts/mesh.h index 40d1a20..056acf8 100644 --- a/scripts/mesh.h +++ b/scripts/mesh.h @@ -21,6 +21,8 @@ struct mesh_t { extern mesh_t mesh; +void parse_face(const char* buffer, face_t* face); + void load_cube_mesh_data(void); void load_file(void); diff --git a/scripts/vector.c b/scripts/vector.c index 8a299b8..25ac66f 100644 --- a/scripts/vector.c +++ b/scripts/vector.c @@ -25,4 +25,101 @@ vec3_t vec3_rotate_z(vec3_t v, float angle) { .y = v.x * sin(angle) + v.y * cos(angle), .z = v.z, }; +} + +float vec2_length(const vec2_t vector) { + return sqrt((vector.x * vector.x) + (vector.y * vector.y)); +} + +vec2_t vec2_add(const vec2_t a, const vec2_t b) { + return (vec2_t) { + .x = a.x + b.x, + .y = a.y + b.y, + }; +} + +vec2_t vec2_subtract(const vec2_t a, const vec2_t b) { + return (vec2_t) { + .x = a.x - b.x, + .y = a.y - b.y, + }; +} + +vec2_t vec2_multiply(const vec2_t vector, float scalar) { + return (vec2_t) { + .x = vector.x * scalar, + .y = vector.y * scalar, + }; +} + +vec2_t vec2_divide(const vec2_t vector, float scalar) { + return (vec2_t) { + .x = vector.x / scalar, + .y = vector.y / scalar, + }; +} + +float vec2_dot(const vec2_t a, const vec2_t b) { + return (a.x * b.x) + (a.y * b.y); +} + +float vec3_length(const vec3_t vector) { + return sqrtf((vector.x * vector.x) + (vector.y * vector.y) + (vector.z * vector.z)); +} + +void vec2_normalize(vec2_t* vertex) { + float length = vec2_length(*vertex); + vertex->x /= length; + vertex->y /= length; +} + +vec3_t vec3_add(const vec3_t a, const vec3_t b) { + return (vec3_t) { + .x = a.x + b.x, + .y = a.y + b.y, + .z = a.z + b.z, + }; +} + +vec3_t vec3_subtract(const vec3_t a, const vec3_t b) { + return (vec3_t) { + .x = a.x - b.x, + .y = a.y - b.y, + .z = a.z - b.z, + }; +} + +vec3_t vec3_multiply(const vec3_t vector, const float scalar) { + return (vec3_t) { + .x = vector.x * scalar, + .y = vector.y * scalar, + .z = vector.z * scalar, + }; +} + +vec3_t vec3_divide(const vec3_t vector, const float scalar) { + return (vec3_t) { + .x = vector.x / scalar, + .y = vector.y / scalar, + .z = vector.z / scalar, + }; +} + +vec3_t vec3_cross(const vec3_t a, const vec3_t b) { + return (vec3_t) { + .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, + }; +} + +float vec3_dot(const vec3_t a, const vec3_t b) { + return (a.x * b.x) + (a.y * b.y) + (a.z * b.z); +} + +void vec3_normalize(vec3_t* vertex) { + float length = vec3_length(*vertex); + vertex->x /= length; + vertex->y /= length; + vertex->z /= length; } \ No newline at end of file diff --git a/scripts/vector.h b/scripts/vector.h index 30dcc7f..81e1ec9 100644 --- a/scripts/vector.h +++ b/scripts/vector.h @@ -19,4 +19,21 @@ vec3_t vec3_rotate_x(vec3_t v, float angle); vec3_t vec3_rotate_y(vec3_t v, float angle); vec3_t vec3_rotate_z(vec3_t v, float angle); +vec2_t vec2_add(const vec2_t a, const vec2_t b); +vec2_t vec2_subtract(const vec2_t a, const vec2_t b); +vec2_t vec2_multiply(const vec2_t vector, float scalar); +vec2_t vec2_divide(const vec2_t vector, float scalar); +float vec2_length(const vec2_t vector); +float vec2_dot(const vec2_t a, const vec2_t b); +void vec2_normalize(vec2_t* vertex); + +vec3_t vec3_add(const vec3_t a, const vec3_t b); +vec3_t vec3_subtract(const vec3_t a, const vec3_t b); +vec3_t vec3_multiply(const vec3_t vector, const float scalar); +vec3_t vec3_divide(const vec3_t vector, const float scalar); +vec3_t vec3_cross(const vec3_t a, const vec3_t b); +float vec3_length(const vec3_t vector); +float vec3_dot(const vec3_t a, const vec3_t b); +void vec3_normalize(vec3_t* vertex); + #endif