summaryrefslogtreecommitdiff
path: root/render.c
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-07-06 17:55:46 +1000
committerquou <quou@disroot.org>2024-07-06 17:56:54 +1000
commite6f8a3356a91e0304e9965c7b8bfc2f06a2b79cc (patch)
treefa9d44cdc1b007c834bd2c8cfd6e19d175829b4d /render.c
parent8706ad19a8b29073afeece115092f03cbbf369c4 (diff)
Triangle fill.
Diffstat (limited to 'render.c')
-rw-r--r--render.c133
1 files changed, 130 insertions, 3 deletions
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;
+ }
+ }
+}
+