mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-20 19:21:46 +00:00
TINYGL: Refactored line drawing routines.
This commit is contained in:
parent
2d6940923a
commit
4555f10cd8
@ -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;
|
||||
|
@ -71,6 +71,9 @@ struct FrameBuffer {
|
||||
template <bool interpRGB, bool interpZ, bool interpST, bool interpSTZ, int drawLogic>
|
||||
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
|
||||
template <bool interpRGB, bool interpZ>
|
||||
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);
|
||||
|
@ -5,38 +5,147 @@ namespace TinyGL {
|
||||
|
||||
#define ZCMP(z,zpix) ((z) >= (zpix))
|
||||
|
||||
template <bool interpRGB, bool interpZ>
|
||||
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 <bool interpRGB, bool interpZ>
|
||||
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<interpRGB,interpZ>(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 <bool interpRGB, bool interpZ>
|
||||
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<interpRGB,interpZ>(pp, cmode, pz, z, color, r, g, b);
|
||||
} else if (dx > 0) {
|
||||
if (dx >= dy) {
|
||||
drawLine<interpRGB,interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, 1);
|
||||
} else {
|
||||
drawLine<interpRGB,interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, sx);
|
||||
}
|
||||
} else {
|
||||
dx = -dx;
|
||||
if (dx >= dy) {
|
||||
drawLine<interpRGB,interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, -1);
|
||||
} else {
|
||||
drawLine<interpRGB,interpZ>(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<false,true>(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<true, true>(p1, p2, 0);
|
||||
}
|
||||
|
||||
// no Z interpolation
|
||||
void FrameBuffer::fillLineFlat(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
||||
#include "graphics/tinygl/zline.h"
|
||||
fillLine<false, true>(p1, p2, color);
|
||||
}
|
||||
|
||||
#define INTERP_RGB
|
||||
void FrameBuffer::fillLineInterp(ZBufferPoint *p1, ZBufferPoint *p2) {
|
||||
#include "graphics/tinygl/zline.h"
|
||||
fillLine<true, false>(p1, p2, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::fillLineZ(ZBufferPoint *p1, ZBufferPoint *p2) {
|
||||
|
@ -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 <bool interpRGB, bool interpZ, bool interpST, bool interpSTZ, int drawLogic>
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user