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 <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/img.h
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/img.h
									
									
									
									
									
								
							@@ -5,12 +5,12 @@
 | 
			
		||||
#include "mem_arena.h"
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/obj.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/obj.c
									
									
									
									
									
								
							@@ -8,6 +8,7 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user