From e6f8a3356a91e0304e9965c7b8bfc2f06a2b79cc Mon Sep 17 00:00:00 2001 From: quou Date: Sat, 6 Jul 2024 17:55:46 +1000 Subject: Triangle fill. --- 3de.c | 39 ++++++++++++++----- config.h | 4 +- maths.c | 1 - render.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- render.h | 18 ++++++++- 5 files changed, 178 insertions(+), 17 deletions(-) diff --git a/3de.c b/3de.c index 6bf9e33..8af3d18 100644 --- a/3de.c +++ b/3de.c @@ -20,29 +20,42 @@ void draw_torus(Renderer* r, Colour c) { static int a = 0; const int pc = sizeof torus_points / sizeof *torus_points; int asp = (r->clip.w << fbits) / r->clip.h; - int p[4] = { 0, 0, 5 << fbits, f1 }; - int i; + int p[4 * 3] = { 0, 0, 5 << fbits, f1, 0, 0, 0, f1, 0, 0, 0, f1 }, * wp; + int i, j; mtx_push_trans(p); mtx_push_rot_x(a); mtx_push_rot_y(a); mtx_push_rot_z(a); - for (i = 0; i < pc; i += 3) { - vec_cpy(p, &torus_points[i], 3); - mtx_apply(mtx_peek(), p); - persp(p, asp); - ndc2clip((int*)&r->clip, p); - ren_point(r, c, p[0], p[1]); + for (i = 0; i < pc; i += 9) { + for (j = 0; j < 3; j++) { + wp = &p[j * 4]; + vec_cpy(wp, &torus_points[i + j * 3], 3); + mtx_apply(mtx_peek(), wp); + persp(wp, asp); + ndc2clip((int*)&r->clip, wp); + } + ren_tri(r, c, &p[0], &p[4], &p[8], tri_mode_flat); } mtx_popn(4); a += 3; } +void draw_tri(Renderer* r, Colour c, int x, int y) { + int v0[] = { 100, 100 }; + int v1[] = { 0, 0 }; + int v2[] = { 150, 300 }; + v1[0] = x; + v1[1] = y; + ren_tri(r, c, v0, v1, v2, tri_mode_flat); +} + int entrypoint(int argc, const char** argv, Arena* a) { App* app; - Renderer r; + Renderer r = { 0 }; Heap h; FPS f; char buf[32]; + int* depth = 0; Colour blue = make_aliceblue(); (void)argc; (void)argv; @@ -55,12 +68,18 @@ int entrypoint(int argc, const char** argv, Arena* a) { app = new_app(&h, 640, 480, "3D Engine"); if (!app) return app->err; init_fps(&f, 20); + depth = heap_alloc(&h, 3000 * 3000 * sizeof *depth); + if (!depth) { + print_err("Out of memory.\n"); + return error_out_of_memory; + } while (app->o) { fps_begin(&f); while (f.now >= f.next) { app_begin(app); - ren_begin(&r, app->fb, app->w, app->h); + ren_begin(&r, app->fb, depth, app->w, app->h); ren_clear(&r); + ren_cleard(&r, f1 * 300); sprintf(buf, "FPS: %d", app->fps); ren_text(&r, blue, 3, 3, buf); sprintf(buf, "CAP: %d", f.fps); diff --git a/config.h b/config.h index 96094dd..31e98f4 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef config_h #define config_h -#define memory_size (1024 * 1024 * 32) -#define app_memory_size (1024 * 1024 * 16) +#define memory_size (1024 * 1024 * 128) +#define app_memory_size (1024 * 1024 * 64) #endif diff --git a/maths.c b/maths.c index db11491..74d682d 100644 --- a/maths.c +++ b/maths.c @@ -232,7 +232,6 @@ void persp(int* v, int asp) { v[2] += !v[2]; v[0] = ((v[0] << fbits) / v[2]); v[1] = ((v[1] << fbits) / v[2]) * asp >> fbits; - v[2] = f1; } void ndc2clip(int* c, int* p) { diff --git a/render.c b/render.c index 74da997..5949ee9 100644 --- a/render.c +++ b/render.c @@ -1,3 +1,5 @@ +#include "maths.h" +#include "plat.h" #include "render.h" static int font_w = 960; @@ -121,10 +123,11 @@ Colour blend_mod(Colour dst, Colour src, Colour mod) { } -void ren_begin(Renderer* r, Colour* t, int w, int h) { +void ren_begin(Renderer* r, Colour* t, int* d, int w, int h) { r->t = t; r->w = w; r->h = h; + r->d = d; r->clip.x = 0; r->clip.y = 0; r->clip.w = w; @@ -149,6 +152,13 @@ void ren_clearc(Renderer* r, Colour c) { *d = c; } +void ren_cleard(Renderer* r, int depth) { + int* d = r->d; + int i = 0, e = r->w * r->h; + for (i = 0; i < e; i++, d++) + *d = depth; +} + void ren_clip(Renderer* r, const Rect* c) { r->clip = *c; } @@ -183,8 +193,8 @@ void ren_char( for (j = re.y, l = sub.y; j < ey; j++, l++) { for (i = re.x, k = sub.x; i < ex; i++, k++) { int si = k + l * font_w; - unsigned bits = font_data[si / 32]; - int bit = bits & (1 << si % 32); + unsigned bits = font_data[si >> 5]; + int bit = bits & 1 << (si & 0x1f); if (bit) *dst = blend(*dst, c); dst++; @@ -205,3 +215,120 @@ void ren_text( ren_char(r, c, x, y, *s); } +#define max_tri_ec 2 + +void swap_vert(int* a, int* b, int ec) { + int t, i; + for (i = 0; i < ec; i++) { + t = a[i]; + a[i] = b[i]; + b[i] = t; + } +} + +int tri_hand(int* v0, int* v1, int* v2) { + return + (v1[0] - v0[0]) * (v2[1] - v0[1]) - + (v2[0] - v0[0]) * (v1[1] - v0[1]) > 0; +} + +void ren_tri( + Renderer* r, + Colour c, + int* v0, + int* v1, + int* v2, + Tri_Mode mode +) { + int ec, sx, ex, x, y, me, ms, e, ha; + int sb = 0, * d; + switch (mode) { + case tri_mode_flat: + ec = 2; + break; + default: assert(0); + } + if (v0[1] > v1[1]) + swap_vert(v0, v1, ec); + if (v1[1] > v2[1]) + swap_vert(v1, v2, ec); + if (v0[1] > v1[1]) + swap_vert(v0, v1, ec); + ha = tri_hand(v0, v1, v2); + sb = v1[1] == v2[1]; + if (v0[1] == v1[1]) goto rb; + if (ha) { + ms = + ((v2[0] - v0[0]) << fbits) / + (v2[1] - v0[1]); + me = + ((v1[0] - v0[0]) << fbits) / + (v1[1] - v0[1]); + sx = v0[0] << fbits; + ex = v0[0] << fbits; + } else { + ms = + ((v1[0] - v0[0]) << fbits) / + (v1[1] - v0[1]); + me = + ((v2[0] - v0[0]) << fbits) / + (v2[1] - v0[1]); + sx = v0[0] << fbits; + ex = v0[0] << fbits; + } + for ( + y = v0[1]; + y <= v1[1]; + y++, sx += ms, ex += me + ) for ( + x = sx >> fbits, + e = ex >> fbits; + x < e; + x++ + ) { + d = &r->d[x + y * r->w]; + if (*d > v0[2]) { + *d = v0[2]; + r->t[x + y * r->w] = c; + } + } +rb: + if (sb) return; + if (ha) { + ms = ((v2[0] - v0[0]) << fbits) / + (v2[1] - v0[1]); + me = + ((v2[0] - v1[0]) << fbits) / + (v2[1] - v1[1]); + sx = + (v0[0] << fbits) + (v1[1] - v0[1]) * ms + 1; + ex = v1[0] << fbits; + } else { + me = + ((v2[0] - v0[0]) << fbits) / + (v2[1] - v0[1]); + ms = + ((v2[0] - v1[0]) << fbits) / + (v2[1] - v1[1]); + sx = v1[0] << fbits; + ex = + (v0[0] << fbits) + (v1[1] - v0[1]) * me + 1; + } + for ( + y = v1[1]; + y <= v2[1]; + y++, sx += ms, ex += me + ) for ( + x = sx >> fbits, + e = ex >> fbits; + x < e; + x++ + ) { + d = &r->d[x + y * r->w]; + if (*d > v0[2]) { + *d = v0[2]; + r->t[x + y * r->w] = c; + } + } +} + diff --git a/render.h b/render.h index 36bafe4..887cffa 100644 --- a/render.h +++ b/render.h @@ -20,14 +20,16 @@ Colour blend_mod(Colour dst, Colour src, Colour mod); typedef struct { Colour* t; + int* d; int w, h; Rect clip; } Renderer; -void ren_begin(Renderer* r, Colour* t, int w, int h); +void ren_begin(Renderer* r, Colour* t, int* d, int w, int h); void ren_end(Renderer* r); void ren_clear(Renderer* r); void ren_clearc(Renderer* r, Colour c); +void ren_cleard(Renderer* r, int depth); void ren_clip(Renderer* r, const Rect* c); void ren_point(Renderer* r, Colour c, int x, int y); void ren_char( @@ -44,5 +46,19 @@ void ren_text( int y, const char* t ); +typedef enum { + tri_mode_flat, + tri_mode_textured, + tri_mode_lit, + tri_mode_textured_lit +} Tri_Mode; +void ren_tri( + Renderer* r, + Colour c, + int* v0, + int* v1, + int* v2, + Tri_Mode mode +); #endif -- cgit v1.2.3-54-g00ecf