backface culling
This commit is contained in:
parent
648d1662c4
commit
bf2cf4ef01
60
src/main.c
60
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);
|
||||
|
123
src/vector.c
123
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
10
src/vector.h
10
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
|
||||
|
Loading…
Reference in New Issue
Block a user