Create generic buffer type
This commit is contained in:
		
							
								
								
									
										35
									
								
								src/img.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/img.c
									
									
									
									
									
								
							| @@ -4,31 +4,28 @@ | |||||||
| #include "utils.h" | #include "utils.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
| #define SAMPLES_PER_PIXEL 4 | bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size) { | ||||||
|  |   if (!arena || !buffer || buffer->width == 0 || buffer->height == 0) { | ||||||
| bool init_image(Arena *arena, Image *img) { |  | ||||||
|   if (!arena || !img || img->width == 0 || img->height == 0) { |  | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   u64 size = img->width * img->height * SAMPLES_PER_PIXEL; |   u64 size = buffer->width * buffer->height * base_size; | ||||||
|   img->buf = wapp_mem_arena_alloc(arena, 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) { | void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { | ||||||
|   u64 idx = (y * img->width + x) * SAMPLES_PER_PIXEL; |   u64 idx = (y * buffer->width + x) * base_size; | ||||||
|   for (u64 i = 0; i < SAMPLES_PER_PIXEL; ++i) { |   memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); | ||||||
|     img->buf[idx + i] = *(((u8 *)&colour) + i); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void clear_image(Image *img, Colour colour) { | void _clear_buffer(Buffer *buffer, void *value, u64 base_size) { | ||||||
|   for (u64 y = 0; y < img->height; ++y) { |   for (u64 y = 0; y < buffer->height; ++y) { | ||||||
|     for (u64 x = 0; x < img->width; ++x) { |     for (u64 x = 0; x < buffer->width; ++x) { | ||||||
|       set_pixel(img, x, y, colour); |       _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) { |     for (u64 x = x0; x < x1; ++x) { | ||||||
|       t = (f32)(x - x0) / (f32)(x1 - x0); |       t = (f32)(x - x0) / (f32)(x1 - x0); | ||||||
|       y = (i64)y0 + ((i64)y1 - (i64)y0) * t; |       y = (i64)y0 + ((i64)y1 - (i64)y0) * t; | ||||||
|       set_pixel(img, x, y, colour); |       set_pixel(img, x, y, &colour); | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     if (y0 > y1) { |     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) { |     for (u64 y = y0; y < y1; ++y) { | ||||||
|       t = (f32)(y - y0) / (f32)(y1 - y0); |       t = (f32)(y - y0) / (f32)(y1 - y0); | ||||||
|       x = (i64)x0 + ((i64)x1 - (i64)x0) * t; |       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) { | 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); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								src/img.h
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/img.h
									
									
									
									
									
								
							| @@ -5,12 +5,12 @@ | |||||||
| #include "mem_arena.h" | #include "mem_arena.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
| typedef struct img Image; | #define BUF_TYPE(NAME, TYPE)                                                   \ | ||||||
| struct img { |   typedef struct {                                                             \ | ||||||
|   u64 width; |     u64 width;                                                                 \ | ||||||
|   u64 height; |     u64 height;                                                                \ | ||||||
|   u8 *buf; |     TYPE *buf;                                                                 \ | ||||||
| }; |   } NAME | ||||||
|  |  | ||||||
| typedef struct colour Colour; | typedef struct colour Colour; | ||||||
| struct colour { | struct colour { | ||||||
| @@ -20,9 +20,20 @@ struct colour { | |||||||
|   u8 a; |   u8 a; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| bool init_image(Arena *arena, Image *img); | BUF_TYPE(Buffer, void); | ||||||
| void set_pixel(Image *img, u64 x, u64 y, Colour colour); | BUF_TYPE(Image, Colour); | ||||||
| void clear_image(Image *img, Colour 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 draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour); | ||||||
| void save_image(const Image *img, const char *filename); | void save_image(const Image *img, const char *filename); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ int main(void) { | |||||||
|     return TINY_EXIT_MODEL_LOAD_FAILED; |     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); |   render_model(&model, &render, teal, RENDER_TYPE_SHADED, COLOUR_TYPE_FIXED); | ||||||
|   save_image(&(render.img), "result.pam"); |   save_image(&(render.img), "result.pam"); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								src/obj.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/obj.c
									
									
									
									
									
								
							| @@ -8,6 +8,7 @@ | |||||||
| #include <math.h> | #include <math.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
| #define TRIANGLE_VERTICES 3 | #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) { | bool init_render(Arena *arena, Render *render, u64 width, u64 height) { | ||||||
|   render->img = (Image){.width = width, .height = height}; |   render->img = (Image){.width = width, .height = height}; | ||||||
|   render->zbuf = (Image){.width = width, .height = height}; |   if (!init_buffer(arena, &(render->img))) { | ||||||
|  |  | ||||||
|   if (!init_image(arena, &(render->img)) || |  | ||||||
|       !init_image(arena, &(render->zbuf))) { |  | ||||||
|     return false; |     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; |   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) { |       if (coords.x < 0.0f || coords.y < 0.0f || coords.z < 0.0f) { | ||||||
|         continue; |         continue; | ||||||
|       } |       } | ||||||
|       set_pixel(img, x, y, colour); |       set_pixel(img, x, y, &colour); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ struct model { | |||||||
| typedef struct render Render; | typedef struct render Render; | ||||||
| struct render { | struct render { | ||||||
|   Image img; |   Image img; | ||||||
|   Image zbuf; |   Depth depth; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Model load_obj_file(Arena *arena, const char *filename); | Model load_obj_file(Arena *arena, const char *filename); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user