Incomplete implementation of back face culling
This commit is contained in:
parent
5a3b143762
commit
51099ae97e
@ -22,6 +22,7 @@ typedef struct {
|
||||
colour_t colour;
|
||||
} scene_triangle_t;
|
||||
|
||||
MAKE_LIST_TYPE(u64);
|
||||
MAKE_LIST_TYPE(f32);
|
||||
MAKE_LIST_TYPE(vec2i_t);
|
||||
MAKE_LIST_TYPE(vec3f_t);
|
||||
@ -33,6 +34,8 @@ typedef enum {
|
||||
RASTERISER_RENDER_WIREFRAME,
|
||||
RASTERISER_RENDER_FILLED,
|
||||
RASTERISER_RENDER_SHADED,
|
||||
|
||||
COUNT_RASTERISER_RENDER,
|
||||
} render_type_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -159,6 +159,8 @@ int main(void) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
render_type_t type = RASTERISER_RENDER_FILLED;
|
||||
|
||||
while (running) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
@ -174,6 +176,8 @@ int main(void) {
|
||||
camera.rotation.y += 1.0f;
|
||||
} else if (event.key.keysym.sym == SDLK_a) {
|
||||
camera.rotation.y -= 1.0f;
|
||||
} else if (event.key.keysym.sym == SDLK_e) {
|
||||
type = (type + 1) % COUNT_RASTERISER_RENDER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -181,7 +185,7 @@ int main(void) {
|
||||
|
||||
clear_window(&window, bg);
|
||||
|
||||
render_scene(&window, frame_arena, &scene, RASTERISER_RENDER_FILLED);
|
||||
render_scene(&window, frame_arena, &scene, type);
|
||||
|
||||
swap_buffers(&window);
|
||||
|
||||
|
@ -11,12 +11,20 @@
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define CULL_ENABLED 0
|
||||
|
||||
internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
|
||||
Arena *arena, mat4x4f_t camera_matrix,
|
||||
mat3x4f_t projection_matrix,
|
||||
const instance_t *instance, render_type_t type);
|
||||
internal void clip_instance(Arena *arena, model_t *model,
|
||||
const rasteriser_scene_t *scene);
|
||||
|
||||
#if CULL_ENABLED
|
||||
internal void cull_back_faces(Arena *arena, const rasteriser_scene_t *scene,
|
||||
model_t *model);
|
||||
#endif
|
||||
|
||||
internal void clip_instance_against_plane(Arena *arena, model_t *model,
|
||||
const bounding_sphere_t *sphere,
|
||||
const clipping_plane_t *plane);
|
||||
@ -26,6 +34,13 @@ internal void clip_triangle_against_plane(Arena *arena, model_t *model,
|
||||
i64 triangle_index,
|
||||
const clipping_plane_t *plane);
|
||||
internal list_float *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1, f32 d1);
|
||||
|
||||
#if CULL_ENABLED
|
||||
internal inline vec3f_t
|
||||
calculate_triangle_normal(const model_t *model,
|
||||
const scene_triangle_t *triangle);
|
||||
#endif
|
||||
|
||||
internal inline void order_triangle_points(triangle_t *triangle);
|
||||
internal inline bounding_sphere_t
|
||||
get_bounding_sphere(const list_vertex_t *vertices);
|
||||
@ -57,11 +72,9 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
|
||||
mat3x4f_t projection_matrix,
|
||||
const instance_t *instance, render_type_t type) {
|
||||
list_vertex_t *transformed = list_create_with_capacity(
|
||||
vertex_t, arena,
|
||||
(instance->model->vertices->count + 10) * sizeof(vertex_t));
|
||||
vertex_t, arena, instance->model->vertices->count + 10);
|
||||
list_scene_triangle_t *triangles = list_create_with_capacity(
|
||||
scene_triangle_t, arena,
|
||||
(instance->model->triangles->count + 10) * sizeof(scene_triangle_t));
|
||||
scene_triangle_t, arena, instance->model->triangles->count + 10);
|
||||
if (!transformed || !triangles) {
|
||||
return;
|
||||
}
|
||||
@ -94,13 +107,17 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
|
||||
}
|
||||
|
||||
model_t model = {transformed, triangles};
|
||||
#if CULL_ENABLED
|
||||
cull_back_faces(arena, scene, &model);
|
||||
#endif
|
||||
|
||||
clip_instance(arena, &model, scene);
|
||||
if (is_null_model(&model)) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_vec2i_t *projected = list_create_with_capacity(
|
||||
vec2i_t, arena, instance->model->vertices->count * sizeof(vec2i_t));
|
||||
vec2i_t, arena, instance->model->vertices->count);
|
||||
if (!projected) {
|
||||
return;
|
||||
}
|
||||
@ -151,6 +168,8 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
|
||||
case RASTERISER_RENDER_SHADED:
|
||||
draw_shaded_triangle(wnd, arena, tri);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,6 +409,36 @@ internal void clip_instance(Arena *arena, model_t *model,
|
||||
}
|
||||
}
|
||||
|
||||
#if CULL_ENABLED
|
||||
internal void cull_back_faces(Arena *arena, const rasteriser_scene_t *scene,
|
||||
model_t *model) {
|
||||
list_uint64_t *to_remove =
|
||||
list_create_with_capacity(u64, arena, model->triangles->count);
|
||||
vec3f_t normal;
|
||||
scene_triangle_t triangle;
|
||||
vertex_t v0;
|
||||
vec3f_t viewing_vector;
|
||||
f32 dot_product;
|
||||
|
||||
for (u64 i = 0; i < model->triangles->count; ++i) {
|
||||
triangle = list_get(model->triangles, i);
|
||||
v0 = list_get(model->vertices, triangle.idx0);
|
||||
normal = calculate_triangle_normal(model, &triangle);
|
||||
viewing_vector = vec_sub(vec3f_t, v0.position, scene->camera->position);
|
||||
dot_product = vec_dot(vec3f_t, normal, viewing_vector);
|
||||
|
||||
if (dot_product <= 0.0f) {
|
||||
list_append(u64, arena, to_remove, i);
|
||||
}
|
||||
}
|
||||
|
||||
for (u64 i = 0; i < to_remove->count; ++i) {
|
||||
u64 idx = list_get(to_remove, i);
|
||||
list_remove(model->triangles, idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void clip_instance_against_plane(Arena *arena, model_t *model,
|
||||
const bounding_sphere_t *sphere,
|
||||
const clipping_plane_t *plane) {
|
||||
@ -536,6 +585,21 @@ internal list_float *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1, f32 d1) {
|
||||
return values;
|
||||
}
|
||||
|
||||
#if CULL_ENABLED
|
||||
internal inline vec3f_t
|
||||
calculate_triangle_normal(const model_t *model,
|
||||
const scene_triangle_t *triangle) {
|
||||
vertex_t v0 = list_get(model->vertices, triangle->idx0);
|
||||
vertex_t v1 = list_get(model->vertices, triangle->idx1);
|
||||
vertex_t v2 = list_get(model->vertices, triangle->idx2);
|
||||
|
||||
vec3f_t ba = vec_sub(vec3f_t, v1.position, v0.position);
|
||||
vec3f_t ca = vec_sub(vec3f_t, v2.position, v0.position);
|
||||
|
||||
return vec_cross(vec3f_t, ba, ca);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal inline void order_triangle_points(triangle_t *triangle) {
|
||||
if (triangle->p1.y < triangle->p0.y) {
|
||||
swap(vec2i_t, triangle->p0, triangle->p1);
|
||||
|
Loading…
Reference in New Issue
Block a user