From 4eb2ae06f1b735a02cc8e7774232e6713d897976 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 4 Aug 2024 16:52:02 +0100 Subject: [PATCH] Create generic buffer type --- src/img.c | 35 ++++++++++++++++------------------- src/img.h | 29 ++++++++++++++++++++--------- src/main.c | 2 +- src/obj.c | 16 +++++++++++----- src/obj.h | 2 +- 5 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/img.c b/src/img.c index bdfa4d8..6b8239d 100644 --- a/src/img.c +++ b/src/img.c @@ -4,31 +4,28 @@ #include "utils.h" #include #include +#include -#define SAMPLES_PER_PIXEL 4 - -bool init_image(Arena *arena, Image *img) { - if (!arena || !img || img->width == 0 || img->height == 0) { +bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size) { + if (!arena || !buffer || buffer->width == 0 || buffer->height == 0) { return false; } - u64 size = img->width * img->height * SAMPLES_PER_PIXEL; - img->buf = wapp_mem_arena_alloc(arena, size); + u64 size = buffer->width * buffer->height * base_size; + buffer->buf = wapp_mem_arena_alloc(arena, size); - return img->buf != NULL; + return buffer->buf != NULL; } -void set_pixel(Image *img, u64 x, u64 y, Colour colour) { - u64 idx = (y * img->width + x) * SAMPLES_PER_PIXEL; - for (u64 i = 0; i < SAMPLES_PER_PIXEL; ++i) { - img->buf[idx + i] = *(((u8 *)&colour) + i); - } +void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { + u64 idx = (y * buffer->width + x) * base_size; + memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); } -void clear_image(Image *img, Colour colour) { - for (u64 y = 0; y < img->height; ++y) { - for (u64 x = 0; x < img->width; ++x) { - set_pixel(img, x, y, colour); +void _clear_buffer(Buffer *buffer, void *value, u64 base_size) { + for (u64 y = 0; y < buffer->height; ++y) { + for (u64 x = 0; x < buffer->width; ++x) { + _set_pixel(buffer, x, y, value, base_size); } } } @@ -49,7 +46,7 @@ void draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour) { for (u64 x = x0; x < x1; ++x) { t = (f32)(x - x0) / (f32)(x1 - x0); y = (i64)y0 + ((i64)y1 - (i64)y0) * t; - set_pixel(img, x, y, colour); + set_pixel(img, x, y, &colour); } } else { if (y0 > y1) { @@ -60,11 +57,11 @@ void draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour) { for (u64 y = y0; y < y1; ++y) { t = (f32)(y - y0) / (f32)(y1 - y0); x = (i64)x0 + ((i64)x1 - (i64)x0) * t; - set_pixel(img, x, y, colour); + set_pixel(img, x, y, &colour); } } } void save_image(const Image *img, const char *filename) { - write_p7_image(img->width, img->height, img->buf, filename); + write_p7_image(img->width, img->height, (u8 *)(img->buf), filename); } diff --git a/src/img.h b/src/img.h index 2d80e6c..96539da 100644 --- a/src/img.h +++ b/src/img.h @@ -5,12 +5,12 @@ #include "mem_arena.h" #include -typedef struct img Image; -struct img { - u64 width; - u64 height; - u8 *buf; -}; +#define BUF_TYPE(NAME, TYPE) \ + typedef struct { \ + u64 width; \ + u64 height; \ + TYPE *buf; \ + } NAME typedef struct colour Colour; struct colour { @@ -20,9 +20,20 @@ struct colour { u8 a; }; -bool init_image(Arena *arena, Image *img); -void set_pixel(Image *img, u64 x, u64 y, Colour colour); -void clear_image(Image *img, Colour colour); +BUF_TYPE(Buffer, void); +BUF_TYPE(Image, Colour); +BUF_TYPE(Depth, f32); + +#define init_buffer(ARENA, BUF) \ + _init_buffer(ARENA, (Buffer *)BUF, 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); +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); void save_image(const Image *img, const char *filename); diff --git a/src/main.c b/src/main.c index 17c0f66..9788bd8 100644 --- a/src/main.c +++ b/src/main.c @@ -36,7 +36,7 @@ int main(void) { return TINY_EXIT_MODEL_LOAD_FAILED; } - clear_image(&(render.img), bg); + clear_buffer(&(render.img), &bg); render_model(&model, &render, teal, RENDER_TYPE_SHADED, COLOUR_TYPE_FIXED); save_image(&(render.img), "result.pam"); diff --git a/src/obj.c b/src/obj.c index 246d83c..16ea246 100644 --- a/src/obj.c +++ b/src/obj.c @@ -8,6 +8,7 @@ #include #include #include +#include #define TRIANGLE_VERTICES 3 @@ -134,13 +135,18 @@ Model load_obj_file(Arena *arena, const char *filename) { bool init_render(Arena *arena, Render *render, u64 width, u64 height) { render->img = (Image){.width = width, .height = height}; - render->zbuf = (Image){.width = width, .height = height}; - - if (!init_image(arena, &(render->img)) || - !init_image(arena, &(render->zbuf))) { + if (!init_buffer(arena, &(render->img))) { return false; } + render->depth = (Depth){.width = width, .height = height}; + if (!init_buffer(arena, &(render->depth))) { + return false; + } + + f32 inf = INFINITY; + clear_buffer(&(render->depth), &inf); + return true; } @@ -232,7 +238,7 @@ 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); + set_pixel(img, x, y, &colour); } } } diff --git a/src/obj.h b/src/obj.h index 1f07fc3..65e824b 100644 --- a/src/obj.h +++ b/src/obj.h @@ -50,7 +50,7 @@ struct model { typedef struct render Render; struct render { Image img; - Image zbuf; + Depth depth; }; Model load_obj_file(Arena *arena, const char *filename);