Compare commits
2 Commits
e3c463d2f1
...
52dbae227d
Author | SHA1 | Date | |
---|---|---|---|
52dbae227d | |||
5636fa57fc |
7
.gitmodules
vendored
7
.gitmodules
vendored
@ -1,4 +1,3 @@
|
|||||||
[submodule "include/c_cpp_aliases"]
|
[submodule "intern/wapp"]
|
||||||
path = include/c_cpp_aliases
|
path = intern/wapp
|
||||||
url = https://git.thewizardapprentice.com/abdelrahman/c-cpp-aliases.git
|
url = https://git.thewizardapprentice.com/abdelrahman/wizapp-stdlib.git
|
||||||
branch = main
|
|
||||||
|
6
compile
6
compile
@ -1,7 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
WAPP_INCLUDE="$(find ./intern/wapp/src -type d | xargs -I{} echo -n "-I{} ")"
|
||||||
|
WAPP_SRC="$(find ./intern/wapp/src -type f -name "*.c" | xargs -I{} echo -n "{} ")"
|
||||||
|
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS="-g -Wall -Werror -pedantic -Iinclude $(pkg-config --cflags sdl2)"
|
CFLAGS="-g -Wall -Werror -pedantic -Iinclude $WAPP_INCLUDE $(pkg-config --cflags sdl2)"
|
||||||
LIBS="$(pkg-config --libs sdl2) -lm"
|
LIBS="$(pkg-config --libs sdl2) -lm"
|
||||||
|
|
||||||
RAYTRACER_SRC="src/window/*.c \
|
RAYTRACER_SRC="src/window/*.c \
|
||||||
@ -17,6 +20,7 @@ RASTERISER_SRC="src/window/*.c \
|
|||||||
src/list/*.c \
|
src/list/*.c \
|
||||||
src/rasteriser/*.c \
|
src/rasteriser/*.c \
|
||||||
src/math/*.c \
|
src/math/*.c \
|
||||||
|
$WAPP_SRC \
|
||||||
"
|
"
|
||||||
|
|
||||||
BUILD=build_dir
|
BUILD=build_dir
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 9f2e22e6cfd3e90b155110f1914f46494a3b0e7c
|
|
@ -1,7 +1,8 @@
|
|||||||
#ifndef TYPED_LIST_H
|
#ifndef TYPED_LIST_H
|
||||||
#define TYPED_LIST_H
|
#define TYPED_LIST_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -17,39 +18,27 @@
|
|||||||
u64 count; \
|
u64 count; \
|
||||||
} LIST_TYPE_NAME(T)
|
} LIST_TYPE_NAME(T)
|
||||||
|
|
||||||
#define list_create(T) \
|
#define list_create(T, ARENA) \
|
||||||
(LIST_TYPE_NAME(T) *)_create_list(sizeof(T), BASE_LIST_CAPACITY)
|
(LIST_TYPE_NAME(T) *)_create_list(ARENA, sizeof(T), BASE_LIST_CAPACITY)
|
||||||
#define list_create_with_capacity(T, CAPACITY) \
|
#define list_create_with_capacity(T, ARENA, CAPACITY) \
|
||||||
(LIST_TYPE_NAME(T) *)_create_list(sizeof(T), CAPACITY)
|
(LIST_TYPE_NAME(T) *)_create_list(ARENA, sizeof(T), CAPACITY)
|
||||||
|
|
||||||
#define list_destroy(T, LP) \
|
#define _increase_list_capacity(T, ARENA, LP, CAP) \
|
||||||
do { \
|
|
||||||
munmap(LP->items, sizeof(T) * LP->capacity); \
|
|
||||||
LP->items = NULL; \
|
|
||||||
LP->count = 0; \
|
|
||||||
LP->capacity = 0; \
|
|
||||||
munmap(LP, sizeof(LIST_TYPE_NAME(T))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define _increase_list_capacity(T, LP, CAP) \
|
|
||||||
do { \
|
do { \
|
||||||
u64 new_capacity = LP->capacity * 2; \
|
u64 new_capacity = LP->capacity * 2; \
|
||||||
T *tmp = _alloc_for_list(sizeof(T) * new_capacity); \
|
T *tmp = _alloc_for_list(ARENA, sizeof(T) * new_capacity); \
|
||||||
assert(tmp != NULL && "Failed to increase capacity"); \
|
assert(tmp != NULL && "Failed to increase capacity"); \
|
||||||
\
|
\
|
||||||
memcpy(tmp, LP->items, sizeof(T) * LP->count); \
|
memcpy(tmp, LP->items, sizeof(T) * LP->count); \
|
||||||
\
|
\
|
||||||
i32 deallocated = munmap(LP->items, sizeof(T) * LP->capacity); \
|
|
||||||
assert(deallocated == 0 && "Failed to deallocate old memory"); \
|
|
||||||
\
|
|
||||||
LP->capacity = new_capacity; \
|
LP->capacity = new_capacity; \
|
||||||
LP->items = tmp; \
|
LP->items = tmp; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define list_append(T, LP, ITEM) \
|
#define list_append(T, ARENA, LP, ITEM) \
|
||||||
do { \
|
do { \
|
||||||
if (LP->count + 1 >= LP->capacity) { \
|
if (LP->count + 1 >= LP->capacity) { \
|
||||||
_increase_list_capacity(T, LP, LP->capacity * 2); \
|
_increase_list_capacity(T, ARENA, LP, LP->capacity * 2); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
LP->items[(LP->count)++] = ITEM; \
|
LP->items[(LP->count)++] = ITEM; \
|
||||||
@ -59,13 +48,13 @@
|
|||||||
|
|
||||||
#define list_get(LP, IDX) LP->items[IDX]
|
#define list_get(LP, IDX) LP->items[IDX]
|
||||||
|
|
||||||
#define list_merge(T, DST, LP1, LP2) \
|
#define list_merge(T, ARENA, DST, LP1, LP2) \
|
||||||
do { \
|
do { \
|
||||||
u64 new_count = LP1->count + LP2->count; \
|
u64 new_count = LP1->count + LP2->count; \
|
||||||
u64 capacity = \
|
u64 capacity = \
|
||||||
new_count < BASE_LIST_CAPACITY ? BASE_LIST_CAPACITY : new_count * 2; \
|
new_count < BASE_LIST_CAPACITY ? BASE_LIST_CAPACITY : new_count * 2; \
|
||||||
\
|
\
|
||||||
DST = (LIST_TYPE_NAME(T) *)_create_list(new_count, capacity); \
|
DST = (LIST_TYPE_NAME(T) *)_create_list(ARENA, new_count, capacity); \
|
||||||
assert(DST != NULL && "Failed to allocate new list"); \
|
assert(DST != NULL && "Failed to allocate new list"); \
|
||||||
\
|
\
|
||||||
u64 lp1_copy_size = sizeof(T) * LP1->count; \
|
u64 lp1_copy_size = sizeof(T) * LP1->count; \
|
||||||
@ -79,7 +68,7 @@
|
|||||||
|
|
||||||
MAKE_LIST_TYPE(void);
|
MAKE_LIST_TYPE(void);
|
||||||
|
|
||||||
list_void_t *_create_list(u64 size, u64 count);
|
list_void_t *_create_list(Arena *arena, u64 size, u64 count);
|
||||||
void *_alloc_for_list(u64 size);
|
void *_alloc_for_list(Arena *arena, u64 size);
|
||||||
|
|
||||||
#endif // !TYPED_LIST_H
|
#endif // !TYPED_LIST_H
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
#ifndef MATH_UTILS_H
|
#ifndef MATH_UTILS_H
|
||||||
#define MATH_UTILS_H
|
#define MATH_UTILS_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define RADIANS(DEG) (DEG * (f32)M_PI / 180.0f)
|
#define RADIANS(DEG) (DEG * (f32)M_PI / 180.0f)
|
||||||
|
#define swap(T, v1, v2) \
|
||||||
|
{ \
|
||||||
|
T tmp = v1; \
|
||||||
|
v1 = v2; \
|
||||||
|
v2 = tmp; \
|
||||||
|
}
|
||||||
|
|
||||||
f32 clamp(f32 value, f32 min, f32 max);
|
f32 clamp(f32 value, f32 min, f32 max);
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#ifndef RASTERISER_H
|
#ifndef RASTERISER_H
|
||||||
#define RASTERISER_H
|
#define RASTERISER_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "list/typed_list.h"
|
#include "list/typed_list.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
|
|
||||||
@ -17,11 +18,17 @@ typedef struct {
|
|||||||
vec2i_t p0;
|
vec2i_t p0;
|
||||||
vec2i_t p1;
|
vec2i_t p1;
|
||||||
vec2i_t p2;
|
vec2i_t p2;
|
||||||
|
f32 h0;
|
||||||
|
f32 h1;
|
||||||
|
f32 h2;
|
||||||
} triangle_t;
|
} triangle_t;
|
||||||
|
|
||||||
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);
|
colour_t 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,
|
||||||
void draw_line(window_t *wnd, line_t line, colour_t colour);
|
colour_t colour);
|
||||||
|
void draw_shaded_triangle(window_t *wnd, Arena *arena, triangle_t triangle,
|
||||||
|
colour_t colour);
|
||||||
|
void draw_line(window_t *wnd, Arena *arena, line_t line, colour_t colour);
|
||||||
|
|
||||||
#endif // !RASTERISER_H
|
#endif // !RASTERISER_H
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef RAYTRACER_H
|
#ifndef RAYTRACER_H
|
||||||
#define RAYTRACER_H
|
#define RAYTRACER_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef SCENE_H
|
#ifndef SCENE_H
|
||||||
#define SCENE_H
|
#define SCENE_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef VEC_H
|
#ifndef VEC_H
|
||||||
#define VEC_H
|
#define VEC_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
i32 x;
|
i32 x;
|
||||||
@ -33,12 +33,6 @@ typedef struct {
|
|||||||
#define vec_dot(T, v1, v2) vec_dot_##T(v1, v2)
|
#define vec_dot(T, v1, v2) vec_dot_##T(v1, v2)
|
||||||
#define vec_magnitude(T, v) vec_magnitude_##T(v)
|
#define vec_magnitude(T, v) vec_magnitude_##T(v)
|
||||||
#define vec_unit(T, v) vec_unit_##T(v)
|
#define vec_unit(T, v) vec_unit_##T(v)
|
||||||
#define vec_swap(T, v1, v2) \
|
|
||||||
{ \
|
|
||||||
T tmp = v1; \
|
|
||||||
v1 = v2; \
|
|
||||||
v2 = tmp; \
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2);
|
vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2);
|
||||||
vec2i_t vec_sub_vec2i_t(vec2i_t v1, vec2i_t v2);
|
vec2i_t vec_sub_vec2i_t(vec2i_t v1, vec2i_t v2);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef WINDOW_H
|
#ifndef WINDOW_H
|
||||||
#define WINDOW_H
|
#define WINDOW_H
|
||||||
|
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
1
intern/wapp
Submodule
1
intern/wapp
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 8ed372d9388b65dd4d3651f8850a7a1f08d984de
|
@ -1,16 +1,18 @@
|
|||||||
#include "list/typed_list.h"
|
#include "list/typed_list.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
list_void_t *_create_list(u64 size, u64 count) {
|
list_void_t *_create_list(Arena *arena, u64 size, u64 count) {
|
||||||
list_void_t *list = (list_void_t *)_alloc_for_list(sizeof(list_void_t));
|
list_void_t *list =
|
||||||
|
(list_void_t *)_alloc_for_list(arena, sizeof(list_void_t));
|
||||||
if (!list) {
|
if (!list) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
list->items = (void *)_alloc_for_list(size * count);
|
list->items = (void *)_alloc_for_list(arena, size * count);
|
||||||
if (!list->items) {
|
if (!list->items) {
|
||||||
munmap(list, sizeof(list_void_t));
|
munmap(list, sizeof(list_void_t));
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -23,7 +25,6 @@ list_void_t *_create_list(u64 size, u64 count) {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_alloc_for_list(u64 size) {
|
void *_alloc_for_list(Arena *arena, u64 size) {
|
||||||
return mmap(NULL, size, PROT_READ | PROT_WRITE,
|
return wapp_mem_arena_alloc(arena, size);
|
||||||
MAP_ANON | MAP_NORESERVE | MAP_SHARED, -1, 0);
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "math/math_utils.h"
|
#include "math/math_utils.h"
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
|
|
||||||
f32 clamp(f32 value, f32 min, f32 max) {
|
f32 clamp(f32 value, f32 min, f32 max) {
|
||||||
if (value < min) {
|
if (value < min) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include "mem_arena.h"
|
||||||
|
#include "mem_utils.h"
|
||||||
#include "misc/misc_utils.h"
|
#include "misc/misc_utils.h"
|
||||||
#include "rasteriser/rasteriser.h"
|
#include "rasteriser/rasteriser.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
@ -27,8 +29,17 @@ int main(void) {
|
|||||||
.p0 = {-200, -250},
|
.p0 = {-200, -250},
|
||||||
.p1 = {200, 50},
|
.p1 = {200, 50},
|
||||||
.p2 = {20, 250},
|
.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 (running) {
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@ -40,13 +51,17 @@ int main(void) {
|
|||||||
|
|
||||||
clear_window(&window, bg);
|
clear_window(&window, bg);
|
||||||
|
|
||||||
draw_filled_triangle(&window, triangle, (colour_t){.colour = 0x00ff00ff});
|
draw_shaded_triangle(&window, arena, triangle,
|
||||||
draw_wireframe_triangle(&window, triangle,
|
(colour_t){.colour = 0x00ff00ff});
|
||||||
|
draw_wireframe_triangle(&window, arena, triangle,
|
||||||
(colour_t){.colour = 0x000000ff});
|
(colour_t){.colour = 0x000000ff});
|
||||||
|
|
||||||
swap_buffers(&window);
|
swap_buffers(&window);
|
||||||
|
|
||||||
|
wapp_mem_arena_clear(arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wapp_mem_arena_destroy(&arena);
|
||||||
close_window(&window);
|
close_window(&window);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "rasteriser/rasteriser.h"
|
#include "rasteriser/rasteriser.h"
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "list/typed_list.h"
|
#include "list/typed_list.h"
|
||||||
|
#include "math/math_utils.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -9,20 +11,22 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.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);
|
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) {
|
colour_t colour) {
|
||||||
order_triangle_points(&triangle);
|
order_triangle_points(&triangle);
|
||||||
|
|
||||||
draw_line(wnd, (line_t){triangle.p0, triangle.p1}, colour);
|
draw_line(wnd, arena, (line_t){triangle.p0, triangle.p1}, colour);
|
||||||
draw_line(wnd, (line_t){triangle.p1, triangle.p2}, colour);
|
draw_line(wnd, arena, (line_t){triangle.p1, triangle.p2}, colour);
|
||||||
draw_line(wnd, (line_t){triangle.p2, triangle.p0}, 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);
|
order_triangle_points(&triangle);
|
||||||
|
|
||||||
i32 x0 = triangle.p0.x;
|
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 x2 = triangle.p2.x;
|
||||||
i32 y2 = triangle.p2.y;
|
i32 y2 = triangle.p2.y;
|
||||||
|
|
||||||
list_float_t *x01 = interpolate(y0, x0, y1, x1);
|
list_float_t *x01 = interpolate(arena, y0, x0, y1, x1);
|
||||||
list_float_t *x12 = interpolate(y1, x1, y2, x2);
|
list_float_t *x12 = interpolate(arena, y1, x1, y2, x2);
|
||||||
list_float_t *x02 = interpolate(y0, x0, y2, x2);
|
list_float_t *x02 = interpolate(arena, y0, x0, y2, x2);
|
||||||
list_float_t *x012 = NULL;
|
list_float_t *x012 = NULL;
|
||||||
|
|
||||||
list_pop(x01); // Last element of x01 is a duplicate of first element in x12
|
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_left;
|
||||||
list_float_t *x_right;
|
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 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);
|
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;
|
list_float_t *values = NULL;
|
||||||
|
|
||||||
if (abs(line.p1.x - line.p0.x) > abs(line.p1.y - line.p0.y)) {
|
if (abs(line.p1.x - line.p0.x) > abs(line.p1.y - line.p0.y)) {
|
||||||
if (line.p1.x < line.p0.x) {
|
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;
|
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 x1 = line.p1.x;
|
||||||
i32 y1 = line.p1.y;
|
i32 y1 = line.p1.y;
|
||||||
|
|
||||||
values = interpolate(x0, y0, x1, y1);
|
values = interpolate(arena, x0, y0, x1, y1);
|
||||||
if (!values) {
|
if (!values) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,7 +153,7 @@ void draw_line(window_t *wnd, line_t line, colour_t colour) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (line.p1.y < line.p0.y) {
|
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;
|
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 x1 = line.p1.x;
|
||||||
i32 y1 = line.p1.y;
|
i32 y1 = line.p1.y;
|
||||||
|
|
||||||
values = interpolate(y0, x0, y1, x1);
|
values = interpolate(arena, y0, x0, y1, x1);
|
||||||
if (!values) {
|
if (!values) {
|
||||||
return;
|
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);
|
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;
|
list_float_t *values;
|
||||||
if (i0 == i1) {
|
if (i0 == i1) {
|
||||||
values = list_create_with_capacity(f32, 20);
|
values = list_create_with_capacity(f32, arena, 20);
|
||||||
if (values) {
|
if (values) {
|
||||||
list_append(f32, values, d0);
|
list_append(f32, arena, values, d0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
values = list_create(f32);
|
values = list_create(f32, arena);
|
||||||
if (!values) {
|
if (!values) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -122,7 +193,7 @@ internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1) {
|
|||||||
f32 d = d0;
|
f32 d = d0;
|
||||||
|
|
||||||
for (i32 i = i0; i <= i1; ++i) {
|
for (i32 i = i0; i <= i1; ++i) {
|
||||||
list_append(f32, values, d);
|
list_append(f32, arena, values, d);
|
||||||
d += a;
|
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) {
|
internal inline void order_triangle_points(triangle_t *triangle) {
|
||||||
if (triangle->p1.y < triangle->p0.y) {
|
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) {
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "raytracer/raytracer.h"
|
#include "raytracer/raytracer.h"
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "raytracer/raytracer.h"
|
#include "raytracer/raytracer.h"
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "misc/misc_utils.h"
|
#include "misc/misc_utils.h"
|
||||||
|
|
||||||
internal const sphere_t spheres[] = {
|
internal const sphere_t spheres[] = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "window/window.h"
|
#include "window/window.h"
|
||||||
#include "c_cpp_aliases/aliases.h"
|
#include "aliases.h"
|
||||||
#include "math/math_utils.h"
|
#include "math/math_utils.h"
|
||||||
#include "vector/vec.h"
|
#include "vector/vec.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user