mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 09:36:21 +00:00
TINYGL: Implemented alpha interpolation in triangle rasterization routine.
This commit is contained in:
parent
03072c4b7b
commit
63fd685589
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user