diff --git a/compile b/compile index 1a38627..706ff02 100755 --- a/compile +++ b/compile @@ -12,6 +12,7 @@ RAYTRACER_SRC="src/window/*.c \ src/scene/*.c \ src/raytracer/*.c \ src/math/*.c \ + src/camera/*.c \ " RASTERISER_SRC="src/window/*.c \ @@ -20,6 +21,7 @@ RASTERISER_SRC="src/window/*.c \ src/list/*.c \ src/rasteriser/*.c \ src/math/*.c \ + src/camera/*.c \ $WAPP_SRC \ " diff --git a/include/camera/camera.h b/include/camera/camera.h new file mode 100644 index 0000000..c13a57c --- /dev/null +++ b/include/camera/camera.h @@ -0,0 +1,15 @@ +#ifndef CAMERA_H +#define CAMERA_H + +#include "vector/vec.h" +#include "window/window.h" + +typedef struct { + vec3f_t position; + vec3f_t rotation; +} camera_t; + +vec2i_t project_point(vec3f_t point, const window_t *wnd, + const camera_t *camera, vec3f_t viewport); + +#endif // !CAMERA_H diff --git a/include/window/window.h b/include/window/window.h index 1ac1d71..ba9f134 100644 --- a/include/window/window.h +++ b/include/window/window.h @@ -38,7 +38,8 @@ void clear_window(window_t *wnd, colour_t colour); void set_pixel(window_t *wnd, i32 x, i32 y, colour_t colour); void swap_buffers(window_t *wnd); -vec3f_t window_to_viewport(window_t *wnd, i32 x, i32 y, vec3f_t viewport); +vec3f_t window_to_viewport(const window_t *wnd, i32 x, i32 y, vec3f_t viewport); +vec2i_t viewport_to_window(const window_t *wnd, f32 x, f32 y, vec3f_t viewport); colour_t colour_add_colour(colour_t a, colour_t b); colour_t colour_mul(colour_t colour, f32 scalar); diff --git a/src/camera/camera.c b/src/camera/camera.c new file mode 100644 index 0000000..180987e --- /dev/null +++ b/src/camera/camera.c @@ -0,0 +1,15 @@ +#include "camera/camera.h" +#include "vector/vec.h" +#include "window/window.h" + +vec2i_t project_point(vec3f_t point, const window_t *wnd, + const camera_t *camera, vec3f_t viewport) { + if (point.z == 0.0f) { + return (vec2i_t){.x = 0, .y = 0}; + } + + f32 x = point.x * viewport.x / point.z; + f32 y = point.y * viewport.y / point.z; + + return viewport_to_window(wnd, x, y, viewport); +} diff --git a/src/rasteriser/main.c b/src/rasteriser/main.c index 899dd07..6c90563 100644 --- a/src/rasteriser/main.c +++ b/src/rasteriser/main.c @@ -1,3 +1,4 @@ +#include "camera/camera.h" #include "mem_arena.h" #include "mem_utils.h" #include "misc/misc_utils.h" @@ -11,6 +12,12 @@ int main(void) { colour_t bg = (colour_t){.rgba.r = 27, .rgba.g = 38, .rgba.b = 79, .rgba.a = 255}; + camera_t camera = { + .position = {.x = 0.0f, .y = 0.0f, .z = 0.0f}, + .rotation = {.x = 0.0f, .y = 0.0f, .z = 0.0f}, + }; + vec3f_t viewport = {.x = 1.0f, .y = 1.0f, .z = 1.0f}; + window_t window = {0}; if (!init_window(&window, 800, 800, "CG From Scratch Rasteriser")) { @@ -25,14 +32,47 @@ int main(void) { // i32 h_min = ((i32)window.half_height) * -1; // i32 h_max = (i32)window.half_height; - triangle_t triangle = { - .p0 = {-200, -250}, - .p1 = {200, 50}, - .p2 = {20, 250}, - .h0 = 0, - .h1 = 0, - .h2 = 1, - }; + // The four "front" vertices + vec3f_t vAf = {-2, -0.5, 5}; + vec3f_t vBf = {-2, 0.5, 5}; + vec3f_t vCf = {-1, 0.5, 5}; + vec3f_t vDf = {-1, -0.5, 5}; + + // The four "back" vertices + vec3f_t vAb = {-2, -0.5, 6}; + vec3f_t vBb = {-2, 0.5, 6}; + vec3f_t vCb = {-1, 0.5, 6}; + vec3f_t vDb = {-1, -0.5, 6}; + + // The front face + line_t lABf = {project_point(vAf, &window, &camera, viewport), + project_point(vBf, &window, &camera, viewport)}; + line_t lBCf = {project_point(vBf, &window, &camera, viewport), + project_point(vCf, &window, &camera, viewport)}; + line_t lCDf = {project_point(vCf, &window, &camera, viewport), + project_point(vDf, &window, &camera, viewport)}; + line_t lDAf = {project_point(vDf, &window, &camera, viewport), + project_point(vAf, &window, &camera, viewport)}; + + // The back face + line_t lABb = {project_point(vAb, &window, &camera, viewport), + project_point(vBb, &window, &camera, viewport)}; + line_t lBCb = {project_point(vBb, &window, &camera, viewport), + project_point(vCb, &window, &camera, viewport)}; + line_t lCDb = {project_point(vCb, &window, &camera, viewport), + project_point(vDb, &window, &camera, viewport)}; + line_t lDAb = {project_point(vDb, &window, &camera, viewport), + project_point(vAb, &window, &camera, viewport)}; + + // The front-to-back edges + line_t lABfb = {project_point(vAf, &window, &camera, viewport), + project_point(vAb, &window, &camera, viewport)}; + line_t lBCfb = {project_point(vBf, &window, &camera, viewport), + project_point(vBb, &window, &camera, viewport)}; + line_t lCDfb = {project_point(vCf, &window, &camera, viewport), + project_point(vCb, &window, &camera, viewport)}; + line_t lDAfb = {project_point(vDf, &window, &camera, viewport), + project_point(vDb, &window, &camera, viewport)}; Arena *arena = NULL; u64 capacity = 10ull * 1024ull * 1024ull * 1024ull; @@ -51,10 +91,20 @@ int main(void) { clear_window(&window, bg); - draw_shaded_triangle(&window, arena, triangle, - (colour_t){.colour = 0x00ff00ff}); - draw_wireframe_triangle(&window, arena, triangle, - (colour_t){.colour = 0xff008aff}); + draw_line(&window, arena, lABf, (colour_t){.colour = 0xffaa00ff}); + draw_line(&window, arena, lBCf, (colour_t){.colour = 0xffaa00ff}); + draw_line(&window, arena, lCDf, (colour_t){.colour = 0xffaa00ff}); + draw_line(&window, arena, lDAf, (colour_t){.colour = 0xffaa00ff}); + + draw_line(&window, arena, lABb, (colour_t){.colour = 0x00ffaaff}); + draw_line(&window, arena, lBCb, (colour_t){.colour = 0x00ffaaff}); + draw_line(&window, arena, lCDb, (colour_t){.colour = 0x00ffaaff}); + draw_line(&window, arena, lDAb, (colour_t){.colour = 0x00ffaaff}); + + draw_line(&window, arena, lABfb, (colour_t){.colour = 0xee0099ff}); + draw_line(&window, arena, lBCfb, (colour_t){.colour = 0xee0099ff}); + draw_line(&window, arena, lCDfb, (colour_t){.colour = 0xee0099ff}); + draw_line(&window, arena, lDAfb, (colour_t){.colour = 0xee0099ff}); swap_buffers(&window); diff --git a/src/raytracer/main.c b/src/raytracer/main.c index 554853c..53ac937 100644 --- a/src/raytracer/main.c +++ b/src/raytracer/main.c @@ -1,4 +1,5 @@ #include "aliases.h" +#include "camera/camera.h" #include "raytracer/raytracer.h" #include "scene/scene.h" #include "vector/vec.h" @@ -11,11 +12,6 @@ #define RECURSION_DEPTH 3 -typedef struct { - vec3f_t position; - vec3f_t rotation; -} camera_t; - i32 main(i32 argc, char *argv[]) { colour_t bg = (colour_t){.rgba.r = 27, .rgba.g = 38, .rgba.b = 79, .rgba.a = 255}; diff --git a/src/window/window.c b/src/window/window.c index 7fd7d8f..559949d 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -159,7 +159,8 @@ void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour) { pixels[index] = colour.colour; } -vec3f_t window_to_viewport(window_t *wnd, i32 x, i32 y, vec3f_t viewport) { +vec3f_t window_to_viewport(const window_t *wnd, i32 x, i32 y, + vec3f_t viewport) { return (vec3f_t){ .x = x * viewport.x / wnd->width, .y = y * viewport.y / wnd->height, @@ -167,6 +168,14 @@ vec3f_t window_to_viewport(window_t *wnd, i32 x, i32 y, vec3f_t viewport) { }; } +vec2i_t viewport_to_window(const window_t *wnd, f32 x, f32 y, + vec3f_t viewport) { + return (vec2i_t){ + .x = x / viewport.x * wnd->width, + .y = y / viewport.y * wnd->height, + }; +} + colour_t colour_add_colour(colour_t a, colour_t b) { f32 alpha = clamp((f32)(a.rgba.a + b.rgba.a), 0.0f, (f32)UINT8_MAX);