TINYGL: Encapsulated pixel access in FrameBuffer class, provided an implementation of glBlendFunc.
This commit is contained in:
parent
10c25d49d4
commit
03072c4b7b
5 changed files with 286 additions and 85 deletions
|
@ -63,6 +63,7 @@ void glopEnableDisable(GLContext *c, GLParam *p) {
|
||||||
break;
|
break;
|
||||||
case TGL_BLEND:
|
case TGL_BLEND:
|
||||||
c->enable_blend = v;
|
c->enable_blend = v;
|
||||||
|
c->fb->enableBlending(v);
|
||||||
break;
|
break;
|
||||||
case TGL_POLYGON_OFFSET_FILL:
|
case TGL_POLYGON_OFFSET_FILL:
|
||||||
if (v)
|
if (v)
|
||||||
|
@ -105,6 +106,9 @@ void glopEnableDisable(GLContext *c, GLParam *p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void glopBlendFunc(GLContext *c, GLParam *p) {
|
void glopBlendFunc(GLContext *c, GLParam *p) {
|
||||||
|
TGLenum sfactor = p[1].i;
|
||||||
|
TGLenum dfactor = p[2].i;
|
||||||
|
c->fb->setBlendingFactors(sfactor,dfactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glopShadeModel(GLContext *c, GLParam *p) {
|
void glopShadeModel(GLContext *c, GLParam *p) {
|
||||||
|
|
|
@ -85,6 +85,7 @@ FrameBuffer::FrameBuffer(int width, int height, const Graphics::PixelBuffer &fra
|
||||||
|
|
||||||
this->buffer.pbuf = this->pbuf.getRawBuffer();
|
this->buffer.pbuf = this->pbuf.getRawBuffer();
|
||||||
this->buffer.zbuf = this->zbuf;
|
this->buffer.zbuf = this->zbuf;
|
||||||
|
_blendingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::~FrameBuffer() {
|
FrameBuffer::~FrameBuffer() {
|
||||||
|
@ -161,4 +162,13 @@ void FrameBuffer::setTexture(const Graphics::PixelBuffer &texture) {
|
||||||
current_texture = texture;
|
current_texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FrameBuffer::setBlendingFactors( int sfactor, int dfactor ) {
|
||||||
|
_sourceBlendingFactor = sfactor;
|
||||||
|
_destinationBlendingFactor = dfactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameBuffer::enableBlending(bool enableBlending) {
|
||||||
|
_blendingEnabled = enableBlending;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace TinyGL
|
} // end of namespace TinyGL
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define GRAPHICS_TINYGL_ZBUFFER_H_
|
#define GRAPHICS_TINYGL_ZBUFFER_H_
|
||||||
|
|
||||||
#include "graphics/pixelbuffer.h"
|
#include "graphics/pixelbuffer.h"
|
||||||
|
#include "graphics/tinygl/gl.h"
|
||||||
|
|
||||||
namespace TinyGL {
|
namespace TinyGL {
|
||||||
|
|
||||||
|
@ -55,8 +56,203 @@ struct FrameBuffer {
|
||||||
void delOffscreenBuffer(Buffer *buffer);
|
void delOffscreenBuffer(Buffer *buffer);
|
||||||
void clear(int clear_z, int z, int clear_color, int r, int g, int b);
|
void clear(int clear_z, int z, int clear_color, int r, int g, int b);
|
||||||
|
|
||||||
void writePixel(int pixel, int value);
|
FORCEINLINE void writePixel(int pixel, int value) {
|
||||||
void writePixel(int pixel, byte r, byte g, byte b);
|
if (_blendingEnabled == false) {
|
||||||
|
this->pbuf.setPixelAt(pixel,value);
|
||||||
|
} else {
|
||||||
|
byte rSrc, gSrc, bSrc, aSrc;
|
||||||
|
byte rDst, gDst, bDst, aDst;
|
||||||
|
this->pbuf.getFormat().colorToARGB(value, aDst, rDst, gDst, bDst);
|
||||||
|
switch (_sourceBlendingFactor) {
|
||||||
|
case TGL_ZERO:
|
||||||
|
rSrc = gSrc = bSrc = 0;
|
||||||
|
break;
|
||||||
|
case TGL_ONE:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
break;
|
||||||
|
case TGL_DST_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * rDst) >> 8;
|
||||||
|
gSrc = (gSrc * gDst) >> 8;
|
||||||
|
bSrc = (bSrc * bDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * (255 - rDst)) >> 8;
|
||||||
|
gSrc = (gSrc * (255 - gDst)) >> 8;
|
||||||
|
bSrc = (bSrc * (255 - bDst)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * aSrc) >> 8;
|
||||||
|
gSrc = (gSrc * aSrc) >> 8;
|
||||||
|
bSrc = (bSrc * aSrc) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * (255 - aSrc)) >> 8;
|
||||||
|
gSrc = (gSrc * (255 - aSrc)) >> 8;
|
||||||
|
bSrc = (bSrc * (255 - aSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_DST_ALPHA:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * aDst) >> 8;
|
||||||
|
gSrc = (gSrc * aDst) >> 8;
|
||||||
|
bSrc = (bSrc * aDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_ALPHA:
|
||||||
|
rSrc = (rSrc * (1 - aDst)) >> 8;
|
||||||
|
gSrc = (gSrc * (1 - aDst)) >> 8;
|
||||||
|
bSrc = (bSrc * (1 - aDst)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA_SATURATE: {
|
||||||
|
int factor = aDst < 1 - aSrc ? aDst : 1 - aSrc;
|
||||||
|
rSrc = (rSrc * factor) >> 8;
|
||||||
|
gSrc = (gSrc * factor) >> 8;
|
||||||
|
bSrc = (bSrc * factor) >> 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (_destinationBlendingFactor) {
|
||||||
|
case TGL_ZERO:
|
||||||
|
rDst = gDst = bDst = 0;
|
||||||
|
break;
|
||||||
|
case TGL_ONE:
|
||||||
|
break;
|
||||||
|
case TGL_SRC_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rSrc * rDst) >> 8;
|
||||||
|
gDst = (gSrc * gDst) >> 8;
|
||||||
|
bDst = (bSrc * bDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * (255 - rSrc)) >> 8;
|
||||||
|
gDst = (gDst * (255 - gSrc)) >> 8;
|
||||||
|
bDst = (bDst * (255 - bSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * aSrc) >> 8;
|
||||||
|
gDst = (gDst * aSrc) >> 8;
|
||||||
|
bDst = (bDst * aSrc) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * (255 - aSrc)) >> 8;
|
||||||
|
gDst = (gDst * (255 - aSrc)) >> 8;
|
||||||
|
bDst = (bDst * (255 - aSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_DST_ALPHA:
|
||||||
|
rDst = (rDst * aDst) >> 8;
|
||||||
|
gDst = (gDst * aDst) >> 8;
|
||||||
|
bDst = (bDst * aDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_ALPHA:
|
||||||
|
rDst = (rDst * (255 - aDst)) >> 8;
|
||||||
|
gDst = (gDst * (255 - aDst)) >> 8;
|
||||||
|
bDst = (bDst * (255 - aDst)) >> 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->pbuf.setPixelAt(pixel,255,rSrc + rDst,gSrc + gDst,bSrc + bDst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE void writePixel(int pixel, byte rDst, byte gDst, byte bDst) {
|
||||||
|
if (_blendingEnabled == false) {
|
||||||
|
this->pbuf.setPixelAt(pixel,255,rDst,gDst,bDst);
|
||||||
|
} else {
|
||||||
|
byte rSrc, gSrc, bSrc, aSrc;
|
||||||
|
switch (_sourceBlendingFactor) {
|
||||||
|
case TGL_ZERO:
|
||||||
|
rSrc = gSrc = bSrc = 0;
|
||||||
|
break;
|
||||||
|
case TGL_ONE:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
break;
|
||||||
|
case TGL_DST_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * rDst) >> 8;
|
||||||
|
gSrc = (gSrc * gDst) >> 8;
|
||||||
|
bSrc = (bSrc * bDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * (255 - rDst)) >> 8;
|
||||||
|
gSrc = (gSrc * (255 - gDst)) >> 8;
|
||||||
|
bSrc = (bSrc * (255 - bDst)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * aSrc) >> 8;
|
||||||
|
gSrc = (gSrc * aSrc) >> 8;
|
||||||
|
bSrc = (bSrc * aSrc) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rSrc = (rSrc * (255 - aSrc)) >> 8;
|
||||||
|
gSrc = (gSrc * (255 - aSrc)) >> 8;
|
||||||
|
bSrc = (bSrc * (255 - aSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_DST_ALPHA:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_ALPHA:
|
||||||
|
rSrc = gSrc = bSrc = 0;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA_SATURATE: // Still not sure
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (_destinationBlendingFactor) {
|
||||||
|
case TGL_ZERO:
|
||||||
|
rDst = gDst = bDst = 0;
|
||||||
|
break;
|
||||||
|
case TGL_ONE:
|
||||||
|
break;
|
||||||
|
case TGL_SRC_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rSrc * rDst) >> 8;
|
||||||
|
gDst = (gSrc * gDst) >> 8;
|
||||||
|
bDst = (bSrc * bDst) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_COLOR:
|
||||||
|
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * (255 - rSrc)) >> 8;
|
||||||
|
gDst = (gDst * (255 - gSrc)) >> 8;
|
||||||
|
bDst = (bDst * (255 - bSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * aSrc) >> 8;
|
||||||
|
gDst = (gDst * aSrc) >> 8;
|
||||||
|
bDst = (bDst * aSrc) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||||
|
rDst = (rDst * (255 - aSrc)) >> 8;
|
||||||
|
gDst = (gDst * (255 - aSrc)) >> 8;
|
||||||
|
bDst = (bDst * (255 - aSrc)) >> 8;
|
||||||
|
break;
|
||||||
|
case TGL_DST_ALPHA:
|
||||||
|
break;
|
||||||
|
case TGL_ONE_MINUS_DST_ALPHA:
|
||||||
|
rDst = gDst = bDst = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->pbuf.setPixelAt(pixel,255,rSrc + rDst,gSrc + gDst,bSrc + bDst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableBlending(bool enableBlending);
|
||||||
|
void setBlendingFactors(int sfactor, int dfactor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blit the buffer to the screen buffer, checking the depth of the pixels.
|
* Blit the buffer to the screen buffer, checking the depth of the pixels.
|
||||||
|
@ -109,6 +305,10 @@ struct FrameBuffer {
|
||||||
int *ctable;
|
int *ctable;
|
||||||
Graphics::PixelBuffer current_texture;
|
Graphics::PixelBuffer current_texture;
|
||||||
Graphics::PixelBuffer pbuf;
|
Graphics::PixelBuffer pbuf;
|
||||||
|
private:
|
||||||
|
bool _blendingEnabled;
|
||||||
|
int _sourceBlendingFactor;
|
||||||
|
int _destinationBlendingFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// memory.c
|
// memory.c
|
||||||
|
|
|
@ -6,32 +6,30 @@ namespace TinyGL {
|
||||||
#define ZCMP(z,zpix) ((z) >= (zpix))
|
#define ZCMP(z,zpix) ((z) >= (zpix))
|
||||||
|
|
||||||
template <bool interpRGB, bool interpZ>
|
template <bool interpRGB, bool interpZ>
|
||||||
FORCEINLINE static void putPixel(PIXEL *pp, const Graphics::PixelFormat &cmode, unsigned int *pz,
|
FORCEINLINE static void putPixel(FrameBuffer *buffer, int pixelOffset, const Graphics::PixelFormat &cmode, unsigned int *pz, unsigned int &z, int &color, unsigned int &r, unsigned int &g, unsigned int &b) {
|
||||||
unsigned int &z, int &color, unsigned int &r, unsigned int &g, unsigned int &b) {
|
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
if (ZCMP(z, *pz)) {
|
if (ZCMP(z, *pz)) {
|
||||||
if (interpRGB) {
|
if (interpRGB) {
|
||||||
*pp = RGB_TO_PIXEL(r >> 8, g >> 8, b >> 8);
|
buffer->writePixel(pixelOffset,RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*pp = color;
|
buffer->writePixel(pixelOffset,color);
|
||||||
}
|
}
|
||||||
*pz = z;
|
*pz = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (interpRGB) {
|
if (interpRGB) {
|
||||||
*pp = RGB_TO_PIXEL(r >> 8, g >> 8, b >> 8);
|
buffer->writePixel(pixelOffset,RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*pp = color;
|
buffer->writePixel(pixelOffset,color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool interpRGB, bool interpZ> FORCEINLINE static void drawLine(ZBufferPoint *p1, ZBufferPoint *p2, PIXEL *pp,
|
template <bool interpRGB, bool interpZ>
|
||||||
const Graphics::PixelFormat &cmode, unsigned int *pz, unsigned int &z, int &color,
|
FORCEINLINE static void drawLine(FrameBuffer *buffer, ZBufferPoint *p1, ZBufferPoint *p2, int &pixelOffset, 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) {
|
||||||
unsigned int &r, unsigned int &g, unsigned int &b, int dx, int dy, int inc_1, int inc_2) {
|
|
||||||
int n = dx;
|
int n = dx;
|
||||||
int rinc, ginc, binc;
|
int rinc, ginc, binc;
|
||||||
int zinc;
|
int zinc;
|
||||||
|
@ -46,10 +44,10 @@ template <bool interpRGB, bool interpZ> FORCEINLINE static void drawLine(ZBuffer
|
||||||
int a = 2 * dy - dx;
|
int a = 2 * dy - dx;
|
||||||
dy = 2 * dy;
|
dy = 2 * dy;
|
||||||
dx = 2 * dx - dy;
|
dx = 2 * dx - dy;
|
||||||
int pp_inc_1 = (inc_1) * PSZB;
|
int pp_inc_1 = (inc_1);
|
||||||
int pp_inc_2 = (inc_2) * PSZB;
|
int pp_inc_2 = (inc_2);
|
||||||
do {
|
do {
|
||||||
putPixel<interpRGB, interpZ>(pp, cmode, pz, z, color, r, g, b);
|
putPixel<interpRGB,interpZ>(buffer, pixelOffset, cmode, pz, z, color, r, g, b);
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
z += zinc;
|
z += zinc;
|
||||||
}
|
}
|
||||||
|
@ -59,13 +57,13 @@ template <bool interpRGB, bool interpZ> FORCEINLINE static void drawLine(ZBuffer
|
||||||
b += binc;
|
b += binc;
|
||||||
}
|
}
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
pp = (PIXEL *)((char *)pp + pp_inc_1);
|
pixelOffset += pp_inc_1;
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz += inc_1;
|
pz += inc_1;
|
||||||
}
|
}
|
||||||
a -= dx;
|
a -= dx;
|
||||||
} else {
|
} else {
|
||||||
pp = (PIXEL *)((char *)pp + pp_inc_2);
|
pixelOffset += pp_inc_2;
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz += inc_2;
|
pz += inc_2;
|
||||||
}
|
}
|
||||||
|
@ -74,12 +72,13 @@ template <bool interpRGB, bool interpZ> FORCEINLINE static void drawLine(ZBuffer
|
||||||
} while (--n >= 0);
|
} while (--n >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool interpRGB, bool interpZ> void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
template <bool interpRGB, bool interpZ>
|
||||||
int dx, dy, sx;
|
void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
||||||
PIXEL *pp;
|
int dx, dy, sx, pp;
|
||||||
unsigned int r, g, b;
|
unsigned int r, g, b;
|
||||||
unsigned int *pz = NULL;
|
unsigned int *pz = NULL;
|
||||||
unsigned int z;
|
unsigned int z;
|
||||||
|
int pixelOffset;
|
||||||
|
|
||||||
if (p1->y > p2->y || (p1->y == p2->y && p1->x > p2->x)) {
|
if (p1->y > p2->y || (p1->y == p2->y && p1->x > p2->x)) {
|
||||||
ZBufferPoint *tmp;
|
ZBufferPoint *tmp;
|
||||||
|
@ -88,7 +87,7 @@ template <bool interpRGB, bool interpZ> void FrameBuffer::fillLine(ZBufferPoint
|
||||||
p2 = tmp;
|
p2 = tmp;
|
||||||
}
|
}
|
||||||
sx = xsize;
|
sx = xsize;
|
||||||
pp = (PIXEL *)((char *)pbuf.getRawBuffer() + linesize * p1->y + p1->x * PSZB);
|
pixelOffset = xsize * p1->y + p1->x;
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz = zbuf + (p1->y * sx + p1->x);
|
pz = zbuf + (p1->y * sx + p1->x);
|
||||||
z = p1->z;
|
z = p1->z;
|
||||||
|
@ -102,33 +101,31 @@ template <bool interpRGB, bool interpZ> void FrameBuffer::fillLine(ZBufferPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dx == 0 && dy == 0) {
|
if (dx == 0 && dy == 0) {
|
||||||
putPixel<interpRGB,interpZ>(pp, cmode, pz, z, color, r, g, b);
|
putPixel<interpRGB,interpZ>(this, pixelOffset, cmode, pz, z, color, r, g, b);
|
||||||
} else if (dx > 0) {
|
} else if (dx > 0) {
|
||||||
if (dx >= dy) {
|
if (dx >= dy) {
|
||||||
drawLine<interpRGB, interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, 1);
|
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, 1);
|
||||||
} else {
|
} else {
|
||||||
drawLine<interpRGB, interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, sx);
|
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, cmode, pz, z, color, r, g, b, dx, dy, sx + 1, sx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dx = -dx;
|
dx = -dx;
|
||||||
if (dx >= dy) {
|
if (dx >= dy) {
|
||||||
drawLine<interpRGB, interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, -1);
|
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, -1);
|
||||||
} else {
|
} else {
|
||||||
drawLine<interpRGB, interpZ>(p1, p2, pp, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, sx);
|
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, cmode, pz, z, color, r, g, b, dx, dy, sx - 1, sx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::plot(ZBufferPoint *p) {
|
void FrameBuffer::plot(ZBufferPoint *p) {
|
||||||
unsigned int *pz;
|
unsigned int *pz;
|
||||||
PIXEL *pp;
|
|
||||||
|
|
||||||
pz = zbuf + (p->y * xsize + p->x);
|
pz = zbuf + (p->y * xsize + p->x);
|
||||||
pp = (PIXEL *)((char *) pbuf.getRawBuffer() + linesize * p->y + p->x * PSZB);
|
|
||||||
unsigned int r, g, b;
|
unsigned int r, g, b;
|
||||||
int col = RGB_TO_PIXEL(p->r, p->g, p->b);
|
int col = RGB_TO_PIXEL(p->r, p->g, p->b);
|
||||||
unsigned int z = p->z;
|
unsigned int z = p->z;
|
||||||
putPixel<false, true>(pp, cmode, pz, z, col, r, g, b);
|
putPixel<false, true>(this, linesize * p->y + p->x * PSZB, cmode, pz, z, col, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::fillLineFlatZ(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
void FrameBuffer::fillLineFlatZ(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
||||||
|
|
|
@ -18,10 +18,9 @@ static const int NB_INTERP = 8;
|
||||||
|
|
||||||
#define SAR_RND_TO_ZERO(v,n) (v / (1 << n))
|
#define SAR_RND_TO_ZERO(v,n) (v / (1 << n))
|
||||||
|
|
||||||
FORCEINLINE static void putPixelMapping(PIXEL *pp, unsigned int *pz, Graphics::PixelBuffer &texture,
|
FORCEINLINE static void putPixelMapping(FrameBuffer *buffer, int buf, unsigned int *pz, Graphics::PixelBuffer &texture, int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &dzdx, int &dsdx, int &dtdx) {
|
||||||
int _a, unsigned int &z, unsigned int &t, unsigned int &s, int &dzdx, int &dsdx, int &dtdx) {
|
|
||||||
if (ZCMP(z, pz[_a])) {
|
if (ZCMP(z, pz[_a])) {
|
||||||
pp[_a] = texture.getRawBuffer()[((t & 0x3FC00000) | s) >> 14];
|
buffer->writePixel(buf + _a, texture.getRawBuffer()[((t & 0x3FC00000) | s) >> 14]);
|
||||||
pz[_a] = z;
|
pz[_a] = z;
|
||||||
}
|
}
|
||||||
z += dzdx;
|
z += dzdx;
|
||||||
|
@ -29,10 +28,9 @@ FORCEINLINE static void putPixelMapping(PIXEL *pp, unsigned int *pz, Graphics::P
|
||||||
t += dtdx;
|
t += dtdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE static void putPixelFlat(PIXEL *pp, unsigned int *pz, int _a, unsigned int &z,
|
FORCEINLINE static void putPixelFlat(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, unsigned int &z, int color, int &dzdx) {
|
||||||
int color, int &dzdx) {
|
|
||||||
if (ZCMP(z, pz[_a])) {
|
if (ZCMP(z, pz[_a])) {
|
||||||
pp[_a] = color;
|
buffer->writePixel(buf + _a, color);
|
||||||
pz[_a] = z;
|
pz[_a] = z;
|
||||||
}
|
}
|
||||||
z += dzdx;
|
z += dzdx;
|
||||||
|
@ -45,21 +43,17 @@ FORCEINLINE static void putPixelDepth(unsigned int *pz, int _a, unsigned int &z,
|
||||||
z += dzdx;
|
z += dzdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE static void putPixelSmooth(Graphics::PixelBuffer &buf, unsigned int *pz, int _a,
|
FORCEINLINE static void putPixelSmooth(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, unsigned int &z, int &tmp, unsigned int &rgb, int &dzdx, unsigned int &drgbdx) {
|
||||||
unsigned int &z, int &tmp, unsigned int &rgb, int &dzdx, unsigned int &drgbdx) {
|
|
||||||
if (ZCMP(z, pz[_a])) {
|
if (ZCMP(z, pz[_a])) {
|
||||||
tmp = rgb & 0xF81F07E0;
|
tmp = rgb & 0xF81F07E0;
|
||||||
buf.setPixelAt(_a, tmp | (tmp >> 16));
|
buffer->writePixel(buf + _a,tmp | (tmp >> 16));
|
||||||
pz[_a] = z;
|
pz[_a] = z;
|
||||||
}
|
}
|
||||||
z += dzdx;
|
z += dzdx;
|
||||||
rgb = (rgb + drgbdx) & (~0x00200800);
|
rgb = (rgb + drgbdx) & (~0x00200800);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE static void putPixelMappingPerspective(Graphics::PixelBuffer &buf,
|
FORCEINLINE static void putPixelMappingPerspective(FrameBuffer *buffer, int 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) {
|
||||||
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])) {
|
if (ZCMP(z, pz[_a])) {
|
||||||
unsigned ttt = (t & 0x003FC000) >> (9 - PSZSH);
|
unsigned ttt = (t & 0x003FC000) >> (9 - PSZSH);
|
||||||
unsigned sss = (s & 0x003FC000) >> (17 - PSZSH);
|
unsigned sss = (s & 0x003FC000) >> (17 - PSZSH);
|
||||||
|
@ -80,7 +74,7 @@ FORCEINLINE static void putPixelMappingPerspective(Graphics::PixelBuffer &buf,
|
||||||
c_r = (c_r * l_r) / 256;
|
c_r = (c_r * l_r) / 256;
|
||||||
c_g = (c_g * l_g) / 256;
|
c_g = (c_g * l_g) / 256;
|
||||||
c_b = (c_b * l_b) / 256;
|
c_b = (c_b * l_b) / 256;
|
||||||
buf.setPixelAt(_a, c_r, c_g, c_b);
|
buffer->writePixel(buf + _a,c_r, c_g, c_b);
|
||||||
pz[_a] = z;
|
pz[_a] = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,8 +211,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// screen coordinates
|
// screen coordinates
|
||||||
|
|
||||||
byte *pp1 = pbuf.getRawBuffer() + linesize * p0->y;
|
int pp1 = xsize * p0->y;
|
||||||
pz1 = zbuf + p0->y * xsize;
|
pz1 = zbuf + p0->y * xsize;
|
||||||
|
|
||||||
switch (drawLogic) {
|
switch (drawLogic) {
|
||||||
|
@ -366,14 +360,16 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
nb_lines--;
|
nb_lines--;
|
||||||
{
|
{
|
||||||
switch (drawLogic) {
|
switch (drawLogic) {
|
||||||
case DRAW_DEPTH_ONLY: {
|
case DRAW_DEPTH_ONLY:
|
||||||
PIXEL *pp;
|
case DRAW_FLAT:
|
||||||
|
case DRAW_MAPPING: {
|
||||||
|
int pp;
|
||||||
int n;
|
int n;
|
||||||
unsigned int *pz;
|
unsigned int *pz;
|
||||||
unsigned int z;
|
unsigned int z;
|
||||||
unsigned int s, t;
|
unsigned int s, t;
|
||||||
n = (x2 >> 16) - x1;
|
n = (x2 >> 16) - x1;
|
||||||
pp = (PIXEL *)((char *)pp1 + x1 * PSZB);
|
pp = pp1 + x1;
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz = pz1 + x1;
|
pz = pz1 + x1;
|
||||||
z = z1;
|
z = z1;
|
||||||
|
@ -384,27 +380,27 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
}
|
}
|
||||||
while (n >= 3) {
|
while (n >= 3) {
|
||||||
if (drawLogic == DRAW_DEPTH_ONLY) {
|
if (drawLogic == DRAW_DEPTH_ONLY) {
|
||||||
putPixelDepth(pz, 0, z ,dzdx);
|
putPixelDepth(pz, 0, z, dzdx);
|
||||||
putPixelDepth(pz, 1, z, dzdx);
|
putPixelDepth(pz, 1, z, dzdx);
|
||||||
putPixelDepth(pz, 2, z, dzdx);
|
putPixelDepth(pz, 2, z, dzdx);
|
||||||
putPixelDepth(pz, 3, z, dzdx);
|
putPixelDepth(pz, 3, z, dzdx);
|
||||||
}
|
}
|
||||||
if (drawLogic == DRAW_FLAT) {
|
if (drawLogic == DRAW_FLAT) {
|
||||||
putPixelFlat(pp, pz, 0, z, color, dzdx);
|
putPixelFlat(this, pp, pz, 0, z, color, dzdx);
|
||||||
putPixelFlat(pp, pz, 1, z, color, dzdx);
|
putPixelFlat(this, pp, pz, 1, z, color, dzdx);
|
||||||
putPixelFlat(pp, pz, 2, z, color, dzdx);
|
putPixelFlat(this, pp, pz, 2, z, color, dzdx);
|
||||||
putPixelFlat(pp, pz, 3, z, color, dzdx);
|
putPixelFlat(this, pp, pz, 3, z, color, dzdx);
|
||||||
}
|
}
|
||||||
if (drawLogic == DRAW_MAPPING) {
|
if (drawLogic == DRAW_MAPPING) {
|
||||||
putPixelMapping(pp, pz, texture, 0, z, t, s, dzdx, dsdx, dtdx);
|
putPixelMapping(this, pp, pz, texture, 0, z, t, s, dzdx, dsdx, dtdx);
|
||||||
putPixelMapping(pp, pz, texture, 1, z, t, s, dzdx, dsdx, dtdx);
|
putPixelMapping(this, pp, pz, texture, 1, z, t, s, dzdx, dsdx, dtdx);
|
||||||
putPixelMapping(pp, pz, texture, 2, z, t, s, dzdx, dsdx, dtdx);
|
putPixelMapping(this, pp, pz, texture, 2, z, t, s, dzdx, dsdx, dtdx);
|
||||||
putPixelMapping(pp, pz, texture, 3, z, t, s, dzdx, dsdx, dtdx);
|
putPixelMapping(this, pp, pz, texture, 3, z, t, s, dzdx, dsdx, dtdx);
|
||||||
}
|
}
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz += 4;
|
pz += 4;
|
||||||
}
|
}
|
||||||
pp = (PIXEL *)((char *)pp + 4 * PSZB);
|
pp += 4;
|
||||||
n -= 4;
|
n -= 4;
|
||||||
}
|
}
|
||||||
while (n >= 0) {
|
while (n >= 0) {
|
||||||
|
@ -412,15 +408,15 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
putPixelDepth(pz, 0, z, dzdx);
|
putPixelDepth(pz, 0, z, dzdx);
|
||||||
}
|
}
|
||||||
if (drawLogic == DRAW_FLAT) {
|
if (drawLogic == DRAW_FLAT) {
|
||||||
putPixelFlat(pp, pz, 0, z, color, dzdx);
|
putPixelFlat(this, pp, pz, 0, z, color, dzdx);
|
||||||
}
|
}
|
||||||
if (drawLogic == DRAW_MAPPING) {
|
if (drawLogic == DRAW_MAPPING) {
|
||||||
putPixelMapping(pp, pz, texture, 0, z, t, s, dzdx, dsdx, dtdx);
|
putPixelMapping(this, pp, pz, texture, 0, z, t, s, dzdx, dsdx, dtdx);
|
||||||
}
|
}
|
||||||
if (interpZ) {
|
if (interpZ) {
|
||||||
pz += 1;
|
pz += 1;
|
||||||
}
|
}
|
||||||
pp = (PIXEL *)((char *)pp + PSZB);
|
pp += 1;
|
||||||
n -= 1;
|
n -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,8 +449,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
|
|
||||||
n = (x2 >> 16) - x1;
|
n = (x2 >> 16) - x1;
|
||||||
|
|
||||||
Graphics::PixelBuffer buf = pbuf;
|
int buf = pp1 + x1;
|
||||||
buf = pp1 + x1 * PSZB;
|
|
||||||
|
|
||||||
pm = pm1 + x1;
|
pm = pm1 + x1;
|
||||||
pz = pz1 + x1;
|
pz = pz1 + x1;
|
||||||
|
@ -462,36 +457,34 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
while (n >= 3) {
|
while (n >= 3) {
|
||||||
for (int a = 0; a < 4; a++) {
|
for (int a = 0; a < 4; a++) {
|
||||||
if (ZCMP(z, pz[a]) && pm[0]) {
|
if (ZCMP(z, pz[a]) && pm[0]) {
|
||||||
buf.setPixelAt(a, color);
|
writePixel(buf + a, color);
|
||||||
pz[a] = z;
|
pz[a] = z;
|
||||||
}
|
}
|
||||||
z += dzdx;
|
z += dzdx;
|
||||||
}
|
}
|
||||||
pz += 4;
|
pz += 4;
|
||||||
pm += 4;
|
pm += 4;
|
||||||
buf.shiftBy(4);
|
buf += 4;
|
||||||
n -= 4;
|
n -= 4;
|
||||||
}
|
}
|
||||||
while (n >= 0) {
|
while (n >= 0) {
|
||||||
if (ZCMP(z, pz[0]) && pm[0]) {
|
if (ZCMP(z, pz[0]) && pm[0]) {
|
||||||
buf.setPixelAt(0, color);
|
writePixel(buf, color);
|
||||||
pz[0] = z;
|
pz[0] = z;
|
||||||
}
|
}
|
||||||
pz += 1;
|
pz += 1;
|
||||||
pm += 1;
|
pm += 1;
|
||||||
buf.shiftBy(1);
|
buf += 1;
|
||||||
n -= 1;
|
n -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DRAW_SMOOTH: {
|
case DRAW_SMOOTH: {
|
||||||
unsigned int *pz;
|
unsigned int *pz;
|
||||||
Graphics::PixelBuffer buf = pbuf;
|
int buf = pp1 + x1;
|
||||||
unsigned int z, rgb, drgbdx;
|
unsigned int z, rgb, drgbdx;
|
||||||
int n;
|
int n;
|
||||||
n = (x2 >> 16) - x1;
|
n = (x2 >> 16) - x1;
|
||||||
int bpp = buf.getFormat().bytesPerPixel;
|
|
||||||
buf = (byte *)pp1 + x1 * bpp;
|
|
||||||
pz = pz1 + x1;
|
pz = pz1 + x1;
|
||||||
z = z1;
|
z = z1;
|
||||||
rgb = (r1 << 16) & 0xFFC00000;
|
rgb = (r1 << 16) & 0xFFC00000;
|
||||||
|
@ -499,17 +492,17 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
rgb |= (b1 << 5) & 0x001FF000;
|
rgb |= (b1 << 5) & 0x001FF000;
|
||||||
drgbdx = _drgbdx;
|
drgbdx = _drgbdx;
|
||||||
while (n >= 3) {
|
while (n >= 3) {
|
||||||
putPixelSmooth(buf, pz, 0, z, tmp, rgb, dzdx, drgbdx);
|
putPixelSmooth(this, buf, pz, 0, z, tmp, rgb, dzdx, drgbdx);
|
||||||
putPixelSmooth(buf, pz, 1, z, tmp, rgb, dzdx, drgbdx);
|
putPixelSmooth(this, buf, pz, 1, z, tmp, rgb, dzdx, drgbdx);
|
||||||
putPixelSmooth(buf, pz, 2, z, tmp, rgb, dzdx, drgbdx);
|
putPixelSmooth(this, buf, pz, 2, z, tmp, rgb, dzdx, drgbdx);
|
||||||
putPixelSmooth(buf, pz, 3, z, tmp, rgb, dzdx, drgbdx);
|
putPixelSmooth(this, buf, pz, 3, z, tmp, rgb, dzdx, drgbdx);
|
||||||
pz += 4;
|
pz += 4;
|
||||||
buf.shiftBy(4);
|
buf += 4;
|
||||||
n -= 4;
|
n -= 4;
|
||||||
}
|
}
|
||||||
while (n >= 0) {
|
while (n >= 0) {
|
||||||
putPixelSmooth(buf, pz, 0, z, tmp, rgb, dzdx, drgbdx);
|
putPixelSmooth(this, buf, pz, 0, z, tmp, rgb, dzdx, drgbdx);
|
||||||
buf.shiftBy(1);
|
buf += 1;
|
||||||
pz += 1;
|
pz += 1;
|
||||||
n -= 1;
|
n -= 1;
|
||||||
}
|
}
|
||||||
|
@ -524,8 +517,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
fz = (float)z1;
|
fz = (float)z1;
|
||||||
zinv = (float)(1.0 / fz);
|
zinv = (float)(1.0 / fz);
|
||||||
|
|
||||||
Graphics::PixelBuffer buf = pbuf;
|
int buf = pp1 + x1;
|
||||||
buf = pp1 + x1 * PSZB;
|
|
||||||
|
|
||||||
pz = pz1 + x1;
|
pz = pz1 + x1;
|
||||||
z = z1;
|
z = z1;
|
||||||
|
@ -548,11 +540,10 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
zinv = (float)(1.0 / fz);
|
zinv = (float)(1.0 / fz);
|
||||||
}
|
}
|
||||||
for (int _a = 0; _a < 8; _a++) {
|
for (int _a = 0; _a < 8; _a++) {
|
||||||
putPixelMappingPerspective(buf, textureFormat, texture, pz, _a, z, t, s, tmp, rgb, dzdx, dsdx, dtdx,
|
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, _a, z, t, s, tmp, rgb, dzdx, dsdx, dtdx, drgbdx);
|
||||||
drgbdx);
|
|
||||||
}
|
}
|
||||||
pz += NB_INTERP;
|
pz += NB_INTERP;
|
||||||
buf.shiftBy(NB_INTERP);
|
buf += NB_INTERP;
|
||||||
n -= NB_INTERP;
|
n -= NB_INTERP;
|
||||||
sz += ndszdx;
|
sz += ndszdx;
|
||||||
tz += ndtzdx;
|
tz += ndtzdx;
|
||||||
|
@ -569,10 +560,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
while (n >= 0) {
|
while (n >= 0) {
|
||||||
putPixelMappingPerspective(buf, textureFormat, texture, pz, 0, z, t, s, tmp, rgb, dzdx, dsdx, dtdx,
|
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, 0, z, t, s, tmp, rgb, dzdx, dsdx, dtdx, drgbdx);
|
||||||
drgbdx);
|
|
||||||
pz += 1;
|
pz += 1;
|
||||||
buf.shiftBy(1);
|
buf += 1;
|
||||||
n -= 1;
|
n -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,7 +620,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
||||||
x2 += dx2dy2;
|
x2 += dx2dy2;
|
||||||
|
|
||||||
// screen coordinates
|
// screen coordinates
|
||||||
pp1 += linesize;
|
pp1 += xsize;
|
||||||
pz1 += xsize;
|
pz1 += xsize;
|
||||||
|
|
||||||
if (drawLogic == DRAW_SHADOW || drawLogic == DRAW_SHADOW_MASK)
|
if (drawLogic == DRAW_SHADOW || drawLogic == DRAW_SHADOW_MASK)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue