diff options
author | quou <quou@disroot.org> | 2024-07-27 11:15:21 +1000 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-07-27 11:17:11 +1000 |
commit | 951f6115c16c3ab482c19705344295c90af1625b (patch) | |
tree | c7b140f8ba9db86955f2352d23fa9808138fad3e /render.c | |
parent | d2c76fd62fa735f3d4fc3ceb55a75d6f0b2dc758 (diff) |
clipping and viewport improvements.
Diffstat (limited to 'render.c')
-rw-r--r-- | render.c | 111 |
1 files changed, 69 insertions, 42 deletions
@@ -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( |