diff --git a/src/main.c b/src/main.c index c5c32c3..fe3eca3 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,8 @@ int main(void) { } clear_buffer(&(render.img), &bg); - render_model(&obj, &render, teal, RENDER_TYPE_SHADED, COLOUR_TYPE_FIXED); + render_model(&obj, &render, teal, RENDER_TYPE_SHADED, COLOUR_TYPE_FIXED, + PROJECTION_TYPE_PERSPECTIVE); save_image(&(render.img), "result.pam"); wapp_mem_arena_destroy(&arena); diff --git a/src/obj.c b/src/obj.c index 71aa2ba..5a3c5d1 100644 --- a/src/obj.c +++ b/src/obj.c @@ -35,6 +35,19 @@ .y = V1.z * V2.x - V1.x * V2.z, \ .z = V1.x * V2.y - V1.y * V2.x, \ }) +#define mat4x4_mul_vec4(MAT, V) \ + ((V4f){ \ + .x = MAT.row0.x * V.x + MAT.row0.y * V.y + MAT.row0.z * V.z + \ + MAT.row0.w * V.w, \ + .y = MAT.row1.x * V.x + MAT.row1.y * V.y + MAT.row1.z * V.z + \ + MAT.row1.w * V.w, \ + .z = MAT.row2.x * V.x + MAT.row2.y * V.y + MAT.row2.z * V.z + \ + MAT.row2.w * V.w, \ + .w = MAT.row3.x * V.x + MAT.row3.y * V.y + MAT.row3.z * V.z + \ + MAT.row3.w * V.w, \ + }) +#define project_vec4(V) ((V3f){.x = V.x / V.w, .y = V.y / V.w, .z = V.z / V.w}) +#define vec3_to_vertex(V) ((Vertex){.x = V.x, .y = V.y, .z = V.z}) typedef struct triangle_bbox TriangleBBox; struct triangle_bbox { @@ -235,6 +248,23 @@ internal void render_triangle(const Triangle *triangle, const Model *model, list_get(model->texture_coordinates, triangle->tx2), }; + if (projection == PROJECTION_TYPE_PERSPECTIVE) { + // Basic perspective projection + V4f vertex; + V3f projected; + for (u64 i = 0; i < TRIANGLE_VERTICES; ++i) { + vertex = (V4f){ + .x = vertices[i].x, + .y = vertices[i].y, + .z = vertices[i].z, + .w = 1.0f, + }; + vertex = mat4x4_mul_vec4(g_cam_matrix, vertex); + projected = project_vec4(vertex); + vertices[i] = vec3_to_vertex(projected); + } + } + if (type == RENDER_TYPE_WIREFRAME) { Vertex v0, v1; u64 x0, y0, x1, y1;