diff --git a/src/img.c b/src/img.c index 3d9683b..12dec1e 100644 --- a/src/img.c +++ b/src/img.c @@ -28,6 +28,7 @@ u8 *_get_pixel(Buffer *buffer, u64 x, u64 y, u64 base_size) { void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { u64 idx = calculate_pixel_index(buffer, x, y, base_size); memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); + return; } void _clear_buffer(Buffer *buffer, void *value, u64 base_size) { diff --git a/src/main.c b/src/main.c index acb3148..ab9c7ca 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,9 @@ #include #include +#define SIZE 1200 +#define RESOURCE(NAME) "resources/" NAME + enum { TINY_EXIT_SUCCESS, TINY_EXIT_ARENA_INIT_FAILED, @@ -27,12 +30,12 @@ int main(void) { Colour teal = {.r = 14, .g = 156, .b = 208, .a = 255}; Colour orange = {.r = 242, .g = 100, .b = 48, .a = 255}; Render render; - if (!init_render(arena, &render, 1200, 1200)) { + if (!init_render(arena, &render, SIZE, SIZE)) { return TINY_EXIT_RENDER_INIT_FAILED; } Model model = - load_obj_file(arena, "resources/head.obj", "resources/head.pnm"); + load_obj_file(arena, RESOURCE("head.obj"), RESOURCE("head.pnm")); if (INVALID_MODEL(model)) { return TINY_EXIT_MODEL_LOAD_FAILED; } diff --git a/src/obj.c b/src/obj.c index 52b016d..aea6bef 100644 --- a/src/obj.c +++ b/src/obj.c @@ -49,6 +49,12 @@ struct i64x2 { i64 y; }; +typedef struct u64x2 V2u; +struct u64x2 { + u64 x; + u64 y; +}; + typedef struct f32x3 V3f; struct f32x3 { f32 x; @@ -75,6 +81,8 @@ 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 reorder_points(V2u vertices[TRIANGLE_VERTICES], + TexCoord coordinates[TRIANGLE_VERTICES]); internal TriangleBBox get_triangle_bbox(const Image *img, Vertex vertices[TRIANGLE_VERTICES]); internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom, @@ -162,7 +170,7 @@ bool init_render(Arena *arena, Render *render, u64 width, u64 height) { return false; } - f32 inf = -1.0f * INFINITY; + f32 inf = -INFINITY; clear_buffer(&(render->depth), &inf); return true; @@ -239,17 +247,17 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], Depth *depth = &(render->depth); TriangleBBox bbox = get_triangle_bbox(img, vertices); - u64 v0x, v0y, v1x, v1y, v2x, v2y; - get_image_coordinates(vertices[0].x, vertices[0].y, img, &v0x, &v0y); - get_image_coordinates(vertices[1].x, vertices[1].y, img, &v1x, &v1y); - get_image_coordinates(vertices[2].x, vertices[2].y, img, &v2x, &v2y); + V2u v0, v1, v2; + get_image_coordinates(vertices[0].x, vertices[0].y, img, &(v0.x), &(v0.y)); + get_image_coordinates(vertices[1].x, vertices[1].y, img, &(v1.x), &(v1.y)); + get_image_coordinates(vertices[2].x, vertices[2].y, img, &(v2.x), &(v2.y)); - V2i ab = V2(V2i, i64, v0x, v0y, v1x, v1y); - V2i ac = V2(V2i, i64, v0x, v0y, v2x, v2y); + V2i ab = V2(V2i, i64, v0.x, v0.y, v1.x, v1.y); + V2i ac = V2(V2i, i64, v0.x, v0.y, v2.x, v2.y); f32 d00 = dot_v2(ab, ab); f32 d01 = dot_v2(ab, ac); f32 d11 = dot_v2(ac, ac); - f32 denom = (f32)d00 * (f32)d11 - (f32)d01 * (f32)d01; + f32 denom = d00 * d11 - d01 * d01; V2i ap; V3f coords; f32 z; @@ -263,11 +271,11 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], colour.b *= intensity; } - for (u64 y = bbox.y0; y < bbox.y1; ++y) { - for (u64 x = bbox.x0; x < bbox.x1; ++x) { - ap = V2(V2i, i64, v0x, v0y, x, y); + for (u64 y = bbox.y0; y <= bbox.y1; ++y) { + for (u64 x = bbox.x0; x <= bbox.x1; ++x) { + ap = V2(V2i, i64, v0.x, v0.y, x, y); coords = get_barycentric_coords(d00, d01, d11, denom, &ab, &ac, &ap); - if (coords.x < 0.0f || coords.y < 0.0f || coords.z < 0.0f) { + if (coords.x < 0.0f || coords.y < 0.0f || coords.x + coords.y > 1.0f) { continue; } @@ -317,6 +325,10 @@ internal TriangleBBox get_triangle_bbox(const Image *img, internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom, const V2i *ab, const V2i *ac, const V2i *ap) { + if (denom == 0.0f) { + return (V3f){-INFINITY, -INFINITY, -INFINITY}; + } + f32 d20 = dot_v2((*ap), (*ab)); f32 d21 = dot_v2((*ap), (*ac)); @@ -331,6 +343,13 @@ internal void get_image_coordinates(f32 norm_x, f32 norm_y, const Image *img, u64 *x, u64 *y) { *x = ndc_to_image_coordinate(norm_x, img->width); *y = ndc_to_image_coordinate(0.0f - norm_y, img->height); + + if (*x >= img->width) { + *x = img->width - 1; + } + if (*y >= img->height) { + *y = img->height - 1; + } } internal u64 ndc_to_image_coordinate(f32 value, u64 max) {