diff --git a/src/obj.c b/src/obj.c index 5a3c5d1..a8153b1 100644 --- a/src/obj.c +++ b/src/obj.c @@ -47,7 +47,6 @@ 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 { @@ -57,65 +56,16 @@ struct triangle_bbox { u64 y1; }; -typedef struct i64x2 V2i; -struct i64x2 { - i64 x; - i64 y; -}; - -typedef struct u64x2 V2u; -struct u64x2 { - u64 x; - u64 y; -}; - -typedef struct f32x3 V3f; -struct f32x3 { - f32 x; - f32 y; - f32 z; -}; - -typedef struct f32x4 V4f; -struct f32x4 { - f32 x; - f32 y; - f32 z; - f32 w; -}; - -typedef struct u64x3 V3u; -struct u64x3 { - u64 x; - u64 y; - u64 z; -}; - -typedef struct f32_3x3 M3x3f; -struct f32_3x3 { - V3f row0; - V3f row1; - V3f row2; -}; - -typedef struct f32_4x4 M4x4f; -struct f32_4x4 { - V4f row0; - V4f row1; - V4f row2; - V4f row3; -}; - internal void render_triangle(const Triangle *triangle, const Model *model, Render *render, Colour colour, RenderType type, ProjectionType projection); -internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], - TexCoord coordinates[TRIANGLE_VERTICES], - Colour colour, f32 intensity, Image *texture); +internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES], + V2f coordinates[TRIANGLE_VERTICES], Colour colour, + f32 intensity, Image *texture); internal void reorder_points(V2u vertices[TRIANGLE_VERTICES], - TexCoord coordinates[TRIANGLE_VERTICES]); + V2f coordinates[TRIANGLE_VERTICES]); internal TriangleBBox get_triangle_bbox(const Image *img, - Vertex vertices[TRIANGLE_VERTICES]); + V3f vertices[TRIANGLE_VERTICES]); internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom, const V2i *ab, const V2i *ac, const V2i *ap); @@ -145,8 +95,8 @@ Model load_obj_file(Arena *arena, const char *filename, const char *texture) { } Model model = (Model){ - .vertices = list_create(Vertex, arena), - .texture_coordinates = list_create(TexCoord, arena), + .vertices = list_create(V3f, arena), + .texture_coordinates = list_create(V2f, arena), .triangles = list_create(Triangle, arena), }; if (!(model.vertices) || !(model.texture_coordinates) || !(model.triangles)) { @@ -155,8 +105,8 @@ Model load_obj_file(Arena *arena, const char *filename, const char *texture) { char line[8192]; char identifier[8]; - Vertex vertex; - TexCoord coord; + V3f vertex; + V2f coord; Triangle triangle; f32 vx, vy, vz; f32 u, v; @@ -172,12 +122,12 @@ Model load_obj_file(Arena *arena, const char *filename, const char *texture) { vertex.x = vx; vertex.y = vy; vertex.z = vz; - list_append(Vertex, arena, model.vertices, vertex); + list_append(V3f, arena, model.vertices, vertex); } else if (strncmp(identifier, "vt", 8) == 0) { sscanf(line + 2, "%f %f", &u, &v); coord.u = u; coord.v = v; - list_append(TexCoord, arena, model.texture_coordinates, coord); + list_append(V2f, arena, model.texture_coordinates, coord); } else if (strncmp(identifier, "f", 8) == 0) { sscanf(line + 2, "%lu/%lu/%lu %lu/%lu/%lu %lu/%lu/%lu", &fp0, &tx0, &ign_0_2, &fp1, &tx1, &ign_1_2, &fp2, &tx2, &ign_2_2); @@ -237,12 +187,12 @@ internal void render_triangle(const Triangle *triangle, const Model *model, Render *render, Colour colour, RenderType type, ProjectionType projection) { Image *img = &(render->img); - Vertex vertices[TRIANGLE_VERTICES] = { + V3f vertices[TRIANGLE_VERTICES] = { list_get(model->vertices, triangle->p0), list_get(model->vertices, triangle->p1), list_get(model->vertices, triangle->p2), }; - TexCoord coordinates[TRIANGLE_VERTICES] = { + V2f coordinates[TRIANGLE_VERTICES] = { list_get(model->texture_coordinates, triangle->tx0), list_get(model->texture_coordinates, triangle->tx1), list_get(model->texture_coordinates, triangle->tx2), @@ -251,7 +201,6 @@ internal void render_triangle(const Triangle *triangle, const Model *model, 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, @@ -260,13 +209,12 @@ internal void render_triangle(const Triangle *triangle, const Model *model, .w = 1.0f, }; vertex = mat4x4_mul_vec4(g_cam_matrix, vertex); - projected = project_vec4(vertex); - vertices[i] = vec3_to_vertex(projected); + vertices[i] = project_vec4(vertex); } } if (type == RENDER_TYPE_WIREFRAME) { - Vertex v0, v1; + V3f v0, v1; u64 x0, y0, x1, y1; for (u64 i = 0; i < TRIANGLE_VERTICES; ++i) { v0 = vertices[i]; @@ -299,9 +247,9 @@ internal void render_triangle(const Triangle *triangle, const Model *model, } } -internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], - TexCoord coordinates[TRIANGLE_VERTICES], - Colour colour, f32 intensity, Image *texture) { +internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES], + V2f coordinates[TRIANGLE_VERTICES], Colour colour, + f32 intensity, Image *texture) { Image *img = &(render->img); Depth *depth = &(render->depth); TriangleBBox bbox = get_triangle_bbox(img, vertices); @@ -366,7 +314,7 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], } internal TriangleBBox get_triangle_bbox(const Image *img, - Vertex vertices[TRIANGLE_VERTICES]) { + V3f vertices[TRIANGLE_VERTICES]) { f32 x0 = min(vertices[0].x, min(vertices[1].x, vertices[2].x)); f32 x1 = max(vertices[0].x, max(vertices[1].x, vertices[2].x)); // NOTE (Abdelrahman): Because y is flipped, we use max for the minimum and diff --git a/src/obj.h b/src/obj.h index 10c1c6a..91d5926 100644 --- a/src/obj.h +++ b/src/obj.h @@ -9,19 +9,6 @@ #define NULL_MODEL ((Model){0}) #define INVALID_MODEL(m) (m.vertices == NULL || m.triangles == NULL) -typedef struct vertex Vertex; -struct vertex { - f32 x; - f32 y; - f32 z; -}; - -typedef struct texcoord TexCoord; -struct texcoord { - f32 u; - f32 v; -}; - typedef struct triangle Triangle; struct triangle { u64 p0; @@ -32,6 +19,67 @@ struct triangle { u64 tx2; }; +typedef struct i64x2 V2i; +struct i64x2 { + i64 x; + i64 y; +}; + +typedef struct u64x2 V2u; +struct u64x2 { + u64 x; + u64 y; +}; + +typedef struct f32x2 V2f; +struct f32x2 { + union { + f32 x; + f32 u; + }; + union { + f32 y; + f32 v; + }; +}; + +typedef struct f32x3 V3f; +struct f32x3 { + f32 x; + f32 y; + f32 z; +}; + +typedef struct f32x4 V4f; +struct f32x4 { + f32 x; + f32 y; + f32 z; + f32 w; +}; + +typedef struct u64x3 V3u; +struct u64x3 { + u64 x; + u64 y; + u64 z; +}; + +typedef struct f32_3x3 M3x3f; +struct f32_3x3 { + V3f row0; + V3f row1; + V3f row2; +}; + +typedef struct f32_4x4 M4x4f; +struct f32_4x4 { + V4f row0; + V4f row1; + V4f row2; + V4f row3; +}; + typedef enum { RENDER_TYPE_WIREFRAME, RENDER_TYPE_FILLED, @@ -54,14 +102,14 @@ typedef enum { COUNT_PROJECTION_TYPE, } ProjectionType; -MAKE_LIST_TYPE(Vertex); -MAKE_LIST_TYPE(TexCoord); +MAKE_LIST_TYPE(V3f); +MAKE_LIST_TYPE(V2f); MAKE_LIST_TYPE(Triangle); typedef struct model Model; struct model { - LIST_TYPE(Vertex) * vertices; - LIST_TYPE(TexCoord) * texture_coordinates; + LIST_TYPE(V3f) * vertices; + LIST_TYPE(V2f) * texture_coordinates; LIST_TYPE(Triangle) * triangles; Image *texture; };