summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--3de.c39
-rw-r--r--config.h4
-rw-r--r--maths.c1
-rw-r--r--render.c133
-rw-r--r--render.h18
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