TINYGL: implemented tglDepthFunc

This commit is contained in:
Pawel Kolodziejski 2014-07-04 23:14:44 +02:00
parent 7370dcd635
commit 1b8dd28bc7
12 changed files with 84 additions and 21 deletions

View File

@ -236,6 +236,12 @@ GfxTinyGL::GfxTinyGL() :
_bufferId(0), _currentActor(nullptr) {
g_driver = this;
_storedDisplay = nullptr;
// TGL_LEQUAL as tglDepthFunc ensures that subsequent drawing attempts for
// the same triangles are not ignored by the depth test.
// That's necessary for EMI where some models have multiple faces which
// refer to the same vertices. The first face is usually using the
// color map and the following are using textures.
_depthFunc = (g_grim->getGameType() == GType_MONKEY4) ? TGL_LEQUAL : TGL_LESS;
}
GfxTinyGL::~GfxTinyGL() {
@ -731,6 +737,7 @@ void GfxTinyGL::clearShadowMode() {
void GfxTinyGL::set3DMode() {
tglMatrixMode(TGL_MODELVIEW);
tglEnable(TGL_DEPTH_TEST);
tglDepthFunc(_depthFunc);
}
void GfxTinyGL::setShadow(Shadow *shadow) {

View File

@ -143,6 +143,7 @@ private:
Common::HashMap<int, TinyGL::Buffer *> _buffers;
uint _bufferId;
const Actor *_currentActor;
TGLenum _depthFunc;
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);

View File

@ -20,11 +20,13 @@ The changes made from the original version of TinyGL 0.4 are:
* struct structName instead of typedef struct {} structName;
* pass-by-const-reference instead of by-value when possible
* Changed the math-functions to use const-pointers if possible.
* Reformatted the source to use the same code-formatting conventions as the rest of ResidualVM (indentation-wise, not variable-naming wise)
* Reformatted the source to use the same code-formatting conventions as the rest of ResidualVM
(indentation-wise, not variable-naming wise)
* Refactored all the maths code in a C++ fashion, removed some unused functions.
* Heavily refactored the triangle and line drawing routines
* Renamed ZBuffer into FrameBuffer and moved all the external C functions as member functions.
* Added implementation of glBlendFunc and support for 8-bit alpha.
* Added implementation of glAlphaTestFunc.
* Added implementation of tglBlendFunc and support for 8-bit alpha.
* Added implementation of tglAlphaTestFunc.
* Added implementation of tglDepthFunc.
For more information refer to log changes in github: https://github.com/residualvm/residualvm

View File

@ -195,6 +195,14 @@ void tglAlphaFunc(TGLenum func, float ref) {
TinyGL::gl_add_op(p);
}
void tglDepthFunc(TGLenum func) {
TinyGL::GLParam p[2];
p[0].op = TinyGL::OP_DepthFunc;
p[1].i = func;
TinyGL::gl_add_op(p);
}
void tglPolygonMode(int face, int mode) {
TinyGL::GLParam p[3];

View File

@ -799,6 +799,7 @@ void tglColorMask(TGLboolean r, TGLboolean g, TGLboolean b, TGLboolean a);
void tglDepthMask(int enableWrite);
void tglBlendFunc(TGLenum sfactor, TGLenum dfactor);
void tglAlphaFunc(TGLenum func, float ref);
void tglDepthFunc(TGLenum func);
void tglSetShadowMaskBuf(unsigned char *buf);
void tglSetShadowColor(unsigned char r, unsigned char g, unsigned char b);

View File

@ -156,6 +156,8 @@ void glInit(void *zbuffer1) {
tglAlphaFunc(TGL_ALWAYS, 0.f);
tglDepthFunc(TGL_LESS);
c->matrix_model_projection_updated = 1;
// opengl 1.1 arrays

View File

@ -121,6 +121,11 @@ void glopAlphaFunc(GLContext *c, GLParam *p) {
c->fb->setAlphaTestFunc(func, ref);
}
void glopDepthFunc(GLContext *c, GLParam *p) {
TGLenum func = p[1].i;
c->fb->setDepthFunc(func);
}
void glopShadeModel(GLContext *c, GLParam *p) {
int code = p[1].i;
c->current_shade_model = code;

View File

@ -53,6 +53,7 @@ ADD_OP(ColorMask, 1, "%08x")
ADD_OP(DepthMask, 1, "%d")
ADD_OP(BlendFunc, 2, "%d %d")
ADD_OP(AlphaFunc, 2, "%d %f")
ADD_OP(DepthFunc, 1, "%d")
ADD_OP(CallList, 1, "%d")
ADD_OP(Hint, 2, "%C %C")

View File

@ -181,4 +181,8 @@ void FrameBuffer::enableAlphaTest(bool enable) {
_alphaTestEnabled = enable;
}
void FrameBuffer::setDepthFunc(int func) {
_depthFunc = func;
}
} // end of namespace TinyGL

View File

@ -74,6 +74,40 @@ struct FrameBuffer {
pbuf.getRGBAt(pixel, r, g, b);
}
FORCEINLINE bool compareDepth(unsigned int &zSrc, unsigned int &zDst) {
switch (_depthFunc) {
case TGL_NEVER:
break;
case TGL_LESS:
if (zDst < zSrc)
return true;
break;
case TGL_EQUAL:
if (zDst == zSrc)
return true;
break;
case TGL_LEQUAL:
if (zDst <= zSrc)
return true;
break;
case TGL_GREATER:
if (zDst > zSrc)
return true;
break;
case TGL_NOTEQUAL:
if (zDst != zSrc)
return true;
break;
case TGL_GEQUAL:
if (zDst >= zSrc)
return true;
break;
case TGL_ALWAYS:
return true;
}
return false;
}
FORCEINLINE bool checkAlphaTest(byte aSrc) {
if (!_alphaTestEnabled)
return true;
@ -246,6 +280,7 @@ struct FrameBuffer {
void setBlendingFactors(int sfactor, int dfactor);
void enableAlphaTest(bool enable);
void setAlphaTestFunc(int func, float ref);
void setDepthFunc(int func);
void enableDepthWrite(bool enable) {
this->_depthWrite = enable;
}
@ -309,6 +344,7 @@ private:
bool _alphaTestEnabled;
int _alphaTestFunc;
int _alphaTestRefVal;
int _depthFunc;
};
// memory.c

View File

@ -3,14 +3,12 @@
namespace TinyGL {
#define ZCMP(z,zpix) ((z) >= (zpix))
template <bool interpRGB, bool interpZ, bool depthWrite>
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 (buffer->compareDepth(z, *pz)) {
if (interpRGB) {
buffer->writePixel(pixelOffset, RGB_TO_PIXEL(r >> 8, g >> 8, b >> 8));
} else {

View File

@ -4,8 +4,6 @@
namespace TinyGL {
#define ZCMP(z, zpix) ((z) >= (zpix))
static const int NB_INTERP = 8;
#define SAR_RND_TO_ZERO(v,n) (v / (1 << n))
@ -14,7 +12,7 @@ template <bool depthWrite>
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])) {
if (buffer->compareDepth(z, pz[_a])) {
buffer->writePixel(buf + _a, texture.getRawBuffer()[((t & 0x3FC00000) | s) >> 14]);
if (depthWrite) {
pz[_a] = z;
@ -28,7 +26,7 @@ FORCEINLINE static void putPixelMapping(FrameBuffer *buffer, int buf, unsigned i
template <bool depthWrite>
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])) {
if (buffer->compareDepth(z, pz[_a])) {
buffer->writePixel(buf + _a, color);
if (depthWrite) {
pz[_a] = z;
@ -38,8 +36,8 @@ FORCEINLINE static void putPixelFlat(FrameBuffer *buffer, int buf, unsigned int
}
template <bool depthWrite>
FORCEINLINE static void putPixelDepth(unsigned int *pz, int _a, unsigned int &z, int &dzdx) {
if (ZCMP(z, pz[_a])) {
FORCEINLINE static void putPixelDepth(FrameBuffer *buffer, unsigned int *pz, int _a, unsigned int &z, int &dzdx) {
if (buffer->compareDepth(z, pz[_a])) {
if (depthWrite) {
pz[_a] = z;
}
@ -50,7 +48,7 @@ FORCEINLINE static void putPixelDepth(unsigned int *pz, int _a, unsigned int &z,
template <bool depthWrite>
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])) {
if (buffer->compareDepth(z, pz[_a])) {
tmp = rgb & 0xF81F07E0;
buffer->writePixel(buf + _a, tmp | (tmp >> 16));
if (depthWrite) {
@ -66,7 +64,7 @@ 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])) {
if (buffer->compareDepth(z, pz[_a])) {
unsigned ttt = (t & 0x003FC000) >> (9 - PSZSH);
unsigned sss = (s & 0x003FC000) >> (17 - PSZSH);
int pixel = ((ttt | sss) >> 1);
@ -405,10 +403,10 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
}
while (n >= 3) {
if (drawLogic == DRAW_DEPTH_ONLY) {
putPixelDepth<depthWrite>(pz, 0, z, dzdx);
putPixelDepth<depthWrite>(pz, 1, z, dzdx);
putPixelDepth<depthWrite>(pz, 2, z, dzdx);
putPixelDepth<depthWrite>(pz, 3, z, dzdx);
putPixelDepth<depthWrite>(this, pz, 0, z, dzdx);
putPixelDepth<depthWrite>(this, pz, 1, z, dzdx);
putPixelDepth<depthWrite>(this, pz, 2, z, dzdx);
putPixelDepth<depthWrite>(this, pz, 3, z, dzdx);
}
if (drawLogic == DRAW_FLAT) {
putPixelFlat<depthWrite>(this, pp, pz, 0, z, color, dzdx);
@ -430,7 +428,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
}
while (n >= 0) {
if (drawLogic == DRAW_DEPTH_ONLY) {
putPixelDepth<depthWrite>(pz, 0, z, dzdx);
putPixelDepth<depthWrite>(this, pz, 0, z, dzdx);
}
if (drawLogic == DRAW_FLAT) {
putPixelFlat<depthWrite>(this, pp, pz, 0, z, color, dzdx);
@ -481,7 +479,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
z = z1;
while (n >= 3) {
for (int a = 0; a < 4; a++) {
if (ZCMP(z, pz[a]) && pm[0]) {
if (compareDepth(z, pz[a]) && pm[0]) {
writePixel(buf + a, color);
if (depthWrite) {
pz[a] = z;
@ -495,7 +493,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
n -= 4;
}
while (n >= 0) {
if (ZCMP(z, pz[0]) && pm[0]) {
if (compareDepth(z, pz[0]) && pm[0]) {
writePixel(buf, color);
if (depthWrite) {
pz[0] = z;