diff --git a/src/img.c b/src/img.c index 6b8239d..3d9683b 100644 --- a/src/img.c +++ b/src/img.c @@ -1,4 +1,5 @@ #include "img.h" +#include "aliases.h" #include "mem_arena.h" #include "pam.h" #include "utils.h" @@ -6,6 +7,8 @@ #include #include +internal u64 calculate_pixel_index(Buffer *buffer, u64 x, u64 y, u64 base_size); + bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size) { if (!arena || !buffer || buffer->width == 0 || buffer->height == 0) { return false; @@ -17,8 +20,13 @@ bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size) { return buffer->buf != NULL; } +u8 *_get_pixel(Buffer *buffer, u64 x, u64 y, u64 base_size) { + u64 idx = calculate_pixel_index(buffer, x, y, base_size); + return ((u8 *)(buffer->buf)) + idx; +} + void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { - u64 idx = (y * buffer->width + x) * base_size; + u64 idx = calculate_pixel_index(buffer, x, y, base_size); memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); } @@ -65,3 +73,8 @@ void draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour) { void save_image(const Image *img, const char *filename) { write_p7_image(img->width, img->height, (u8 *)(img->buf), filename); } + +internal u64 calculate_pixel_index(Buffer *buffer, u64 x, u64 y, + u64 base_size) { + return (y * buffer->width + x) * base_size; +} diff --git a/src/img.h b/src/img.h index 432ac19..998fafc 100644 --- a/src/img.h +++ b/src/img.h @@ -26,12 +26,15 @@ BUF_TYPE(f32, Depth); #define init_buffer(ARENA, BUF) \ _init_buffer(ARENA, (Buffer *)BUF, sizeof(*((BUF)->buf))) +#define get_pixel(TYPE, BUF, X, Y) \ + (*((TYPE *)(_get_pixel((Buffer *)BUF, X, Y, sizeof(*((BUF)->buf)))))) #define set_pixel(BUF, X, Y, VAL_PTR) \ _set_pixel((Buffer *)BUF, X, Y, VAL_PTR, sizeof(*((BUF)->buf))) #define clear_buffer(BUF, VAL_PTR) \ _clear_buffer((Buffer *)BUF, VAL_PTR, sizeof(*((BUF)->buf))) bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size); +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); void _clear_buffer(Buffer *buffer, void *value, u64 base_size); void draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour); diff --git a/src/obj.c b/src/obj.c index 16ea246..f901f1f 100644 --- a/src/obj.c +++ b/src/obj.c @@ -144,7 +144,7 @@ bool init_render(Arena *arena, Render *render, u64 width, u64 height) { return false; } - f32 inf = INFINITY; + f32 inf = -1.0f * INFINITY; clear_buffer(&(render->depth), &inf); return true; @@ -215,6 +215,7 @@ internal void render_triangle(const Triangle *triangle, const Model *model, internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], Colour colour) { Image *img = &(render->img); + Depth *depth = &(render->depth); TriangleBBox bbox = get_triangle_bbox(img, vertices); u64 v0x, v0y, v1x, v1y, v2x, v2y; @@ -230,6 +231,8 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], f32 denom = (f32)d00 * (f32)d11 - (f32)d01 * (f32)d01; V2i ap; V3f coords; + f32 z; + f32 zbuf; for (u64 y = bbox.y0; y < bbox.y1; ++y) { for (u64 x = bbox.x0; x < bbox.x1; ++x) { @@ -238,7 +241,16 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], if (coords.x < 0.0f || coords.y < 0.0f || coords.z < 0.0f) { continue; } - set_pixel(img, x, y, &colour); + + z = 0.0f; + z += vertices[0].z * coords.x + vertices[1].z * coords.y + + vertices[2].z * coords.z; + zbuf = get_pixel(f32, &(render->depth), x, y); + + if (z > zbuf) { + set_pixel(depth, x, y, &z); + set_pixel(img, x, y, &colour); + } } } }