summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-07-27 11:15:21 +1000
committerquou <quou@disroot.org>2024-07-27 11:17:11 +1000
commit951f6115c16c3ab482c19705344295c90af1625b (patch)
treec7b140f8ba9db86955f2352d23fa9808138fad3e
parentd2c76fd62fa735f3d4fc3ceb55a75d6f0b2dc758 (diff)
clipping and viewport improvements.
-rw-r--r--3de.c13
-rw-r--r--maths.c4
-rw-r--r--rect.c44
-rw-r--r--rect.h2
-rw-r--r--render.c111
-rw-r--r--render.h10
6 files changed, 136 insertions, 48 deletions
diff --git a/3de.c b/3de.c
index eb7a8f8..e18b643 100644
--- a/3de.c
+++ b/3de.c
@@ -43,6 +43,12 @@ void draw_tri(Renderer* r, int x, int y) {
ren_tri(r, v0, v1, v2, tex);
}
+void draw_line(Renderer* r, int x, int y) {
+ int s[] = { 100, 100 };
+ int e[] = { x, y };
+ ren_line(r, make_red(), s, e);
+}
+
int entrypoint(int argc, const char** argv, Arena* a) {
App* app;
Renderer r = { 0 };
@@ -83,10 +89,12 @@ int entrypoint(int argc, const char** argv, Arena* a) {
while (app->o) {
fps_begin(&f);
while (f.now >= f.next) {
+ Rect clip = { 30, 80, 400, 800 };
app_begin(app);
update_player(&p, &s);
ren_begin(&r, app->fb, depth, app->w, app->h);
- ren_clear(&r);
+ ren_clip(&r, &clip);
+ ren_clearc(&r, make_blue());
ren_cleard(&r, f1 * 300);
sprintf(buf, "FPS: %d", app->fps);
ren_texts(&r, blue, 3, 3, buf);
@@ -94,10 +102,11 @@ int entrypoint(int argc, const char** argv, Arena* a) {
ren_texts(&r, blue, 3, 8, buf);
sprintf(buf, "MOUSE: %d, %d", app->mx, app->my);
ren_texts(&r, blue, 3, 13, buf);
+ draw_line(&r, app->mx, app->my);
push_player_cam(&p);
draw_gun(&r);
pop_player_cam();
- /*draw_tri(&r, app->mx, app->my);*/
+ draw_tri(&r, app->mx, app->my);
ren_end(&r);
app_end(app);
fps_update(&f);
diff --git a/maths.c b/maths.c
index 706c12b..70b354e 100644
--- a/maths.c
+++ b/maths.c
@@ -290,8 +290,8 @@ int* persp(int* v, int asp) {
}
int* ndc2clip(const int* c, int* p) {
- register int hw = c[2] >> 1;
- register int hh = c[3] >> 1;
+ register int hw = c[0] >> 1;
+ register int hh = c[1] >> 1;
p[0] = ((hw << fbits) * p[0]) >> fbits;
p[1] = ((hh << fbits) * -p[1]) >> fbits;
p[0] >>= fbits;
diff --git a/rect.c b/rect.c
index c72c66e..e3d3948 100644
--- a/rect.c
+++ b/rect.c
@@ -19,6 +19,24 @@ Rect* rect_clip(Rect* r, const Rect* c) {
return r;
}
+Rect* rect_clipr(Rect* r, const int* c) {
+ int n;
+ int x = r->x, y = r->y;
+ if ((n = c[0] - r->x) > 0) {
+ r->w -= n;
+ r->x += n;
+ }
+ if ((n = c[1] - r->y) > 0) {
+ r->h -= n;
+ r->y += n;
+ }
+ if ((n = x + r->w - c[2]) > 0)
+ r->w -= n;
+ if ((n = y + r->h - c[3]) > 0)
+ r->h -= n;
+ return r;
+}
+
Rect* rect_clips(Rect* r, Rect* s, const Rect* c) {
int n;
int x = r->x, y = r->y;
@@ -44,3 +62,29 @@ Rect* rect_clips(Rect* r, Rect* s, const Rect* c) {
}
return r;
}
+
+Rect* rect_clipsr(Rect* r, Rect* s, const int* c) {
+ int n;
+ int x = r->x, y = r->y;
+ if ((n = c[0] - r->x) > 0) {
+ r->w -= n;
+ r->x += n;
+ s->w -= n;
+ s->x += n;
+ }
+ if ((n = c[1] - r->y) > 0) {
+ r->h -= n;
+ r->y += n;
+ s->h -= n;
+ s->y += n;
+ }
+ if ((n = x + r->w - c[2]) > 0) {
+ r->w -= n;
+ s->w -= n;
+ }
+ if ((n = y + r->h - c[3]) > 0) {
+ r->h -= n;
+ s->h -= n;
+ }
+ return r;
+}
diff --git a/rect.h b/rect.h
index b055607..74f3084 100644
--- a/rect.h
+++ b/rect.h
@@ -6,6 +6,8 @@ typedef struct {
} Rect;
Rect* rect_clip(Rect* r, const Rect* c);
+Rect* rect_clipr(Rect* r, const int* c);
Rect* rect_clips(Rect* r, Rect* s, const Rect* c);
+Rect* rect_clipsr(Rect* r, Rect* s, const int* c);
#endif
diff --git a/render.c b/render.c
index 233c084..c8b673b 100644
--- a/render.c
+++ b/render.c
@@ -149,17 +149,13 @@ Colour col_mul(Colour a, Colour b) {
void ren_begin(Renderer* r, Colour* t, int* d, int w, int h) {
r->t = t;
- r->vp[2] = w;
- r->vp[3] = h;
+ r->vp[0] = w;
+ r->vp[1] = h;
r->d = d;
- r->clip.x = 0;
- r->clip.y = 0;
- r->clip.w = w;
- r->clip.h = h;
- r->vp[0] = 0;
- r->vp[1] = 0;
- r->vp[2] = w;
- r->vp[3] = h;
+ r->clip[0] = 0;
+ r->clip[1] = 0;
+ r->clip[2] = w;
+ r->clip[3] = h;
r->asp = (w << fbits) / h;
r->n = 256;
}
@@ -169,36 +165,49 @@ void ren_end(Renderer* r) {
}
void ren_clear(Renderer* r) {
- Colour* d = r->t, b = { 0 };
- int i = 0, e = r->vp[2] * r->vp[3];
- for (i = 0; i < e; i++, d++)
- *d = b;
+ Colour c = { 0 };
+ ren_clearc(r, c);
}
void ren_clearc(Renderer* r, Colour c) {
- Colour* d = r->t;
- int i = 0, e = r->vp[2] * r->vp[3];
- for (i = 0; i < e; i++, d++)
- *d = c;
+ Colour* d = &r->t[r->clip[0] + r->clip[1] * r->vp[0]];
+ int s = r->vp[0] - (r->clip[2] - r->clip[0]), y;
+ for (y = r->clip[1]; y < r->clip[3]; y++) {
+ int x;
+ for (x = r->clip[0]; x < r->clip[2]; x++) {
+ *d = c;
+ d++;
+ }
+ d += s;
+ }
}
void ren_cleard(Renderer* r, int depth) {
- int* d = r->d;
- int i = 0, e = r->vp[2] * r->vp[3];
- for (i = 0; i < e; i++, d++)
- *d = depth;
+ int* d = &r->d[r->clip[0] + r->clip[1] * r->vp[0]];
+ int s = r->vp[0] - (r->clip[2] - r->clip[0]), y;
+ for (y = r->clip[1]; y < r->clip[3]; y++) {
+ int x;
+ for (x = r->clip[0]; x < r->clip[2]; x++) {
+ *d = depth;
+ d++;
+ }
+ d += s;
+ }
}
void ren_clip(Renderer* r, const Rect* c) {
- r->clip = *c;
+ r->clip[0] = c->x;
+ r->clip[1] = c->y;
+ r->clip[2] = c->x + c->w;
+ r->clip[3] = c->y + c->h;
}
void ren_point(Renderer* r, Colour c, int x, int y) {
- if (x < 0) return;
- if (y < 0) return;
- if (x >= r->vp[2]) return;
- if (y >= r->vp[3]) return;
- r->t[x + y * r->vp[2]] = c;
+ if (x < r->clip[0]) return;
+ if (y < r->clip[1]) return;
+ if (x >= r->clip[2]) return;
+ if (y >= r->clip[3]) return;
+ r->t[x + y * r->vp[0]] = c;
}
#define imp_ren_char(chw, chh, fw, data) \
@@ -209,11 +218,11 @@ void ren_point(Renderer* r, Colour c, int x, int y) {
re.x = x; \
re.y = y; \
sub.x = (ch - ' ') * chw; \
- rect_clips(&re, &sub, &r->clip); \
+ rect_clipsr(&re, &sub, r->clip); \
ex = re.x + re.w; \
ey = re.y + re.h; \
- dst = r->t + (re.x + re.y * r->vp[2]); \
- s = r->vp[2] - re.w; \
+ dst = r->t + (re.x + re.y * r->vp[0]); \
+ s = r->vp[0] - re.w; \
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 * fw; \
@@ -416,6 +425,24 @@ void step_line(
}
}
+void ren_line(
+ Renderer* r,
+ Colour c,
+ const int* s,
+ const int* e
+) {
+ Line l;
+ init_line(&l, s, e);
+ while (l.x != e[0] && l.y != e[1]) {
+ Colour* dst = &r->t[l.x + l.y * r->vp[0]];
+ if (l.x < r->clip[0] || l.y < r->clip[1]) goto step;
+ if (l.x >= r->clip[2] || l.y >= r->clip[3]) goto step;
+ *dst = blend(*dst, c);
+step:
+ step_line(&l);
+ }
+}
+
void ren_tri(
Renderer* r,
const int* iv0,
@@ -426,8 +453,8 @@ void ren_tri(
#define ic 6
#define ec 8
int ha, i;
- const int fcx = r->clip.x + r->clip.w;
- const int fcy = r->clip.y + r->clip.h;
+ const int fcx = r->clip[2];
+ const int fcy = r->clip[3];
int v0[ec], v1[ec], v2[ec];
Line ne, fe; /* near and far edges */
Line ni[ic], fi[ic]; /* near and far interpolants */
@@ -478,7 +505,7 @@ void ren_tri(
if (v1[1] > fcy) v1[1] = fcy;
#define scanline\
int x, ex = mini(fe.x, fcx);\
- if (fe.y >= r->clip.y) { \
+ if (fe.y >= r->clip[1]) { \
for (i = 0; i < ic; i++)\
init_lerp(\
&xi[i],\
@@ -487,17 +514,17 @@ void ren_tri(
);\
for (x = ne.x; x < ex; x++) {\
Colour col;\
- if (x >= r->clip.x) { \
+ if (x >= r->clip[0]) { \
col.r = (xi[3].x * 255) >> fbits;\
col.g = (xi[4].x * 255) >> fbits;\
col.b = (xi[5].x * 255) >> fbits;\
col.a = 0xff;\
- if (xi[0].x < r->d[x + fe.y * r->vp[2]]) { \
- r->t[x + fe.y * r->vp[2]] = col_mul(\
+ if (xi[0].x < r->d[x + fe.y * r->vp[0]]) { \
+ r->t[x + fe.y * r->vp[0]] = col_mul(\
sample_tex(tex, xi[1].x, xi[2].x),\
col\
);\
- r->d[x + fe.y * r->vp[2]] = xi[0].x; \
+ r->d[x + fe.y * r->vp[0]] = xi[0].x; \
} \
} \
for (i = 0; i < ic; i++)\
@@ -605,10 +632,10 @@ int point_os(
int y
) {
return
- x >= r->vp[0] &&
- y >= r->vp[1] &&
- x < r->vp[2] &&
- y < r->vp[3];
+ x >= r->clip[0] &&
+ y >= r->clip[1] &&
+ x < r->clip[2] &&
+ y < r->clip[3];
}
void ren_mesh(
diff --git a/render.h b/render.h
index 996ba37..2299a30 100644
--- a/render.h
+++ b/render.h
@@ -42,8 +42,8 @@ typedef struct {
Colour* t;
int* d;
int asp, n;
- int vp[4];
- Rect clip;
+ int vp[2];
+ int clip[4];
} Renderer;
int tri_os(
@@ -95,6 +95,12 @@ void ren_texts(
int y,
const char* t
);
+void ren_line(
+ Renderer* r,
+ Colour c,
+ const int* s,
+ const int* e
+);
/* Vertex format:
* x y z u v r g b
* All fixed point values with 9 bits of precision.