From 4555f10cd8287cb0371a1515ce3c6ceae34b92c0 Mon Sep 17 00:00:00 2001 From: Stefano Musumeci Date: Tue, 17 Jun 2014 17:00:20 +0200 Subject: [PATCH] TINYGL: Refactored line drawing routines. --- graphics/tinygl/zbuffer.cpp | 10 +-- graphics/tinygl/zbuffer.h | 3 + graphics/tinygl/zline.cpp | 131 +++++++++++++++++++++++++++++++--- graphics/tinygl/ztriangle.cpp | 71 +++++++++--------- 4 files changed, 160 insertions(+), 55 deletions(-) diff --git a/graphics/tinygl/zbuffer.cpp b/graphics/tinygl/zbuffer.cpp index a270caf1213..88806c18881 100644 --- a/graphics/tinygl/zbuffer.cpp +++ b/graphics/tinygl/zbuffer.cpp @@ -57,11 +57,11 @@ void memset_l(void *adr, int val, int count) { *p++ = val; } -FrameBuffer::FrameBuffer(int xsize, int ysize, const Graphics::PixelBuffer &frame_buffer) { +FrameBuffer::FrameBuffer(int width, int height, const Graphics::PixelBuffer &frame_buffer) { int size; - this->xsize = xsize; - this->ysize = ysize; + this->xsize = width; + this->ysize = height; this->cmode = frame_buffer.getFormat(); PSZB = this->pixelbytes = this->cmode.bytesPerPixel; this->pixelbits = this->cmode.bytesPerPixel * 8; @@ -72,8 +72,8 @@ FrameBuffer::FrameBuffer(int xsize, int ysize, const Graphics::PixelBuffer &fram this->zbuf = (unsigned int *)gl_malloc(size); if (!frame_buffer) { - byte *pbuf = (byte *)gl_malloc(this->ysize * this->linesize); - this->pbuf.set(this->cmode, pbuf); + byte *pixelBuffer = (byte *)gl_malloc(this->ysize * this->linesize); + this->pbuf.set(this->cmode, pixelBuffer); this->frame_buffer_allocated = 1; } else { this->frame_buffer_allocated = 0; diff --git a/graphics/tinygl/zbuffer.h b/graphics/tinygl/zbuffer.h index ce7362563ed..275113cb6e6 100644 --- a/graphics/tinygl/zbuffer.h +++ b/graphics/tinygl/zbuffer.h @@ -71,6 +71,9 @@ struct FrameBuffer { template void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); + template + void fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color); + void fillTriangleMappingPerspective(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); void fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); void fillTriangleFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); diff --git a/graphics/tinygl/zline.cpp b/graphics/tinygl/zline.cpp index 85e30a06518..9e08010df2c 100644 --- a/graphics/tinygl/zline.cpp +++ b/graphics/tinygl/zline.cpp @@ -5,38 +5,147 @@ namespace TinyGL { #define ZCMP(z,zpix) ((z) >= (zpix)) +template +FORCEINLINE static void putPixel(PIXEL *pp, const Graphics::PixelFormat &cmode, unsigned int *pz, unsigned int &z, int &color, unsigned int &r, unsigned int &g, unsigned int &b) { + if (interpZ) { + if (ZCMP(z,*pz)) { + if (interpRGB) { + *pp = RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8); + } + else { + *pp = color; + } + *pz = z; + } + } + else { + if (interpRGB) { + *pp = RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8); + } + else { + *pp = color; + } + } +} + +template +FORCEINLINE static void drawLine(ZBufferPoint *p1, ZBufferPoint *p2, PIXEL *pp, const Graphics::PixelFormat &cmode, unsigned int *pz, unsigned int &z, int &color, unsigned int &r, unsigned int &g, unsigned int &b, int dx, int dy, int inc_1, int inc_2) { + int n = dx; + int rinc, ginc, binc; + int zinc; + if (interpZ) { + zinc = (p2->z - p1->z) / n; + } + if (interpRGB) { + rinc = ((p2->r - p1->r) << 8) / n; + ginc = ((p2->g - p1->g) << 8) / n; + binc = ((p2->b - p1->b) << 8) / n; + } + int a = 2 * dy - dx; + dy = 2 * dy; + dx = 2 * dx - dy; + int pp_inc_1 = (inc_1) * PSZB; + int pp_inc_2 = (inc_2) * PSZB; + do { + putPixel(pp, cmode, pz, z, color, r, g, b); + if (interpZ) { + z += zinc; + } + if (interpRGB) { + r += rinc; + g += ginc; + b += binc; + } + if (a > 0) { + pp = (PIXEL *)((char *)pp + pp_inc_1); + if (interpZ) { + pz += inc_1; + } + a -= dx; + } else { + pp = (PIXEL *)((char *)pp + pp_inc_2); + if (interpZ) { + pz += inc_2; + } + a += dy; + } + } while (--n >= 0); +} + +template +void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) { + int dx, dy, sx; + PIXEL *pp; + unsigned int r, g, b; + unsigned int *pz = NULL; + unsigned int z; + + if (p1->y > p2->y || (p1->y == p2->y && p1->x > p2->x)) { + ZBufferPoint *tmp; + tmp = p1; + p1 = p2; + p2 = tmp; + } + sx = xsize; + pp = (PIXEL *)((char *) pbuf.getRawBuffer() + linesize * p1->y + p1->x * PSZB); + if (interpZ) { + pz = zbuf + (p1->y * sx + p1->x); + z = p1->z; + } + dx = p2->x - p1->x; + dy = p2->y - p1->y; + if (interpRGB) { + r = p2->r << 8; + g = p2->g << 8; + b = p2->b << 8; + } + + if (dx == 0 && dy == 0) { + putPixel(pp, cmode, pz, z, color, r, g, b); + } else if (dx > 0) { + if (dx >= dy) { + drawLine(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, 1); + } else { + drawLine(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + drawLine(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, -1); + } else { + drawLine(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, sx); + } + } +} + void FrameBuffer::plot(ZBufferPoint *p) { unsigned int *pz; PIXEL *pp; pz = zbuf + (p->y * xsize + p->x); pp = (PIXEL *)((char *) pbuf.getRawBuffer() + linesize * p->y + p->x * PSZB); - if (ZCMP((unsigned int)p->z, *pz)) { - *pp = RGB_TO_PIXEL(p->r, p->g, p->b); - *pz = p->z; - } + unsigned int r, g, b; + int col = RGB_TO_PIXEL(p->r, p->g, p->b); + unsigned int z = p->z; + putPixel(pp, cmode, pz, z, col, r, g, b); } -#define INTERP_Z void FrameBuffer::fillLineFlatZ(ZBufferPoint *p1, ZBufferPoint *p2, int color) { #include "graphics/tinygl/zline.h" } // line with color interpolation -#define INTERP_Z -#define INTERP_RGB void FrameBuffer::fillLineInterpZ(ZBufferPoint *p1, ZBufferPoint *p2) { -#include "graphics/tinygl/zline.h" + fillLine(p1, p2, 0); } // no Z interpolation void FrameBuffer::fillLineFlat(ZBufferPoint *p1, ZBufferPoint *p2, int color) { -#include "graphics/tinygl/zline.h" + fillLine(p1, p2, color); } -#define INTERP_RGB void FrameBuffer::fillLineInterp(ZBufferPoint *p1, ZBufferPoint *p2) { -#include "graphics/tinygl/zline.h" + fillLine(p1, p2, 0); } void FrameBuffer::fillLineZ(ZBufferPoint *p1, ZBufferPoint *p2) { diff --git a/graphics/tinygl/ztriangle.cpp b/graphics/tinygl/ztriangle.cpp index 182ee461cb9..21c7d1b6a4d 100644 --- a/graphics/tinygl/ztriangle.cpp +++ b/graphics/tinygl/ztriangle.cpp @@ -18,7 +18,8 @@ static const int NB_INTERP = 8; #define SAR_RND_TO_ZERO(v,n) (v / (1 << n)) -FORCEINLINE static void putPixelMapping(PIXEL *pp, unsigned int *pz, Graphics::PixelBuffer &texture, int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &dzdx, int &dsdx, int &dtdx) { +FORCEINLINE static void putPixelMapping(PIXEL *pp, unsigned int *pz, Graphics::PixelBuffer &texture, + int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &dzdx, int &dsdx, int &dtdx) { if (ZCMP(z, pz[_a])) { pp[_a] = texture.getRawBuffer()[((t & 0x3FC00000) | s) >> 14]; pz[_a] = z; @@ -28,7 +29,8 @@ FORCEINLINE static void putPixelMapping(PIXEL *pp, unsigned int *pz, Graphics::P t += dtdx; } -FORCEINLINE static void putPixelFlat(PIXEL *pp, unsigned int *pz, int _a, unsigned int &z, int color, int &dzdx) { +FORCEINLINE static void putPixelFlat(PIXEL *pp, unsigned int *pz, int _a, unsigned int &z, + int color, int &dzdx) { if (ZCMP(z, pz[_a])) { pp[_a] = color; pz[_a] = z; @@ -43,7 +45,8 @@ FORCEINLINE static void putPixelDepth(unsigned int *pz, int _a, unsigned int &z, z += dzdx; } -FORCEINLINE static void putPixelSmooth(Graphics::PixelBuffer &buf, unsigned int *pz, int _a, unsigned int &z, int &tmp, unsigned int &rgb, int &dzdx, unsigned int &drgbdx) { +FORCEINLINE static void putPixelSmooth(Graphics::PixelBuffer &buf, unsigned int *pz, int _a, + unsigned int &z, int &tmp, unsigned int &rgb, int &dzdx, unsigned int &drgbdx) { if (ZCMP(z, pz[_a])) { tmp = rgb & 0xF81F07E0; buf.setPixelAt(_a, tmp | (tmp >> 16)); @@ -53,7 +56,10 @@ FORCEINLINE static void putPixelSmooth(Graphics::PixelBuffer &buf, unsigned int rgb = (rgb + drgbdx) & (~0x00200800); } -FORCEINLINE static void putPixelMappingPerspective(Graphics::PixelBuffer &buf, Graphics::PixelFormat &textureFormat, Graphics::PixelBuffer &texture, unsigned int *pz, int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &tmp, unsigned int &rgb, int &dzdx, int &dsdx, int &dtdx, unsigned int &drgbdx) { +FORCEINLINE static void putPixelMappingPerspective(Graphics::PixelBuffer &buf, + Graphics::PixelFormat &textureFormat, Graphics::PixelBuffer &texture, unsigned int *pz, + int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &tmp, unsigned int &rgb, + int &dzdx, int &dsdx, int &dtdx, unsigned int &drgbdx) { if (ZCMP(z, pz[_a])) { unsigned ttt = (t & 0x003FC000) >> (9 - PSZSH); unsigned sss = (s & 0x003FC000) >> (17 - PSZSH); @@ -87,15 +93,15 @@ FORCEINLINE static void putPixelMappingPerspective(Graphics::PixelBuffer &buf, G template void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) { Graphics::PixelBuffer texture; - float fdzdx, fndzdx, ndszdx, ndtzdx; - int _drgbdx; + float fdzdx = 0, fndzdx = 0, ndszdx = 0, ndtzdx = 0; + int _drgbdx = 0; ZBufferPoint *tp, *pr1 = 0, *pr2 = 0, *l1 = 0, *l2 = 0; float fdx1, fdx2, fdy1, fdy2, fz0, d1, d2; - unsigned int *pz1; - unsigned char *pm1; + unsigned int *pz1 = NULL; + unsigned char *pm1 = NULL; int part, update_left, update_right; - int color; + int color = 0; int nb_lines, dx1, dy1, tmp, dx2, dy2; @@ -361,32 +367,21 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint { switch (drawLogic) { case DRAW_DEPTH_ONLY: { - register PIXEL *pp; - register int n; - register unsigned int *pz; - register unsigned int z; - register unsigned int or1, og1, ob1; - register unsigned int s, t; - float sz, tz; + PIXEL *pp; + int n; + unsigned int *pz; + unsigned int z; + unsigned int s, t; n = (x2 >> 16) - x1; pp = (PIXEL *)((char *)pp1 + x1 * PSZB); if (interpZ) { pz = pz1 + x1; z = z1; } - if (interpRGB) { - or1 = r1; - og1 = g1; - ob1 = b1; - } if (interpST) { s = s1; t = t1; } - if (interpSTZ) { - sz = sz1; - tz = tz1; - } while (n >= 3) { if (drawLogic == DRAW_DEPTH_ONLY) { putPixelDepth(pz,0,z,dzdx); @@ -431,8 +426,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint } break; case DRAW_SHADOW_MASK: { - register unsigned char *pm; - register int n; + unsigned char *pm; + int n; n = (x2 >> 16) - x1; pm = pm1 + x1; @@ -451,10 +446,10 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint } break; case DRAW_SHADOW: { - register unsigned char *pm; - register int n; - register unsigned int *pz; - register unsigned int z; + unsigned char *pm; + int n; + unsigned int *pz; + unsigned int z; n = (x2 >> 16) - x1; @@ -490,10 +485,10 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint } break; case DRAW_SMOOTH: { - register unsigned int *pz; + unsigned int *pz; Graphics::PixelBuffer buf = pbuf; - register unsigned int z, rgb, drgbdx; - register int n; + unsigned int z, rgb, drgbdx; + int n; n = (x2 >> 16) - x1; int bpp = buf.getFormat().bytesPerPixel; buf = (byte *)pp1 + x1 * bpp; @@ -521,9 +516,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint } break; case DRAW_MAPPING_PERSPECTIVE: { - register unsigned int *pz; - register unsigned int s, t, z, rgb, drgbdx; - register int n, dsdx, dtdx; + unsigned int *pz; + unsigned int s, t, z, rgb, drgbdx; + int n; float sz, tz, fz, zinv; n = (x2 >> 16) - x1; fz = (float)z1; @@ -572,8 +567,6 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint dtdx = (int)((dtzdx - tt * fdzdx) * zinv); } - int bytePerPixel = texture.getFormat().bytesPerPixel; - while (n >= 0) { putPixelMappingPerspective(buf, textureFormat, texture, pz, 0, z, t, s, tmp, rgb, dzdx, dsdx, dtdx, drgbdx); pz += 1;