TINYGL: Implemented alpha interpolation in triangle rasterization routine.

This commit is contained in:
Stefano Musumeci 2014-06-19 17:30:28 +02:00
parent 03072c4b7b
commit 63fd685589
13 changed files with 320 additions and 163 deletions

View File

@ -347,8 +347,7 @@ Math::Matrix4 GfxTinyGL::getProjection() {
}
void GfxTinyGL::clearScreen() {
_zb->pbuf.clear(_screenSize);
memset(_zb->zbuf, 0, _gameWidth * _gameHeight * sizeof(unsigned int));
_zb->clear(true, 0, true, 0, 0, 0);
}
void GfxTinyGL::clearDepthBuffer() {
@ -638,11 +637,11 @@ void GfxTinyGL::startActorDraw(const Actor *actor) {
}
// FIXME: TinyGL doesn't seem to support translucency.
const float alpha = actor->getEffectiveAlpha();
const float alpha = actor->getEffectiveAlpha();
if (alpha < 1.f) {
_alpha = alpha;
// tglEnable(TGL_BLEND);
// tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
tglEnable(TGL_BLEND);
//tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
}
const Math::Quaternion &quat = actor->getRotationQuat();
@ -701,7 +700,7 @@ void GfxTinyGL::finishActorDraw() {
// FIXME: TinyGL doesn't seem to support translucency.
if (_alpha < 1.f) {
// tglDisable(TGL_BLEND);
tglDisable(TGL_BLEND);
_alpha = 1.f;
}
@ -838,6 +837,7 @@ void GfxTinyGL::drawModelFace(const Mesh *mesh, const MeshFace *face) {
if (face->hasTexture())
tglTexCoord2fv(textureVerts + 2 * face->getTextureVertex(i));
tglColor4f(1.0f,1.0f,1.0f,_alpha);
tglVertex3fv(vertices + 3 * face->getVertex(i));
}
tglEnd();
@ -1063,6 +1063,26 @@ void GfxTinyGL::createBitmap(BitmapData *bitmap) {
}
}
void GfxTinyGL::blitScreen( const Graphics::PixelFormat &format, BlitImage *image, byte *src, int x, int y, int width, int height, bool trans ) {
int srcX, srcY;
if (x < 0) {
srcX = -x;
x = 0;
} else {
srcX = 0;
}
if (y < 0) {
srcY = -y;
y = 0;
} else {
srcY = 0;
}
blitScreen(format, image, src, x, y, srcX, srcY, width, height, width, height, trans);
}
void GfxTinyGL::blit(const Graphics::PixelFormat &format, BlitImage *image, byte *dst, byte *src, int x, int y, int width, int height, bool trans) {
int srcX, srcY;
@ -1149,6 +1169,74 @@ void GfxTinyGL::blit(const Graphics::PixelFormat &format, BlitImage *image, byte
}
}
void GfxTinyGL::blitScreen( const Graphics::PixelFormat &format, BlitImage *image, byte *src, int dstX, int dstY, int srcX, int srcY, int width, int height, int srcWidth, int srcHeight, bool trans ) {
if (_dimLevel > 0.0f && _dimLevel < 1.0f) {
warning("TinyGL doesn't implement partial screen-dimming yet");
}
if (dstX >= _gameWidth || dstY >= _gameHeight)
return;
int clampWidth, clampHeight;
if (dstX + width > _gameWidth)
clampWidth = _gameWidth - dstX;
else
clampWidth = width;
if (dstY + height > _gameHeight)
clampHeight = _gameHeight - dstY;
else
clampHeight = height;
byte *dst = _zb->getPixelBuffer();
dst += (dstX + (dstY * _gameWidth)) * format.bytesPerPixel;
src += (srcX + (srcY * srcWidth)) * format.bytesPerPixel;
Graphics::PixelBuffer srcBuf(format, src);
Graphics::PixelBuffer dstBuf(format, dst);
if (!trans) {
for (int l = 0; l < clampHeight; l++) {
dstBuf.copyBuffer(0, clampWidth, srcBuf);
dstBuf.shiftBy(_gameWidth);
srcBuf.shiftBy(srcWidth);
}
} else {
if (image) {
BlitImage::Line *l = image->_lines;
int maxY = srcY + clampHeight;
int maxX = srcX + clampWidth;
while (l && l->y < srcY)
l = l->next;
while (l && l->y < maxY) {
if (l->x < maxX && l->x + l->length > srcX) {
int length = l->length;
int skipStart = l->x < srcX ? srcX - l->x : 0;
length -= skipStart;
int skipEnd = l->x + l->length > maxX ? l->x + l->length - maxX : 0;
length -= skipEnd;
memcpy(dstBuf.getRawBuffer((l->y - srcY) * _gameWidth + MAX(l->x - srcX, 0)),
l->pixels + skipStart * format.bytesPerPixel, length * format.bytesPerPixel);
}
l = l->next;
}
} else {
for (int l = 0; l < clampHeight; l++) {
for (int r = 0; r < clampWidth; ++r) {
if (srcBuf.getValueAt(r) != 0xf81f) {
dstBuf.setPixelAt(r, srcBuf);
}
}
dstBuf.shiftBy(_gameWidth);
srcBuf.shiftBy(srcWidth);
}
}
}
}
void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
// PS2 EMI uses a TGA for it's splash-screen, avoid using the following
@ -1175,7 +1263,7 @@ void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
int srcX = texc[ntex + 2] * bitmap->getWidth();
int srcY = texc[ntex + 3] * bitmap->getHeight();
blit(bitmap->getPixelFormat(texId), &b[texId], _zb->pbuf.getRawBuffer(), bitmap->getData(texId).getRawBuffer(),
blitScreen(bitmap->getPixelFormat(texId), &b[texId], bitmap->getData(texId).getRawBuffer(),
x + dx1, y + dy1, srcX, srcY, dx2 - dx1, dy2 - dy1, b[texId]._width, b[texId]._height, true);
ntex += 16;
}
@ -1195,7 +1283,7 @@ void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
BlitImage *b = (BlitImage *)bitmap->getTexIds();
if (bitmap->getFormat() == 1)
blit(bitmap->getPixelFormat(num), &b[num], (byte *)_zb->pbuf.getRawBuffer(), (byte *)bitmap->getData(num).getRawBuffer(),
blitScreen(bitmap->getPixelFormat(num), &b[num], (byte *)bitmap->getData(num).getRawBuffer(),
x, y, bitmap->getWidth(), bitmap->getHeight(), true);
else
blit(bitmap->getPixelFormat(num), nullptr, (byte *)_zb->zbuf, (byte *)bitmap->getData(num).getRawBuffer(),
@ -1303,7 +1391,7 @@ void GfxTinyGL::drawTextObject(const TextObject *text) {
if (userData) {
int numLines = text->getNumLines();
for (int i = 0; i < numLines; ++i) {
blit(_pixelFormat, nullptr, (byte *)_zb->pbuf.getRawBuffer(), userData[i].data, userData[i].x, userData[i].y, userData[i].width, userData[i].height, true);
blitScreen(_pixelFormat, nullptr, userData[i].data, userData[i].x, userData[i].y, userData[i].width, userData[i].height, true);
}
}
}
@ -1412,9 +1500,9 @@ void GfxTinyGL::prepareMovieFrame(Graphics::Surface *frame) {
void GfxTinyGL::drawMovieFrame(int offsetX, int offsetY) {
if (_smushWidth == _gameWidth && _smushHeight == _gameHeight) {
_zb->pbuf.copyBuffer(0, _gameWidth * _gameHeight, _smushBitmap);
_zb->copyFromBuffer(_smushBitmap);
} else {
blit(_pixelFormat, nullptr, (byte *)_zb->pbuf.getRawBuffer(), _smushBitmap.getRawBuffer(), offsetX, offsetY, _smushWidth, _smushHeight, false);
blitScreen(_pixelFormat, nullptr, _smushBitmap.getRawBuffer(), offsetX, offsetY, _smushWidth, _smushHeight, false);
}
}
@ -1441,7 +1529,7 @@ void GfxTinyGL::drawEmergString(int x, int y, const char *text, const Color &fgC
int pixel = line & 0x80;
line <<= 1;
if (pixel) {
_zb->pbuf.setPixelAt(((py + y) * _gameWidth) + (px + x), color);
_zb->writePixel(((py + y) * _gameWidth) + (px + x), color);
}
}
}
@ -1467,7 +1555,7 @@ Bitmap *GfxTinyGL::getScreenshot(int w, int h) {
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
uint8 lr, lg, lb;
_zb->pbuf.getRGBAt(y * _gameWidth + x, lr, lg, lb);
_zb->readPixelRGB(y * _gameWidth + x, lr, lg, lb);
color += (lr + lg + lb) / 3;
}
}
@ -1481,11 +1569,11 @@ Bitmap *GfxTinyGL::getScreenshot(int w, int h) {
}
void GfxTinyGL::storeDisplay() {
_storedDisplay.copyBuffer(0, _gameWidth * _gameHeight, _zb->pbuf);
_zb->copyToBuffer(_storedDisplay);
}
void GfxTinyGL::copyStoredToDisplay() {
_zb->pbuf.copyBuffer(0, _gameWidth * _gameHeight, _storedDisplay);
_zb->copyFromBuffer(_storedDisplay);
}
void GfxTinyGL::dimScreen() {
@ -1501,9 +1589,9 @@ void GfxTinyGL::dimRegion(int x, int y, int w, int h, float level) {
for (int ly = y; ly < y + h; ly++) {
for (int lx = x; lx < x + w; lx++) {
uint8 r, g, b;
_zb->pbuf.getRGBAt(ly * _gameWidth + lx, r, g, b);
_zb->readPixelRGB(ly * _gameWidth + lx, r, g, b);
uint32 color = (uint32)(((r + g + b) / 3) * level);
_zb->pbuf.setPixelAt(ly * _gameWidth + lx, color, color, color);
_zb->writePixel(ly * _gameWidth + lx, color, color, color);
}
}
}
@ -1515,7 +1603,7 @@ void GfxTinyGL::irisAroundRegion(int x1, int y1, int x2, int y2) {
if (lx > x1 && lx < x2 && ly > y1 && ly < y2)
continue;
// But set everything around it to black.
_zb->pbuf.setPixelAt(ly * _gameWidth + lx, 0);
_zb->writePixel(ly * _gameWidth + lx, 0);
}
}
}
@ -1534,24 +1622,24 @@ void GfxTinyGL::drawRectangle(const PrimitiveObject *primitive) {
if (y1 >= 0 && y1 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->pbuf.setPixelAt(_gameWidth * y1 + x, c);
_zb->writePixel(_gameWidth * y1 + x, c);
} else {
if (y1 >= 0 && y1 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->pbuf.setPixelAt(_gameWidth * y1 + x, c);
_zb->writePixel(_gameWidth * y1 + x, c);
if (y2 >= 0 && y2 < _gameHeight)
for (int x = x1; x <= x2; x++)
if (x >= 0 && x < _gameWidth)
_zb->pbuf.setPixelAt(_gameWidth * y2 + x, c);
_zb->writePixel(_gameWidth * y2 + x, c);
if (x1 >= 0 && x1 < _gameWidth)
for (int y = y1; y <= y2; y++)
if (y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x1, c);
_zb->writePixel(_gameWidth * y + x1, c);
if (x2 >= 0 && x2 < _gameWidth)
for (int y = y1; y <= y2; y++)
if (y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x2, c);
_zb->writePixel(_gameWidth * y + x2, c);
}
}
@ -1566,7 +1654,7 @@ void GfxTinyGL::drawLine(const PrimitiveObject *primitive) {
if (x2 == x1) {
for (int y = y1; y <= y2; y++) {
if (x1 >= 0 && x1 < _gameWidth && y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x1, color.getRed(), color.getGreen(), color.getBlue());
_zb->writePixel(_gameWidth * y + x1, color.getRed(), color.getGreen(), color.getBlue());
}
} else {
float m = (y2 - y1) / (x2 - x1);
@ -1574,7 +1662,7 @@ void GfxTinyGL::drawLine(const PrimitiveObject *primitive) {
for (int x = x1; x <= x2; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x, color.getRed(), color.getGreen(), color.getBlue());
_zb->writePixel(_gameWidth * y + x, color.getRed(), color.getGreen(), color.getBlue());
}
}
}
@ -1599,14 +1687,14 @@ void GfxTinyGL::drawPolygon(const PrimitiveObject *primitive) {
for (int x = x1; x <= x2; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x, c);
_zb->writePixel(_gameWidth * y + x, c);
}
m = (y4 - y3) / (x4 - x3);
b = (int)(-m * x3 + y3);
for (int x = x3; x <= x4; x++) {
int y = (int)(m * x) + b;
if (x >= 0 && x < _gameWidth && y >= 0 && y < _gameHeight)
_zb->pbuf.setPixelAt(_gameWidth * y + x, c);
_zb->writePixel(_gameWidth * y + x, c);
}
}
@ -1615,7 +1703,7 @@ void GfxTinyGL::readPixels(int x, int y, int width, int height, uint8 *buffer) {
int pos = x + y * 640;
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
_zb->pbuf.getRGBAt(pos + j, r, g, b);
_zb->readPixelRGB(pos + j, r, g, b);
buffer[0] = r;
buffer[1] = g;
buffer[2] = b;

View File

@ -146,6 +146,8 @@ private:
void readPixels(int x, int y, int width, int height, uint8 *buffer);
void blit(const Graphics::PixelFormat &format, BlitImage *blit, byte *dst, byte *src, int x, int y, int width, int height, bool trans);
void blit(const Graphics::PixelFormat &format, BlitImage *blit, byte *dst, byte *src, int dstX, int dstY, int srcX, int srcY, int width, int height, int srcWidth, int srcHeight, bool trans);
void blitScreen(const Graphics::PixelFormat &format, BlitImage *blit, byte *src, int x, int y, int width, int height, bool trans);
void blitScreen(const Graphics::PixelFormat &format, BlitImage *blit, byte *src, int dstX, int dstY, int srcX, int srcY, int width, int height, int srcWidth, int srcHeight, bool trans);
};
} // end of namespace Grim

View File

@ -47,7 +47,7 @@ void tglNormal3fv(float *v) {
// glColor
void tglColor4f(float r, float g, float b, float a) {
TinyGL::GLParam p[8];
TinyGL::GLParam p[9];
p[0].op = TinyGL::OP_Color;
p[1].f = r;
@ -58,11 +58,12 @@ void tglColor4f(float r, float g, float b, float a) {
p[5].ui = (unsigned int)(r * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + ZB_POINT_RED_MIN);
p[6].ui = (unsigned int)(g * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + ZB_POINT_GREEN_MIN);
p[7].ui = (unsigned int)(b * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + ZB_POINT_BLUE_MIN);
p[8].ui = (unsigned int)(a * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN) + ZB_POINT_ALPHA_MIN);
gl_add_op(p);
}
void tglColor4fv(float *v) {
TinyGL::GLParam p[8];
TinyGL::GLParam p[9];
p[0].op = TinyGL::OP_Color;
p[1].f = v[0];
@ -73,6 +74,7 @@ void tglColor4fv(float *v) {
p[5].ui = (unsigned int)(v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + ZB_POINT_RED_MIN);
p[6].ui = (unsigned int)(v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + ZB_POINT_GREEN_MIN);
p[7].ui = (unsigned int)(v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + ZB_POINT_BLUE_MIN);
p[8].ui = (unsigned int)(v[3] * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN) + ZB_POINT_ALPHA_MIN);
TinyGL::gl_add_op(p);
}

View File

@ -29,11 +29,14 @@ void gl_transform_to_viewport(GLContext *c, GLVertex *v) {
+ ZB_POINT_GREEN_MIN);
v->zp.b = (int)(v->color.Z * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
+ ZB_POINT_BLUE_MIN);
v->zp.a = (int)(v->color.W * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN)
+ ZB_POINT_ALPHA_MIN);
} else {
// no need to convert to integer if no lighting : take current color
v->zp.r = c->longcurrent_color[0];
v->zp.g = c->longcurrent_color[1];
v->zp.b = c->longcurrent_color[2];
v->zp.a = c->longcurrent_color[3];
}
// texture

View File

@ -102,6 +102,7 @@ void glInit(void *zbuffer1) {
c->longcurrent_color[0] = 65535;
c->longcurrent_color[1] = 65535;
c->longcurrent_color[2] = 65535;
c->longcurrent_color[3] = 65535;
c->current_normal = Vector4(1.0f, 0.0f, 0.0f, 0.0f);

View File

@ -292,10 +292,10 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
B += att * lB;
}
v->color.X = clampf(R, 0, 1);
v->color.Y = clampf(G, 0, 1);
v->color.Z = clampf(B, 0, 1);
v->color.W = A;
v->color.X = clampf(c->current_color.X * R, 0, 1);
v->color.Y = clampf(c->current_color.Y * G, 0, 1);
v->color.Z = clampf(c->current_color.Z * B, 0, 1);
v->color.W = c->current_color.W * A;
}
} // end of namespace TinyGL

View File

@ -62,7 +62,6 @@ void glopEnableDisable(GLContext *c, GLParam *p) {
c->depth_test = v;
break;
case TGL_BLEND:
c->enable_blend = v;
c->fb->enableBlending(v);
break;
case TGL_POLYGON_OFFSET_FILL:

View File

@ -29,6 +29,7 @@ void glopColor(GLContext *c, GLParam *p) {
c->longcurrent_color[0] = p[5].ui;
c->longcurrent_color[1] = p[6].ui;
c->longcurrent_color[2] = p[7].ui;
c->longcurrent_color[3] = p[8].ui;
if (c->color_material_enabled) {
GLParam q[7];

View File

@ -162,7 +162,7 @@ void FrameBuffer::setTexture(const Graphics::PixelBuffer &texture) {
current_texture = texture;
}
void FrameBuffer::setBlendingFactors( int sfactor, int dfactor ) {
void FrameBuffer::setBlendingFactors(int sfactor, int dfactor) {
_sourceBlendingFactor = sfactor;
_destinationBlendingFactor = dfactor;
}

View File

@ -23,11 +23,13 @@ namespace TinyGL {
#define ZB_POINT_GREEN_MAX ( (1 << 16) - (1 << 9) )
#define ZB_POINT_BLUE_MIN ( (1 << 10) )
#define ZB_POINT_BLUE_MAX ( (1 << 16) - (1 << 10) )
#define ZB_POINT_ALPHA_MIN ( (1 << 10) )
#define ZB_POINT_ALPHA_MAX ( (1 << 16) - (1 << 10) )
// display modes
#define ZB_MODE_5R6G5B 1 // true color 16 bits
#define RGB_TO_PIXEL(r, g, b) cmode.RGBToColor(r, g, b)
#define RGB_TO_PIXEL(r, g, b) cmode.ARGBToColor(255, r, g, b) // Default to 255 alpha aka solid colour.
typedef byte PIXEL;
#define PSZSH 4
@ -43,7 +45,7 @@ struct Buffer {
struct ZBufferPoint {
int x, y, z; // integer coordinates in the zbuffer
int s, t; // coordinates for the mapping
int r, g, b; // color indexes
int r, g, b, a; // color indexes
float sz, tz; // temporary coordinates for mapping
};
@ -56,49 +58,52 @@ struct FrameBuffer {
void delOffscreenBuffer(Buffer *buffer);
void clear(int clear_z, int z, int clear_color, int r, int g, int b);
byte *getPixelBuffer() {
return pbuf.getRawBuffer(0);
}
FORCEINLINE void readPixelRGB(int pixel, byte &r, byte &g, byte &b) {
pbuf.getRGBAt(pixel, r, g, b);
}
FORCEINLINE void writePixel(int pixel, int value) {
if (_blendingEnabled == false) {
this->pbuf.setPixelAt(pixel,value);
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;
rDst = gDst = bDst = 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;
rDst = (rSrc * rDst) >> 8;
gDst = (gSrc * gDst) >> 8;
bDst = (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;
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);
rSrc = (rSrc * aSrc) >> 8;
gSrc = (gSrc * aSrc) >> 8;
bSrc = (bSrc * aSrc) >> 8;
rDst = (rDst * aDst) >> 8;
gDst = (gDst * aDst) >> 8;
bDst = (bDst * aDst) >> 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;
rDst = (rDst * (255 - aDst)) >> 8;
gDst = (gDst * (255 - aDst)) >> 8;
bDst = (bDst * (255 - aDst)) >> 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;
@ -115,59 +120,8 @@ struct FrameBuffer {
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) {
switch (_destinationBlendingFactor) {
case TGL_ZERO:
rSrc = gSrc = bSrc = 0;
break;
@ -188,15 +142,15 @@ struct FrameBuffer {
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;
rSrc = (rSrc * aDst) >> 8;
gSrc = (gSrc * aDst) >> 8;
bSrc = (bSrc * aDst) >> 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;
rSrc = (rSrc * (255 - aDst)) >> 8;
gSrc = (gSrc * (255 - aDst)) >> 8;
bSrc = (bSrc * (255 - aDst)) >> 8;
break;
case TGL_DST_ALPHA:
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
@ -209,19 +163,32 @@ struct FrameBuffer {
default:
break;
}
switch (_destinationBlendingFactor) {
this->pbuf.setPixelAt(pixel,255,rSrc + rDst,gSrc + gDst,bSrc + bDst);
}
}
FORCEINLINE void writePixel(int pixel, byte rDst, byte gDst, byte bDst) {
writePixel(pixel, 255, rDst, gDst, bDst);
}
FORCEINLINE void writePixel(int pixel, byte aDst, byte rDst, byte gDst, byte bDst) {
if (_blendingEnabled == false) {
this->pbuf.setPixelAt(pixel, aDst, rDst, gDst, bDst);
} else {
byte rSrc, gSrc, bSrc, aSrc;
switch (_sourceBlendingFactor) {
case TGL_ZERO:
rDst = gDst = bDst = 0;
break;
case TGL_ONE:
break;
case TGL_SRC_COLOR:
case TGL_DST_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:
case TGL_ONE_MINUS_DST_COLOR:
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
rDst = (rDst * (255 - rSrc)) >> 8;
gDst = (gDst * (255 - gSrc)) >> 8;
@ -229,15 +196,15 @@ struct FrameBuffer {
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;
rDst = (rDst * aDst) >> 8;
gDst = (gDst * aDst) >> 8;
bDst = (bDst * aDst) >> 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;
rDst = (rDst * (255 - aDst)) >> 8;
gDst = (gDst * (255 - aDst)) >> 8;
bDst = (bDst * (255 - aDst)) >> 8;
break;
case TGL_DST_ALPHA:
break;
@ -247,10 +214,61 @@ struct FrameBuffer {
default:
break;
}
this->pbuf.setPixelAt(pixel,255,rSrc + rDst,gSrc + gDst,bSrc + bDst);
switch (_destinationBlendingFactor) {
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 * aDst) >> 8;
gSrc = (gSrc * aDst) >> 8;
bSrc = (bSrc * aDst) >> 8;
break;
case TGL_ONE_MINUS_SRC_ALPHA:
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
rSrc = (rSrc * (255 - aDst)) >> 8;
gSrc = (gSrc * (255 - aDst)) >> 8;
bSrc = (bSrc * (255 - aDst)) >> 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;
}
this->pbuf.setPixelAt(pixel, 255, rSrc + rDst, gSrc + gDst, bSrc + bDst);
}
}
void copyToBuffer(Graphics::PixelBuffer &buffer) {
buffer.copyBuffer(0, xsize * ysize, pbuf);
}
void copyFromBuffer(Graphics::PixelBuffer &buffer) {
pbuf.copyBuffer(0, xsize * ysize, buffer);
}
void enableBlending(bool enableBlending);
void setBlendingFactors(int sfactor, int dfactor);
@ -304,8 +322,8 @@ struct FrameBuffer {
unsigned char *dctable;
int *ctable;
Graphics::PixelBuffer current_texture;
Graphics::PixelBuffer pbuf;
private:
Graphics::PixelBuffer pbuf;
bool _blendingEnabled;
int _sourceBlendingFactor;
int _destinationBlendingFactor;

View File

@ -227,7 +227,7 @@ struct GLContext {
// current vertex state
Vector4 current_color;
unsigned int longcurrent_color[3]; // precomputed integer color
unsigned int longcurrent_color[4]; // precomputed integer color
Vector4 current_normal;
Vector4 current_tex_coord;
int current_edge_flag;

View File

@ -6,30 +6,31 @@ namespace TinyGL {
#define ZCMP(z,zpix) ((z) >= (zpix))
template <bool interpRGB, bool interpZ>
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) {
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) {
if (interpZ) {
if (ZCMP(z, *pz)) {
if (interpRGB) {
buffer->writePixel(pixelOffset,RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8));
}
else {
buffer->writePixel(pixelOffset,color);
buffer->writePixel(pixelOffset, RGB_TO_PIXEL(r >> 8, g >> 8, b >> 8));
} else {
buffer->writePixel(pixelOffset, color);
}
*pz = z;
}
}
else {
} else {
if (interpRGB) {
buffer->writePixel(pixelOffset,RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8));
}
else {
buffer->writePixel(pixelOffset,color);
buffer->writePixel(pixelOffset, RGB_TO_PIXEL(r >> 8, g >> 8, b >> 8));
} else {
buffer->writePixel(pixelOffset, color);
}
}
}
template <bool interpRGB, bool interpZ>
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) {
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) {
int n = dx;
int rinc, ginc, binc;
int zinc;
@ -47,7 +48,7 @@ FORCEINLINE static void drawLine(FrameBuffer *buffer, ZBufferPoint *p1, ZBufferP
int pp_inc_1 = (inc_1);
int pp_inc_2 = (inc_2);
do {
putPixel<interpRGB,interpZ>(buffer, pixelOffset, cmode, pz, z, color, r, g, b);
putPixel<interpRGB, interpZ>(buffer, pixelOffset, cmode, pz, z, color, r, g, b);
if (interpZ) {
z += zinc;
}
@ -101,19 +102,23 @@ void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
}
if (dx == 0 && dy == 0) {
putPixel<interpRGB,interpZ>(this, pixelOffset, cmode, pz, z, color, r, g, b);
putPixel<interpRGB, interpZ>(this, pixelOffset, cmode, pz, z, color, r, g, b);
} else if (dx > 0) {
if (dx >= dy) {
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, 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 {
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, 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 {
dx = -dx;
if (dx >= dy) {
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, 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 {
drawLine<interpRGB,interpZ>(this, p1, p2, pixelOffset, 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);
}
}
}

View File

@ -18,7 +18,9 @@ static const int NB_INTERP = 8;
#define SAR_RND_TO_ZERO(v,n) (v / (1 << n))
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) {
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) {
if (ZCMP(z, pz[_a])) {
buffer->writePixel(buf + _a, texture.getRawBuffer()[((t & 0x3FC00000) | s) >> 14]);
pz[_a] = z;
@ -28,7 +30,8 @@ FORCEINLINE static void putPixelMapping(FrameBuffer *buffer, int buf, unsigned i
t += dtdx;
}
FORCEINLINE static void putPixelFlat(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, unsigned int &z, int color, int &dzdx) {
FORCEINLINE static void putPixelFlat(FrameBuffer *buffer, int buf, unsigned int *pz, int _a,
unsigned int &z, int color, int &dzdx) {
if (ZCMP(z, pz[_a])) {
buffer->writePixel(buf + _a, color);
pz[_a] = z;
@ -43,45 +46,65 @@ FORCEINLINE static void putPixelDepth(unsigned int *pz, int _a, unsigned int &z,
z += dzdx;
}
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) {
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) {
if (ZCMP(z, pz[_a])) {
tmp = rgb & 0xF81F07E0;
buffer->writePixel(buf + _a,tmp | (tmp >> 16));
buffer->writePixel(buf + _a, tmp | (tmp >> 16));
pz[_a] = z;
}
z += dzdx;
rgb = (rgb + drgbdx) & (~0x00200800);
}
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) {
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 &rgba, unsigned int &a,
int &dzdx, int &dsdx, int &dtdx, unsigned int &drgbdx, unsigned int dadx) {
if (ZCMP(z, pz[_a])) {
unsigned ttt = (t & 0x003FC000) >> (9 - PSZSH);
unsigned sss = (s & 0x003FC000) >> (17 - PSZSH);
int pixel = ((ttt | sss) >> 1);
uint8 alpha, c_r, c_g, c_b;
uint8 c_a, c_r, c_g, c_b;
uint32 *textureBuffer = (uint32 *)texture.getRawBuffer(pixel);
uint32 col = *textureBuffer;
alpha = (col >> textureFormat.aShift) & 0xFF;
c_a = (col >> textureFormat.aShift) & 0xFF;
c_r = (col >> textureFormat.rShift) & 0xFF;
c_g = (col >> textureFormat.gShift) & 0xFF;
c_b = (col >> textureFormat.bShift) & 0xFF;
if (alpha == 0xFF) {
tmp = rgb & 0xF81F07E0;
if (c_a == 0xFF) {
tmp = rgba & 0xF81F07E0;
unsigned int light = tmp | (tmp >> 16);
unsigned int l_r = (light & 0xF800) >> 8;
unsigned int l_g = (light & 0x07E0) >> 3;
unsigned int l_b = (light & 0x001F) << 3;
unsigned int l_a = (a / 256);
c_a = (c_a * l_a) / 256;
c_r = (c_r * l_r) / 256;
c_g = (c_g * l_g) / 256;
c_b = (c_b * l_b) / 256;
buffer->writePixel(buf + _a,c_r, c_g, c_b);
buffer->writePixel(buf + _a, c_a, c_r, c_g, c_b);
pz[_a] = z;
} else if (c_a != 0) { // Implementing non binary alpha blending.
tmp = rgba & 0xF81F07E0;
unsigned int light = tmp | (tmp >> 16);
unsigned int l_r = (light & 0xF800) >> 8;
unsigned int l_g = (light & 0x07E0) >> 3;
unsigned int l_b = (light & 0x001F) << 3;
unsigned int l_a = (a / 256);
c_a = (c_a * l_a) / 256;
c_r = (c_r * l_r) / 256;
c_g = (c_g * l_g) / 256;
c_b = (c_b * l_b) / 256;
buffer->writePixel(buf + _a, c_a, c_r, c_g, c_b);
pz[_a] = z;
}
}
z += dzdx;
s += dsdx;
t += dtdx;
rgb = (rgb + drgbdx) & (~0x00200800);
a += dadx;
rgba = (rgba + drgbdx) & (~0x00200800);
}
template <bool interpRGB, bool interpZ, bool interpST, bool interpSTZ, int drawLogic>
@ -109,6 +132,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
int r1 = 0, drdx = 0, drdy = 0, drdl_min = 0, drdl_max = 0;
int g1 = 0, dgdx = 0, dgdy = 0, dgdl_min = 0, dgdl_max = 0;
int b1 = 0, dbdx = 0, dbdy = 0, dbdl_min = 0, dbdl_max = 0;
int a1 = 0, dadx = 0, dady = 0, dadl_min = 0, dadl_max = 0;
int s1 = 0, dsdx = 0, dsdy = 0, dsdl_min = 0, dsdl_max = 0;
int t1 = 0, dtdx = 0, dtdy = 0, dtdl_min = 0, dtdl_max = 0;
@ -173,6 +197,11 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
d2 = (float)(p2->b - p0->b);
dbdx = (int)(fdy2 * d1 - fdy1 * d2);
dbdy = (int)(fdx1 * d2 - fdx2 * d1);
d1 = (float)(p1->a - p0->a);
d2 = (float)(p2->a - p0->a);
dadx = (int)(fdy2 * d1 - fdy1 * d2);
dady = (int)(fdx1 * d2 - fdx2 * d1);
}
if (interpST) {
@ -211,7 +240,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
}
// screen coordinates
int pp1 = xsize * p0->y;
pz1 = zbuf + p0->y * xsize;
@ -320,6 +349,10 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
b1 = l1->b;
dbdl_min = (dbdy + dbdx * dxdy_min);
dbdl_max = dbdl_min + dbdx;
a1 = l1->a;
dadl_min = (dady + dadx * dxdy_min);
dadl_max = dadl_min + dadx;
}
if (interpST) {
@ -360,8 +393,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
nb_lines--;
{
switch (drawLogic) {
case DRAW_DEPTH_ONLY:
case DRAW_FLAT:
case DRAW_DEPTH_ONLY:
case DRAW_FLAT:
case DRAW_MAPPING: {
int pp;
int n;
@ -510,7 +543,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
break;
case DRAW_MAPPING_PERSPECTIVE: {
unsigned int *pz;
unsigned int s, t, z, rgb, drgbdx;
unsigned int s, t, z, rgb, a, drgbdx;
int n;
float sz, tz, fz, zinv;
n = (x2 >> 16) - x1;
@ -526,6 +559,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
rgb = (r1 << 16) & 0xFFC00000;
rgb |= (g1 >> 5) & 0x000007FF;
rgb |= (b1 << 5) & 0x001FF000;
a = a1;
drgbdx = _drgbdx;
while (n >= (NB_INTERP - 1)) {
{
@ -540,7 +574,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
zinv = (float)(1.0 / fz);
}
for (int _a = 0; _a < 8; _a++) {
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, _a, z, t, s, tmp, rgb, dzdx, dsdx, dtdx, drgbdx);
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, _a, z, t, s, tmp, rgb, a, dzdx,
dsdx, dtdx, drgbdx, dadx);
}
pz += NB_INTERP;
buf += NB_INTERP;
@ -560,7 +595,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
}
while (n >= 0) {
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, 0, z, t, s, tmp, rgb, dzdx, dsdx, dtdx, drgbdx);
putPixelMappingPerspective(this, buf, textureFormat, texture, pz, 0, z, t, s, tmp, rgb, a, dzdx,
dsdx, dtdx, drgbdx, dadx);
pz += 1;
buf += 1;
n -= 1;
@ -585,6 +621,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
r1 += drdl_max;
g1 += dgdl_max;
b1 += dbdl_max;
a1 += dadl_max;
}
if (interpST) {
@ -605,6 +642,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
r1 += drdl_min;
g1 += dgdl_min;
b1 += dbdl_min;
a1 += dadl_min;
}
if (interpST) {
s1 += dsdl_min;
@ -643,7 +681,7 @@ void FrameBuffer::fillTriangleFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPo
const bool interpRGB = false;
const bool interpST = false;
const bool interpSTZ = false;
fillTriangle<interpRGB, interpZ ,interpST, interpSTZ, DRAW_FLAT>(p0, p1, p2);
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT>(p0, p1, p2);
}
// Smooth filled triangle.