summaryrefslogtreecommitdiff
path: root/src/renderer.c
blob: 54d3bd0b2896bd71b1a2c440f21f724055206479 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "renderer.h"
#include "screen.h"
#include "ray.h"

#include <math.h>
#include <stdio.h>
#include <string.h>

static void verline(Swapchain* swapchain, int x, int y0, int y1, uint32_t color) {
    for (int y = y0; y <= y1; y++) {
        swapchain->images[swapchain->image_current][(y * swapchain->width) + x] = color;
    }
}

void render(Screen* screen, const Camera* camera) {

    const v2 cam_right = {
        -sin(camera->angle),
        cos(camera->angle)
    };

    Swapchain* swapchain = &screen->swapchain;

    swapchain_next(swapchain);
    
    for (int x = 0; x < screen->swapchain.width; x++) {

        const float xcam = (2 * (x / (float) (swapchain->width))) - 1;
        const float change = camera->fov * atan(xcam);
        const float theta = camera->angle + change;

        v2 hit_pos;
        uint32_t hit = cast_ray(camera->pos, theta, &hit_pos);

        hit_pos.x -= camera->pos.x;
        hit_pos.y -= camera->pos.y;

        float len = v2_cross(hit_pos, cam_right) / v2_len(cam_right);

        uint32_t color;
        switch (hit) {
            case 1: color = 0xFFFF0000; break;
            case 2: color = 0xFF00FF00; break;
            case 3: color = 0xFF0000FF; break;
            case 4: color = 0xFFFF00FF; break;
            case 5: color = 0xFF00FFFF; break;
            default: color = 0xFF000000; break;
        }

        const int
            h = (int) (swapchain->height / len),
            y0 = max((swapchain->height / 2) - (h / 2), 0),
            y1 = min((swapchain->height / 2) + (h / 2), swapchain->height - 1);
        
        verline(swapchain, x, 0, y0, 0xFF202020);
        verline(swapchain, x, y0, y1, color);
        verline(swapchain, x, y1, swapchain->height - 1, 0xFF505050);
    }

    swapchain_submit(swapchain);
}