TINYGL: Implemented alpha blending and color transformation in sprite blitting for Grim TinyGL renderer.
This commit is contained in:
parent
63fd685589
commit
109767e513
10 changed files with 197 additions and 273 deletions
|
@ -636,12 +636,11 @@ void GfxTinyGL::startActorDraw(const Actor *actor) {
|
|||
tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||
}
|
||||
|
||||
// FIXME: TinyGL doesn't seem to support translucency.
|
||||
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();
|
||||
|
@ -686,7 +685,7 @@ void GfxTinyGL::startActorDraw(const Actor *actor) {
|
|||
}
|
||||
|
||||
if (actor->getSortOrder() >= 100) {
|
||||
tglColorMask(false, false, false, false);
|
||||
tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,9 +697,8 @@ void GfxTinyGL::finishActorDraw() {
|
|||
tglMatrixMode(TGL_MODELVIEW);
|
||||
tglDisable(TGL_TEXTURE_2D);
|
||||
|
||||
// FIXME: TinyGL doesn't seem to support translucency.
|
||||
if (_alpha < 1.f) {
|
||||
tglDisable(TGL_BLEND);
|
||||
tglDisable(TGL_BLEND);
|
||||
_alpha = 1.f;
|
||||
}
|
||||
|
||||
|
@ -823,6 +821,8 @@ void GfxTinyGL::drawEMIModelFace(const EMIModel *model, const EMIMeshFace *face)
|
|||
tglEnable(TGL_TEXTURE_2D);
|
||||
tglEnable(TGL_DEPTH_TEST);
|
||||
tglEnable(TGL_ALPHA_TEST);
|
||||
tglDisable(TGL_BLEND);
|
||||
tglColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void GfxTinyGL::drawModelFace(const Mesh *mesh, const MeshFace *face) {
|
||||
|
@ -837,7 +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);
|
||||
tglColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
tglVertex3fv(vertices + 3 * face->getVertex(i));
|
||||
}
|
||||
tglEnd();
|
||||
|
@ -884,9 +884,9 @@ void GfxTinyGL::drawSprite(const Sprite *sprite) {
|
|||
}
|
||||
|
||||
if (sprite->_blendMode == Sprite::BlendAdditive) {
|
||||
//tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE);
|
||||
tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE);
|
||||
} else {
|
||||
//tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
|
||||
tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
tglDisable(TGL_LIGHTING);
|
||||
|
@ -955,7 +955,8 @@ void GfxTinyGL::drawSprite(const Sprite *sprite) {
|
|||
tglEnable(TGL_LIGHTING);
|
||||
tglDisable(TGL_ALPHA_TEST);
|
||||
//tglDepthMask(GL_TRUE);
|
||||
//tglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
|
||||
tglDisable(TGL_BLEND);
|
||||
tglEnable(TGL_DEPTH_TEST);
|
||||
|
||||
tglPopMatrix();
|
||||
|
@ -1063,7 +1064,7 @@ 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 ) {
|
||||
void GfxTinyGL::blitScreen(const Graphics::PixelFormat &format, BlitImage *image, byte *src, int x, int y, int width, int height, bool trans, bool dimSprites) {
|
||||
int srcX, srcY;
|
||||
|
||||
if (x < 0) {
|
||||
|
@ -1080,7 +1081,7 @@ void GfxTinyGL::blitScreen( const Graphics::PixelFormat &format, BlitImage *imag
|
|||
srcY = 0;
|
||||
}
|
||||
|
||||
blitScreen(format, image, src, x, y, srcX, srcY, width, height, width, height, trans);
|
||||
blitScreen(format, image, src, x, y, srcX, srcY, width, height, width, height, trans, dimSprites);
|
||||
}
|
||||
|
||||
void GfxTinyGL::blit(const Graphics::PixelFormat &format, BlitImage *image, byte *dst, byte *src, int x, int y, int width, int height, bool trans) {
|
||||
|
@ -1146,9 +1147,9 @@ void GfxTinyGL::blit(const Graphics::PixelFormat &format, BlitImage *image, byte
|
|||
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;
|
||||
int skipStart = (l->x < srcX) ? (srcX - l->x) : 0;
|
||||
length -= skipStart;
|
||||
int skipEnd = l->x + l->length > maxX ? l->x + l->length - maxX : 0;
|
||||
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);
|
||||
|
@ -1169,12 +1170,7 @@ 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");
|
||||
}
|
||||
|
||||
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, bool dimSprites) {
|
||||
if (dstX >= _gameWidth || dstY >= _gameHeight)
|
||||
return;
|
||||
|
||||
|
@ -1190,49 +1186,69 @@ void GfxTinyGL::blitScreen( const Graphics::PixelFormat &format, BlitImage *imag
|
|||
else
|
||||
clampHeight = height;
|
||||
|
||||
byte *dst = _zb->getPixelBuffer();
|
||||
dst += (dstX + (dstY * _gameWidth)) * format.bytesPerPixel;
|
||||
int blendEnabled;
|
||||
tglGetIntegerv(TGL_BLEND, &blendEnabled);
|
||||
src += (srcX + (srcY * srcWidth)) * format.bytesPerPixel;
|
||||
|
||||
Graphics::PixelBuffer srcBuf(format, src);
|
||||
Graphics::PixelBuffer dstBuf(format, dst);
|
||||
bool hasDim = _dimLevel > 0.0f;
|
||||
dimSprites &= hasDim;
|
||||
|
||||
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 {
|
||||
if ((trans == false || blendEnabled == false) && (dimSprites == false)) {
|
||||
byte *dst = _zb->getPixelBuffer();
|
||||
dst += (dstX + (dstY * _gameWidth)) * format.bytesPerPixel;
|
||||
Graphics::PixelBuffer dstBuf(format, dst);
|
||||
if (!trans) {
|
||||
for (int l = 0; l < clampHeight; l++) {
|
||||
for (int r = 0; r < clampWidth; ++r) {
|
||||
if (srcBuf.getValueAt(r) != 0xf81f) {
|
||||
dstBuf.setPixelAt(r, srcBuf);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float colFactor = 1.0f - _dimLevel;
|
||||
if (dimSprites == false) {
|
||||
colFactor = 1.0f;
|
||||
}
|
||||
for (int l = 0; l < clampHeight; l++) {
|
||||
for (int r = 0; r < clampWidth; ++r) {
|
||||
byte aDst, rDst, gDst, bDst;
|
||||
srcBuf.getARGBAt(r, aDst, rDst, gDst, bDst);
|
||||
if (rDst == 248 && gDst == 0 && bDst == 248)
|
||||
continue;
|
||||
_zb->writePixel((dstX + r) + (dstY + l) * _gameWidth, aDst, rDst * colFactor, gDst * colFactor, bDst * colFactor);
|
||||
}
|
||||
srcBuf.shiftBy(srcWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1264,7 +1280,7 @@ void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
|
|||
int srcY = texc[ntex + 3] * bitmap->getHeight();
|
||||
|
||||
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);
|
||||
x + dx1, y + dy1, srcX, srcY, dx2 - dx1, dy2 - dy1, b[texId]._width, b[texId]._height, true, true);
|
||||
ntex += 16;
|
||||
}
|
||||
}
|
||||
|
@ -1284,7 +1300,7 @@ void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
|
|||
|
||||
if (bitmap->getFormat() == 1)
|
||||
blitScreen(bitmap->getPixelFormat(num), &b[num], (byte *)bitmap->getData(num).getRawBuffer(),
|
||||
x, y, bitmap->getWidth(), bitmap->getHeight(), true);
|
||||
x, y, bitmap->getWidth(), bitmap->getHeight(), true, false);
|
||||
else
|
||||
blit(bitmap->getPixelFormat(num), nullptr, (byte *)_zb->zbuf, (byte *)bitmap->getData(num).getRawBuffer(),
|
||||
x, y, bitmap->getWidth(), bitmap->getHeight(), false);
|
||||
|
@ -1391,7 +1407,7 @@ void GfxTinyGL::drawTextObject(const TextObject *text) {
|
|||
if (userData) {
|
||||
int numLines = text->getNumLines();
|
||||
for (int i = 0; i < numLines; ++i) {
|
||||
blitScreen(_pixelFormat, nullptr, 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, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1469,9 +1485,9 @@ void GfxTinyGL::selectMaterial(const Texture *material) {
|
|||
TGLuint *textures = (TGLuint *)material->_texture;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[0]);
|
||||
|
||||
/*if (material->_hasAlpha && g_grim->getGameType() == GType_MONKEY4) {
|
||||
if (material->_hasAlpha && g_grim->getGameType() == GType_MONKEY4) {
|
||||
tglEnable(TGL_BLEND);
|
||||
}*/
|
||||
}
|
||||
|
||||
// Grim has inverted tex-coords, EMI doesn't
|
||||
if (g_grim->getGameType() != GType_MONKEY4) {
|
||||
|
@ -1502,7 +1518,7 @@ void GfxTinyGL::drawMovieFrame(int offsetX, int offsetY) {
|
|||
if (_smushWidth == _gameWidth && _smushHeight == _gameHeight) {
|
||||
_zb->copyFromBuffer(_smushBitmap);
|
||||
} else {
|
||||
blitScreen(_pixelFormat, nullptr, _smushBitmap.getRawBuffer(), offsetX, offsetY, _smushWidth, _smushHeight, false);
|
||||
blitScreen(_pixelFormat, nullptr, _smushBitmap.getRawBuffer(), offsetX, offsetY, _smushWidth, _smushHeight, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,8 +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);
|
||||
void blitScreen(const Graphics::PixelFormat &format, BlitImage *blit, byte *src, int x, int y, int width, int height, bool trans, bool dimSprites);
|
||||
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, bool dimSprites);
|
||||
};
|
||||
|
||||
} // end of namespace Grim
|
||||
|
|
|
@ -28,6 +28,9 @@ void tglGetIntegerv(int pname, int *params) {
|
|||
case TGL_MAX_TEXTURE_STACK_DEPTH:
|
||||
*params = MAX_TEXTURE_STACK_DEPTH;
|
||||
break;
|
||||
case TGL_BLEND:
|
||||
*params = c->enableBlend;
|
||||
break;
|
||||
default:
|
||||
error("glGet: option not implemented");
|
||||
break;
|
||||
|
|
|
@ -126,7 +126,7 @@ void glInit(void *zbuffer1) {
|
|||
c->render_mode = TGL_RENDER;
|
||||
c->select_buffer = NULL;
|
||||
c->name_stack_size = 0;
|
||||
c->enable_blend = false;
|
||||
c->enableBlend = false;
|
||||
|
||||
// matrix
|
||||
c->matrix_mode = 0;
|
||||
|
@ -146,6 +146,7 @@ void glInit(void *zbuffer1) {
|
|||
tglLoadIdentity();
|
||||
tglMatrixMode(TGL_MODELVIEW);
|
||||
tglLoadIdentity();
|
||||
tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
c->matrix_model_projection_updated = 1;
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ void glopEnableDisable(GLContext *c, GLParam *p) {
|
|||
c->depth_test = v;
|
||||
break;
|
||||
case TGL_BLEND:
|
||||
c->enableBlend = v;
|
||||
c->fb->enableBlending(v);
|
||||
break;
|
||||
case TGL_POLYGON_OFFSET_FILL:
|
||||
|
@ -107,7 +108,7 @@ void glopEnableDisable(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);
|
||||
c->fb->setBlendingFactors(sfactor, dfactor);
|
||||
}
|
||||
|
||||
void glopShadeModel(GLContext *c, GLParam *p) {
|
||||
|
|
|
@ -162,13 +162,13 @@ void FrameBuffer::setTexture(const Graphics::PixelBuffer &texture) {
|
|||
current_texture = texture;
|
||||
}
|
||||
|
||||
void FrameBuffer::setBlendingFactors(int sfactor, int dfactor) {
|
||||
_sourceBlendingFactor = sfactor;
|
||||
_destinationBlendingFactor = dfactor;
|
||||
void FrameBuffer::setBlendingFactors(int sFactor, int dFactor) {
|
||||
_sourceBlendingFactor = sFactor;
|
||||
_destinationBlendingFactor = dFactor;
|
||||
}
|
||||
|
||||
void FrameBuffer::enableBlending(bool enableBlending) {
|
||||
_blendingEnabled = enableBlending;
|
||||
void FrameBuffer::enableBlending(bool enable) {
|
||||
_blendingEnabled = enable;
|
||||
}
|
||||
|
||||
} // end of namespace TinyGL
|
||||
|
|
|
@ -71,202 +71,124 @@ struct FrameBuffer {
|
|||
this->pbuf.setPixelAt(pixel, value);
|
||||
} else {
|
||||
byte rSrc, gSrc, bSrc, aSrc;
|
||||
this->pbuf.getFormat().colorToARGB(value, aSrc, rSrc, gSrc, bSrc);
|
||||
writePixel(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE void writePixel(int pixel, byte rSrc, byte gSrc, byte bSrc) {
|
||||
writePixel(pixel, 255, rSrc, gSrc, bSrc);
|
||||
}
|
||||
|
||||
FORCEINLINE void writePixel(int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc) {
|
||||
if (_blendingEnabled == false) {
|
||||
this->pbuf.setPixelAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||
} else {
|
||||
byte rDst, gDst, bDst, aDst;
|
||||
this->pbuf.getFormat().colorToARGB(value, aDst, rDst, gDst, bDst);
|
||||
this->pbuf.getARGBAt(pixel, aDst, rDst, gDst, bDst);
|
||||
switch (_sourceBlendingFactor) {
|
||||
case TGL_ZERO:
|
||||
rSrc = gSrc = bSrc = 0;
|
||||
break;
|
||||
case TGL_ONE:
|
||||
break;
|
||||
case TGL_DST_COLOR:
|
||||
rSrc = (rDst * rSrc) >> 8;
|
||||
gSrc = (gDst * gSrc) >> 8;
|
||||
bSrc = (bDst * bSrc) >> 8;
|
||||
break;
|
||||
case TGL_ONE_MINUS_DST_COLOR:
|
||||
rSrc = (rSrc * (255 - rDst)) >> 8;
|
||||
gSrc = (gSrc * (255 - gDst)) >> 8;
|
||||
bSrc = (bSrc * (255 - bDst)) >> 8;
|
||||
break;
|
||||
case TGL_SRC_ALPHA:
|
||||
rSrc = (rSrc * aSrc) >> 8;
|
||||
gSrc = (gSrc * aSrc) >> 8;
|
||||
bSrc = (bSrc * aSrc) >> 8;
|
||||
break;
|
||||
case TGL_ONE_MINUS_SRC_ALPHA:
|
||||
rSrc = (rSrc * (255 - aSrc)) >> 8;
|
||||
gSrc = (gSrc * (255 - aSrc)) >> 8;
|
||||
bSrc = (bSrc * (255 - aSrc)) >> 8;
|
||||
break;
|
||||
case TGL_DST_ALPHA:
|
||||
rSrc = (rSrc * aDst) >> 8;
|
||||
gSrc = (gSrc * aDst) >> 8;
|
||||
bSrc = (bSrc * aDst) >> 8;
|
||||
break;
|
||||
case TGL_ONE_MINUS_DST_ALPHA:
|
||||
rSrc = (rSrc * (255 - aDst)) >> 8;
|
||||
gSrc = (gSrc * (255 - aDst)) >> 8;
|
||||
bSrc = (bSrc * (255 - aDst)) >> 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_destinationBlendingFactor) {
|
||||
case TGL_ZERO:
|
||||
rDst = gDst = bDst = 0;
|
||||
break;
|
||||
case TGL_ONE:
|
||||
break;
|
||||
case TGL_DST_COLOR:
|
||||
this->pbuf.getRGBAt(pixel, rSrc, gSrc, bSrc);
|
||||
rDst = (rSrc * rDst) >> 8;
|
||||
gDst = (gSrc * gDst) >> 8;
|
||||
bDst = (bSrc * bDst) >> 8;
|
||||
rDst = (rDst * rSrc) >> 8;
|
||||
gDst = (gDst * gSrc) >> 8;
|
||||
bDst = (bDst * bSrc) >> 8;
|
||||
break;
|
||||
case TGL_ONE_MINUS_DST_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:
|
||||
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_SRC_ALPHA:
|
||||
this->pbuf.getARGBAt(pixel, aSrc, rSrc, gSrc, bSrc);
|
||||
case TGL_ONE_MINUS_DST_ALPHA:
|
||||
rDst = (rDst * (255 - aDst)) >> 8;
|
||||
gDst = (gDst * (255 - aDst)) >> 8;
|
||||
bDst = (bDst * (255 - aDst)) >> 8;
|
||||
break;
|
||||
case TGL_DST_ALPHA:
|
||||
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;
|
||||
int factor = aSrc < 1 - aDst ? aSrc : 1 - aDst;
|
||||
rDst = (rDst * factor) >> 8;
|
||||
gDst = (gDst * factor) >> 8;
|
||||
bDst = (bDst * factor) >> 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
int finalR, finalG, finalB;
|
||||
finalR = rDst + rSrc;
|
||||
finalG = gDst + gSrc;
|
||||
finalB = bDst + bSrc;
|
||||
if (finalR > 255) { finalR = 255; }
|
||||
if (finalG > 255) { finalG = 255; }
|
||||
if (finalB > 255) { finalB = 255; }
|
||||
this->pbuf.setPixelAt(pixel, 255, finalR, finalG, finalB);
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE void writePixel(int pixel, byte rDst, byte gDst, byte bDst) {
|
||||
writePixel(pixel, 255, rDst, gDst, bDst);
|
||||
void copyToBuffer(Graphics::PixelBuffer &buf) {
|
||||
buf.copyBuffer(0, xsize * ysize, pbuf);
|
||||
}
|
||||
|
||||
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_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_DST_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 * 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 - aDst)) >> 8;
|
||||
gDst = (gDst * (255 - aDst)) >> 8;
|
||||
bDst = (bDst * (255 - aDst)) >> 8;
|
||||
break;
|
||||
case TGL_DST_ALPHA:
|
||||
break;
|
||||
case TGL_ONE_MINUS_DST_ALPHA:
|
||||
rDst = gDst = bDst = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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 copyFromBuffer(Graphics::PixelBuffer buf) {
|
||||
pbuf.copyBuffer(0, xsize * ysize, buf);
|
||||
}
|
||||
|
||||
void enableBlending(bool enableBlending);
|
||||
|
|
|
@ -209,7 +209,7 @@ struct GLContext {
|
|||
gl_draw_triangle_func draw_triangle_front, draw_triangle_back;
|
||||
|
||||
// selection
|
||||
bool enable_blend;
|
||||
bool enableBlend;
|
||||
int render_mode;
|
||||
unsigned int *select_buffer;
|
||||
int select_size;
|
||||
|
|
|
@ -75,7 +75,7 @@ FORCEINLINE static void drawLine(FrameBuffer *buffer, ZBufferPoint *p1, ZBufferP
|
|||
|
||||
template <bool interpRGB, bool interpZ>
|
||||
void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
||||
int dx, dy, sx, pp;
|
||||
int dx, dy, sx;
|
||||
unsigned int r, g, b;
|
||||
unsigned int *pz = NULL;
|
||||
unsigned int z;
|
||||
|
@ -105,20 +105,16 @@ void FrameBuffer::fillLine(ZBufferPoint *p1, ZBufferPoint *p2, int color) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,33 +72,18 @@ FORCEINLINE static void putPixelMappingPerspective(FrameBuffer *buffer, int buf,
|
|||
c_r = (col >> textureFormat.rShift) & 0xFF;
|
||||
c_g = (col >> textureFormat.gShift) & 0xFF;
|
||||
c_b = (col >> textureFormat.bShift) & 0xFF;
|
||||
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_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;
|
||||
}
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue