summaryrefslogtreecommitdiff
path: root/gastro/include/lcq/gastro.h
blob: fd4e158c06f15e7c93d208ea0fcb7ff1ad61cc86 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef LCOLONQ_GASTRO_H
#define LCOLONQ_GASTRO_H

#include <lcq/prelude.h>

#define GASTRO_FIXED_POINT 16
typedef i64 gastro_fix;
#define GASTRO_FIX_ONE (1 << GASTRO_FIXED_POINT)
#define GASTRO_FIX_HALF 0x8000
gastro_fix gastro_fix_new(i64 x);
i64 gastro_fix_to_i64(gastro_fix x);
gastro_fix gastro_fix_from_double(double x);
double gastro_fix_to_double(gastro_fix x);
gastro_fix gastro_fix_mul(gastro_fix x, gastro_fix y);
gastro_fix gastro_fix_div(gastro_fix x, gastro_fix y);
gastro_fix gastro_fix_sqrt(gastro_fix s);

typedef struct { gastro_fix x, y; } gastro_vec2;
gastro_vec2 gastro_vec2_new(gastro_fix x, gastro_fix y);
gastro_vec2 gastro_vec2_add(gastro_vec2 x, gastro_vec2 y);
gastro_vec2 gastro_vec2_sub(gastro_vec2 x, gastro_vec2 y);
gastro_fix gastro_vec2_length(gastro_vec2 v);
gastro_fix gastro_vec2_cross(gastro_vec2 v, gastro_vec2 u);
typedef struct { gastro_fix x, y, z; } gastro_vec3;
gastro_vec3 gastro_vec3_new(gastro_fix x, gastro_fix y, gastro_fix z);
void gastro_vec3_print(gastro_vec3 v);
gastro_vec2 gastro_vec3_xy(gastro_vec3 v);
gastro_vec3 gastro_vec3_perspective(gastro_fix nearz, gastro_vec3 p);
gastro_fix gastro_vec3_bary_interpolate(gastro_vec3 bary, gastro_fix x, gastro_fix y, gastro_fix z);
gastro_fix gastro_vec3_bary_interpolate_inv(gastro_vec3 bary, gastro_fix x, gastro_fix y, gastro_fix z);
typedef struct { gastro_fix x, y, z, w; } gastro_vec4;
gastro_vec4 gastro_vec4_new(gastro_fix x, gastro_fix y, gastro_fix z, gastro_fix w);
void gastro_vec4_print(gastro_vec4 v);
gastro_vec3 gastro_vec4_xyz(gastro_vec4 v);
gastro_fix gastro_vec4_idx(gastro_vec4 v, i64 idx);
gastro_fix gastro_vec4_dot(gastro_vec4 a, gastro_vec4 b);

typedef struct { gastro_vec4 rows[4]; } gastro_mat4x4;
gastro_mat4x4 gastro_mat4x4_new(
    gastro_fix  e0, gastro_fix  e1, gastro_fix  e2, gastro_fix  e3,
    gastro_fix  e4, gastro_fix  e5, gastro_fix  e6, gastro_fix  e7,
    gastro_fix  e8, gastro_fix  e9, gastro_fix e10, gastro_fix e11,
    gastro_fix e12, gastro_fix e13, gastro_fix e14, gastro_fix e15);
void gastro_mat4x4_print(gastro_mat4x4 m);
gastro_vec4 gastro_mat4x4_mul_vec4(gastro_mat4x4 m, gastro_vec4 v);
gastro_mat4x4 gastro_mat4x4_mul_mat4x4(gastro_mat4x4 m, gastro_mat4x4 n);

typedef struct {
    u8 r, g, b, a;
} gastro_color;
gastro_color gastro_color_new(u8 r, u8 g, u8 b, u8 a);

typedef struct {
    u32 width, height;
    gastro_color *pixels;
    gastro_fix *depth;
} gastro_ctx;

gastro_vec3 gastro_vec3_denormalize(gastro_ctx *ctx, gastro_vec3 p);

void gastro_ctx_init(gastro_ctx *ret, u32 width, u32 height, gastro_color *pixels, gastro_fix *depth);
void gastro_draw_pixel(gastro_ctx *ctx, gastro_color col, gastro_fix z, i64 x, i64 y);
void gastro_draw_clear(gastro_ctx *ctx, gastro_color col);

typedef struct {
    gastro_vec3 v;
    gastro_fix *attrs;
} gastro_vertex;
typedef gastro_vec4 (*gastro_shader_vertex)(gastro_ctx *ctx, gastro_vec3 v, gastro_fix *attrs, i64 attrs_len);
typedef gastro_color (*gastro_shader_fragment)(gastro_ctx *ctx, gastro_vec3 v, gastro_fix *attrs, i64 attrs_len);
typedef struct {
    gastro_shader_vertex vertex;
    gastro_shader_fragment fragment;
} gastro_program;
gastro_vertex gastro_program_vertex(gastro_ctx *ctx, gastro_program *p, gastro_vec3 v, gastro_fix *attrs, i64 attrs_len);
gastro_color gastro_program_fragment(gastro_ctx *ctx, gastro_program *p, gastro_vec3 v, gastro_fix *attrs, i64 attrs_len);

void gastro_render_triangle(gastro_ctx *ctx, gastro_program *p, gastro_vertex p0, gastro_vertex p1, gastro_vertex p2, i64 attrs_len);
void gastro_render_triangles(gastro_ctx *ctx, gastro_program *p, gastro_fix *vs, i64 elem_size, i64 *idxs, i64 num_triangles);

#include <lcq/gastro/trig.h>

#endif