Switch list to use memory arena

This commit is contained in:
2024-06-27 23:57:14 +01:00
parent 5636fa57fc
commit 52dbae227d
6 changed files with 151 additions and 65 deletions

View File

@@ -1,3 +1,5 @@
#include "mem_arena.h"
#include "mem_utils.h"
#include "misc/misc_utils.h"
#include "rasteriser/rasteriser.h"
#include "vector/vec.h"
@@ -27,8 +29,17 @@ int main(void) {
.p0 = {-200, -250},
.p1 = {200, 50},
.p2 = {20, 250},
.h0 = 0,
.h1 = 0,
.h2 = 1,
};
Arena *arena = NULL;
u64 capacity = 10ull * 1024ull * 1024ull * 1024ull;
if (!wapp_mem_arena_init(&arena, capacity, WAPP_MEM_ALLOC_RESERVE, false)) {
return EXIT_FAILURE;
}
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
@@ -40,13 +51,17 @@ int main(void) {
clear_window(&window, bg);
draw_filled_triangle(&window, triangle, (colour_t){.colour = 0x00ff00ff});
draw_wireframe_triangle(&window, triangle,
draw_shaded_triangle(&window, arena, triangle,
(colour_t){.colour = 0x00ff00ff});
draw_wireframe_triangle(&window, arena, triangle,
(colour_t){.colour = 0x000000ff});
swap_buffers(&window);
wapp_mem_arena_clear(arena);
}
wapp_mem_arena_destroy(&arena);
close_window(&window);
return EXIT_SUCCESS;

View File

@@ -1,6 +1,8 @@
#include "rasteriser/rasteriser.h"
#include "c_cpp_aliases/aliases.h"
#include "aliases.h"
#include "list/typed_list.h"
#include "math/math_utils.h"
#include "mem_arena.h"
#include "vector/vec.h"
#include "window/window.h"
#include <assert.h>
@@ -9,20 +11,22 @@
#include <string.h>
#include <sys/mman.h>
internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1);
internal list_float_t *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1,
f32 d1);
internal inline void order_triangle_points(triangle_t *triangle);
void draw_wireframe_triangle(window_t *wnd, triangle_t triangle,
void draw_wireframe_triangle(window_t *wnd, Arena *arena, triangle_t triangle,
colour_t colour) {
order_triangle_points(&triangle);
draw_line(wnd, (line_t){triangle.p0, triangle.p1}, colour);
draw_line(wnd, (line_t){triangle.p1, triangle.p2}, colour);
draw_line(wnd, (line_t){triangle.p2, triangle.p0}, colour);
draw_line(wnd, arena, (line_t){triangle.p0, triangle.p1}, colour);
draw_line(wnd, arena, (line_t){triangle.p1, triangle.p2}, colour);
draw_line(wnd, arena, (line_t){triangle.p2, triangle.p0}, colour);
}
void draw_filled_triangle(window_t *wnd, triangle_t triangle, colour_t colour) {
void draw_filled_triangle(window_t *wnd, Arena *arena, triangle_t triangle,
colour_t colour) {
order_triangle_points(&triangle);
i32 x0 = triangle.p0.x;
@@ -32,13 +36,13 @@ void draw_filled_triangle(window_t *wnd, triangle_t triangle, colour_t colour) {
i32 x2 = triangle.p2.x;
i32 y2 = triangle.p2.y;
list_float_t *x01 = interpolate(y0, x0, y1, x1);
list_float_t *x12 = interpolate(y1, x1, y2, x2);
list_float_t *x02 = interpolate(y0, x0, y2, x2);
list_float_t *x01 = interpolate(arena, y0, x0, y1, x1);
list_float_t *x12 = interpolate(arena, y1, x1, y2, x2);
list_float_t *x02 = interpolate(arena, y0, x0, y2, x2);
list_float_t *x012 = NULL;
list_pop(x01); // Last element of x01 is a duplicate of first element in x12
list_merge(f32, x012, x01, x12);
list_merge(f32, arena, x012, x01, x12);
list_float_t *x_left;
list_float_t *x_right;
@@ -52,18 +56,86 @@ void draw_filled_triangle(window_t *wnd, triangle_t triangle, colour_t colour) {
}
for (i64 y = y0; y <= y2; ++y) {
for (i64 x = list_get(x_left, y - y0); x < list_get(x_right, y - y0); ++x) {
i32 index = y - y0;
for (i64 x = (i64)list_get(x_left, index); x < list_get(x_right, index);
++x) {
set_pixel(wnd, x, y, colour);
}
}
}
void draw_line(window_t *wnd, line_t line, colour_t colour) {
void draw_shaded_triangle(window_t *wnd, Arena *arena, triangle_t triangle,
colour_t colour) {
order_triangle_points(&triangle);
i32 x0 = triangle.p0.x;
i32 y0 = triangle.p0.y;
i32 x1 = triangle.p1.x;
i32 y1 = triangle.p1.y;
i32 x2 = triangle.p2.x;
i32 y2 = triangle.p2.y;
list_float_t *x01 = interpolate(arena, y0, x0, y1, x1);
list_float_t *x12 = interpolate(arena, y1, x1, y2, x2);
list_float_t *x02 = interpolate(arena, y0, x0, y2, x2);
list_float_t *x012 = NULL;
list_pop(x01); // Last element of x01 is a duplicate of first element in x12
list_merge(f32, arena, x012, x01, x12);
f32 h0 = triangle.h0;
f32 h1 = triangle.h1;
f32 h2 = triangle.h2;
list_float_t *h01 = interpolate(arena, y0, h0, y1, h1);
list_float_t *h12 = interpolate(arena, y1, h1, y2, h2);
list_float_t *h02 = interpolate(arena, y0, h0, y2, h2);
list_float_t *h012 = NULL;
list_pop(h01); // Last element of h01 is a duplicate of first element in h12
list_merge(f32, arena, h012, h01, h12);
list_float_t *x_left;
list_float_t *x_right;
list_float_t *h_left;
list_float_t *h_right;
u64 middle = (u64)(floorf((f32)(x02->count) / 2.0f));
if (list_get(x02, middle) < list_get(x012, middle)) {
x_left = x02;
h_left = h02;
x_right = x012;
h_right = h012;
} else {
x_left = x012;
h_left = h012;
x_right = x02;
h_right = h02;
}
list_float_t *h_segment = NULL;
i32 index = -1;
i64 xl = -1;
i64 xr = -1;
colour_t shaded_colour = (colour_t){0};
for (i64 y = y0; y <= y2; ++y) {
index = y - y0;
xl = (i64)list_get(x_left, index);
xr = (i64)list_get(x_right, index);
for (i64 x = xl; x < xr; ++x) {
h_segment = interpolate(arena, xl, list_get(h_left, index), xr,
list_get(h_right, index));
shaded_colour = colour_mul(colour, list_get(h_segment, x - xl));
set_pixel(wnd, x, y, shaded_colour);
}
}
}
void draw_line(window_t *wnd, Arena *arena, line_t line, colour_t colour) {
list_float_t *values = NULL;
if (abs(line.p1.x - line.p0.x) > abs(line.p1.y - line.p0.y)) {
if (line.p1.x < line.p0.x) {
vec_swap(vec2i_t, line.p0, line.p1);
swap(vec2i_t, line.p0, line.p1);
}
i32 x0 = line.p0.x;
@@ -71,7 +143,7 @@ void draw_line(window_t *wnd, line_t line, colour_t colour) {
i32 x1 = line.p1.x;
i32 y1 = line.p1.y;
values = interpolate(x0, y0, x1, y1);
values = interpolate(arena, x0, y0, x1, y1);
if (!values) {
return;
}
@@ -81,7 +153,7 @@ void draw_line(window_t *wnd, line_t line, colour_t colour) {
}
} else {
if (line.p1.y < line.p0.y) {
vec_swap(vec2i_t, line.p0, line.p1);
swap(vec2i_t, line.p0, line.p1);
}
i32 x0 = line.p0.x;
@@ -89,7 +161,7 @@ void draw_line(window_t *wnd, line_t line, colour_t colour) {
i32 x1 = line.p1.x;
i32 y1 = line.p1.y;
values = interpolate(y0, x0, y1, x1);
values = interpolate(arena, y0, x0, y1, x1);
if (!values) {
return;
}
@@ -98,22 +170,21 @@ void draw_line(window_t *wnd, line_t line, colour_t colour) {
set_pixel(wnd, (i32)(list_get(values, y - y0)), y, colour);
}
}
list_destroy(f32, values);
}
internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1) {
internal list_float_t *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1,
f32 d1) {
list_float_t *values;
if (i0 == i1) {
values = list_create_with_capacity(f32, 20);
values = list_create_with_capacity(f32, arena, 20);
if (values) {
list_append(f32, values, d0);
list_append(f32, arena, values, d0);
}
return values;
}
values = list_create(f32);
values = list_create(f32, arena);
if (!values) {
return NULL;
}
@@ -122,7 +193,7 @@ internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1) {
f32 d = d0;
for (i32 i = i0; i <= i1; ++i) {
list_append(f32, values, d);
list_append(f32, arena, values, d);
d += a;
}
@@ -131,12 +202,15 @@ internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1) {
internal inline void order_triangle_points(triangle_t *triangle) {
if (triangle->p1.y < triangle->p0.y) {
vec_swap(vec2i_t, triangle->p0, triangle->p1);
swap(vec2i_t, triangle->p0, triangle->p1);
swap(f32, triangle->h0, triangle->h1);
}
if (triangle->p2.y < triangle->p0.y) {
vec_swap(vec2i_t, triangle->p0, triangle->p2);
swap(vec2i_t, triangle->p0, triangle->p2);
swap(f32, triangle->h0, triangle->h2);
}
if (triangle->p2.y < triangle->p1.y) {
vec_swap(vec2i_t, triangle->p1, triangle->p2);
swap(vec2i_t, triangle->p1, triangle->p2);
swap(f32, triangle->h1, triangle->h2);
}
}