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