From ab469b8f37b66aa45de870372d5b0cc2061fd7b8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 23 Jun 2024 01:43:31 +0100 Subject: [PATCH] Use list in rasteriser --- compile | 1 + include/rasteriser/rasteriser.h | 4 ++ src/rasteriser/rasteriser.c | 71 ++++++++++++++++++++++++++++----- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/compile b/compile index e765c18..0f40c13 100755 --- a/compile +++ b/compile @@ -14,6 +14,7 @@ RAYTRACER_SRC="src/window/*.c \ RASTERISER_SRC="src/window/*.c \ src/vector/*.c \ src/scene/*.c \ + src/list/*.c \ src/rasteriser/*.c \ src/math/*.c \ " diff --git a/include/rasteriser/rasteriser.h b/include/rasteriser/rasteriser.h index 7287fed..f3054e5 100644 --- a/include/rasteriser/rasteriser.h +++ b/include/rasteriser/rasteriser.h @@ -1,9 +1,13 @@ #ifndef RASTERISER_H #define RASTERISER_H +#include "c_cpp_aliases/aliases.h" +#include "list/typed_list.h" #include "vector/vec.h" #include "window/window.h" +MAKE_LIST_TYPE(f32); + typedef struct { vec2i_t p0; vec2i_t p1; diff --git a/src/rasteriser/rasteriser.c b/src/rasteriser/rasteriser.c index b1041ae..3b11ddb 100644 --- a/src/rasteriser/rasteriser.c +++ b/src/rasteriser/rasteriser.c @@ -1,23 +1,76 @@ #include "rasteriser/rasteriser.h" #include "c_cpp_aliases/aliases.h" +#include "list/typed_list.h" #include "vector/vec.h" #include "window/window.h" +#include +#include +#include + +internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1); void draw_line(window_t *wnd, line_t line, colour_t colour) { - if (line.p1.x < line.p0.x) { - vec_swap(vec2i_t, line.p0, line.p1); - } - i32 x0 = line.p0.x; i32 y0 = line.p0.y; i32 x1 = line.p1.x; i32 y1 = line.p1.y; - f32 a = ((f32)y1 - y0) / ((f32)x1 - x0); - f32 y = y0; + list_float_t *values = NULL; - for (i32 x = x0; x <= x1; ++x) { - set_pixel(wnd, x, (i32)y, colour); - y += a; + if (abs(x1 - x0) > abs(y1 - y0)) { + if (line.p1.x < line.p0.x) { + vec_swap(vec2i_t, line.p0, line.p1); + } + + values = interpolate(x0, y0, x1, y1); + if (!values) { + return; + } + + for (i32 x = x0; x <= x1; ++x) { + set_pixel(wnd, x, (i32)(get(values, x - x0)), colour); + } + } else { + if (line.p1.y < line.p0.y) { + vec_swap(vec2i_t, line.p0, line.p1); + } + + values = interpolate(y0, x0, y1, x1); + if (!values) { + return; + } + + for (i32 y = y0; y <= y1; ++y) { + set_pixel(wnd, (i32)(get(values, y - y0)), y, colour); + } } + + destroy_list(f32, values); +} + +internal list_float_t *interpolate(i32 i0, f32 d0, i32 i1, f32 d1) { + list_float_t *values; + if (i0 == i1) { + values = create_list_with_capacity(f32, 20); + if (values) { + append(f32, values, d0); + } + + return values; + } + + values = create_list(f32); + if (!values) { + return NULL; + } + + f32 a = (d1 - d0) / ((f32)i1 - i0); + f32 d = d0; + + for (i32 i = i0; i <= i1; ++i) { + append(f32, values, d); + d += a; + } + + return values; }