TINYGL,GRIM: Replace custom shadows to stencil buffer solution
This commit is contained in:
parent
0e4075ff77
commit
c66ca22cbb
15 changed files with 77 additions and 265 deletions
|
@ -48,7 +48,7 @@
|
|||
namespace Grim {
|
||||
|
||||
Shadow::Shadow() :
|
||||
shadowMask(nullptr), shadowMaskSize(0), active(false), dontNegate(false), userData(nullptr) {
|
||||
active(false), dontNegate(false), userData(nullptr) {
|
||||
}
|
||||
|
||||
static int animTurn(float turnAmt, const Math::Angle &dest, Math::Angle *cur) {
|
||||
|
@ -222,8 +222,7 @@ void Actor::saveState(SaveGame *savedState) const {
|
|||
savedState->writeString(p.sector->getName());
|
||||
}
|
||||
|
||||
savedState->writeLESint32(shadow.shadowMaskSize);
|
||||
savedState->write(shadow.shadowMask, shadow.shadowMaskSize);
|
||||
savedState->writeLESint32(0);
|
||||
savedState->writeBool(shadow.active);
|
||||
savedState->writeBool(shadow.dontNegate);
|
||||
}
|
||||
|
@ -406,13 +405,9 @@ bool Actor::restoreState(SaveGame *savedState) {
|
|||
}
|
||||
}
|
||||
|
||||
shadow.shadowMaskSize = savedState->readLESint32();
|
||||
delete[] shadow.shadowMask;
|
||||
if (shadow.shadowMaskSize > 0) {
|
||||
shadow.shadowMask = new byte[shadow.shadowMaskSize];
|
||||
savedState->read(shadow.shadowMask, shadow.shadowMaskSize);
|
||||
} else {
|
||||
shadow.shadowMask = nullptr;
|
||||
int shadowMaskSize = savedState->readLESint32();
|
||||
for (int s = 0; s < shadowMaskSize; s++) {
|
||||
savedState->readByte();
|
||||
}
|
||||
shadow.active = savedState->readBool();
|
||||
shadow.dontNegate = savedState->readBool();
|
||||
|
@ -1746,16 +1741,6 @@ bool Actor::updateTalk(uint frameTime) {
|
|||
}
|
||||
|
||||
void Actor::draw() {
|
||||
if (!g_driver->isHardwareAccelerated() && g_grim->getFlagRefreshShadowMask()) {
|
||||
for (int l = 0; l < MAX_SHADOWS; l++) {
|
||||
if (!_shadowArray[l].active)
|
||||
continue;
|
||||
g_driver->setShadow(&_shadowArray[l]);
|
||||
g_driver->drawShadowPlanes();
|
||||
g_driver->setShadow(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: if isAttached(), factor in the joint rotation as well.
|
||||
const Math::Vector3d &absPos = getWorldPos();
|
||||
if (!_costumeStack.empty()) {
|
||||
|
@ -1810,8 +1795,7 @@ void Actor::drawCostume(Costume *costume) {
|
|||
continue;
|
||||
g_driver->setShadow(&_shadowArray[l]);
|
||||
g_driver->setShadowMode();
|
||||
if (g_driver->isHardwareAccelerated())
|
||||
g_driver->drawShadowPlanes();
|
||||
g_driver->drawShadowPlanes();
|
||||
g_driver->startActorDraw(this);
|
||||
costume->draw();
|
||||
g_driver->finishActorDraw();
|
||||
|
@ -1923,9 +1907,6 @@ void Actor::clearShadowPlane(int i) {
|
|||
delete shadow->planeList.back().sector;
|
||||
shadow->planeList.pop_back();
|
||||
}
|
||||
delete[] shadow->shadowMask;
|
||||
shadow->shadowMaskSize = 0;
|
||||
shadow->shadowMask = nullptr;
|
||||
shadow->active = false;
|
||||
shadow->dontNegate = false;
|
||||
|
||||
|
|
|
@ -58,8 +58,6 @@ struct Shadow {
|
|||
Common::String name;
|
||||
Math::Vector3d pos;
|
||||
SectorListType planeList;
|
||||
byte *shadowMask;
|
||||
int shadowMaskSize;
|
||||
bool active;
|
||||
bool dontNegate;
|
||||
Color color;
|
||||
|
|
|
@ -297,7 +297,7 @@ bool GfxOpenGL::supportsShaders() {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void glShadowProjection(const Math::Vector3d &light, const Math::Vector3d &plane, const Math::Vector3d &normal, bool dontNegate) {
|
||||
static void shadowProjection(const Math::Vector3d &light, const Math::Vector3d &plane, const Math::Vector3d &normal, bool dontNegate) {
|
||||
// Based on GPL shadow projection example by
|
||||
// (c) 2002-2003 Phaetos <phaetos@gaffga.de>
|
||||
float d, c;
|
||||
|
@ -562,23 +562,18 @@ void GfxOpenGL::startActorDraw(const Actor *actor) {
|
|||
}
|
||||
|
||||
if (_currentShadowArray) {
|
||||
// TODO find out why shadowMask at device in woods is null
|
||||
if (!_currentShadowArray->shadowMask) {
|
||||
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
||||
_currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight;
|
||||
}
|
||||
Sector *shadowSector = _currentShadowArray->planeList.front().sector;
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
// glColor3f(0.0f, 1.0f, 0.0f); // debug draw color
|
||||
// glColor3f(0.0f, 1.0f, 0.0f); // debug draw color
|
||||
if (g_grim->getGameType() == GType_GRIM) {
|
||||
glColor3ub(_shadowColorR, _shadowColorG, _shadowColorB);
|
||||
} else {
|
||||
glColor3ub(_currentShadowArray->color.getRed(), _currentShadowArray->color.getGreen(), _currentShadowArray->color.getBlue());
|
||||
}
|
||||
glShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||
shadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||
}
|
||||
|
||||
const float alpha = actor->getEffectiveAlpha();
|
||||
|
|
|
@ -85,7 +85,7 @@ void GfxTinyGL::setupScreen(int screenW, int screenH) {
|
|||
|
||||
_pixelFormat = g_system->getScreenFormat();
|
||||
debug("INFO: TinyGL front buffer pixel format: %s", _pixelFormat.toString().c_str());
|
||||
TinyGL::createContext(screenW, screenH, _pixelFormat, 256, g_grim->getGameType() == GType_GRIM, ConfMan.getBool("dirtyrects"));
|
||||
TinyGL::createContext(screenW, screenH, _pixelFormat, 256, true, ConfMan.getBool("dirtyrects"));
|
||||
|
||||
_storedDisplay = new Graphics::Surface;
|
||||
_storedDisplay->create(_gameWidth, _gameHeight, _pixelFormat);
|
||||
|
@ -96,6 +96,10 @@ void GfxTinyGL::setupScreen(int screenW, int screenH) {
|
|||
tglLightModelfv(TGL_LIGHT_MODEL_AMBIENT, ambientSource);
|
||||
TGLfloat diffuseReflectance[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
tglMaterialfv(TGL_FRONT, TGL_DIFFUSE, diffuseReflectance);
|
||||
|
||||
tglClearStencil(0xff);
|
||||
tglStencilFunc(TGL_ALWAYS, 1, 0xff);
|
||||
tglStencilOp(TGL_REPLACE, TGL_REPLACE, TGL_REPLACE);
|
||||
}
|
||||
|
||||
const char *GfxTinyGL::getVideoDeviceName() {
|
||||
|
@ -161,7 +165,7 @@ Math::Matrix4 GfxTinyGL::getProjection() {
|
|||
}
|
||||
|
||||
void GfxTinyGL::clearScreen() {
|
||||
tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
|
||||
tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT | TGL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void GfxTinyGL::clearDepthBuffer() {
|
||||
|
@ -193,7 +197,7 @@ bool GfxTinyGL::supportsShaders() {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void tglShadowProjection(const Math::Vector3d &light, const Math::Vector3d &plane, const Math::Vector3d &normal, bool dontNegate) {
|
||||
static void shadowProjection(const Math::Vector3d &light, const Math::Vector3d &plane, const Math::Vector3d &normal, bool dontNegate) {
|
||||
// Based on GPL shadow projection example by
|
||||
// (c) 2002-2003 Phaetos <phaetos@gaffga.de>
|
||||
float d, c;
|
||||
|
@ -449,6 +453,7 @@ void GfxTinyGL::getActorScreenBBox(const Actor *actor, Common::Point &p1, Common
|
|||
void GfxTinyGL::startActorDraw(const Actor *actor) {
|
||||
_currentActor = actor;
|
||||
tglEnable(TGL_TEXTURE_2D);
|
||||
tglEnable(TGL_LIGHTING);
|
||||
tglMatrixMode(TGL_PROJECTION);
|
||||
tglPushMatrix();
|
||||
tglMatrixMode(TGL_MODELVIEW);
|
||||
|
@ -461,23 +466,18 @@ void GfxTinyGL::startActorDraw(const Actor *actor) {
|
|||
}
|
||||
|
||||
if (_currentShadowArray) {
|
||||
Sector *shadowSector = _currentShadowArray->planeList.front().sector;
|
||||
tglDepthMask(TGL_FALSE);
|
||||
// TODO find out why shadowMask at device in woods is null
|
||||
if (!_currentShadowArray->shadowMask) {
|
||||
_currentShadowArray->shadowMask = new byte[_gameWidth * _gameHeight];
|
||||
_currentShadowArray->shadowMaskSize = _gameWidth * _gameHeight;
|
||||
}
|
||||
assert(_currentShadowArray->shadowMask);
|
||||
//tglSetShadowColor(255, 255, 255);
|
||||
tglEnable(TGL_POLYGON_OFFSET_FILL);
|
||||
tglDisable(TGL_LIGHTING);
|
||||
tglDisable(TGL_TEXTURE_2D);
|
||||
// tglColor3f(0.0f, 1.0f, 0.0f); // debug draw color
|
||||
if (g_grim->getGameType() == GType_GRIM) {
|
||||
tglSetShadowColor(_shadowColorR, _shadowColorG, _shadowColorB);
|
||||
tglColor3ub(_shadowColorR, _shadowColorG, _shadowColorB);
|
||||
} else {
|
||||
tglSetShadowColor(_currentShadowArray->color.getRed(), _currentShadowArray->color.getGreen(), _currentShadowArray->color.getBlue());
|
||||
tglColor3ub(_currentShadowArray->color.getRed(), _currentShadowArray->color.getGreen(), _currentShadowArray->color.getBlue());
|
||||
}
|
||||
tglSetShadowMaskBuf(_currentShadowArray->shadowMask);
|
||||
SectorListType::iterator i = _currentShadowArray->planeList.begin();
|
||||
Sector *shadowSector = i->sector;
|
||||
tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||
shadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||
}
|
||||
|
||||
const float alpha = actor->getEffectiveAlpha();
|
||||
|
@ -537,19 +537,19 @@ void GfxTinyGL::finishActorDraw() {
|
|||
}
|
||||
|
||||
if (_currentShadowArray) {
|
||||
tglSetShadowMaskBuf(nullptr);
|
||||
tglEnable(TGL_LIGHTING);
|
||||
tglColor3f(1.0f, 1.0f, 1.0f);
|
||||
tglDisable(TGL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
tglDisable(TGL_CULL_FACE);
|
||||
}
|
||||
|
||||
tglColorMask(TGL_TRUE, TGL_TRUE, TGL_TRUE, TGL_TRUE);
|
||||
_currentActor = nullptr;
|
||||
}
|
||||
|
||||
void GfxTinyGL::drawShadowPlanes() {
|
||||
tglEnable(TGL_SHADOW_MASK_MODE);
|
||||
tglDepthMask(TGL_FALSE);
|
||||
tglPushMatrix();
|
||||
|
||||
|
@ -559,13 +559,14 @@ void GfxTinyGL::drawShadowPlanes() {
|
|||
tglTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
}
|
||||
|
||||
if (!_currentShadowArray->shadowMask) {
|
||||
_currentShadowArray->shadowMask = new byte[_gameWidth * _gameHeight];
|
||||
_currentShadowArray->shadowMaskSize = _gameWidth * _gameHeight;
|
||||
}
|
||||
memset(_currentShadowArray->shadowMask, 0, _gameWidth * _gameHeight);
|
||||
tglColorMask(TGL_FALSE, TGL_FALSE, TGL_FALSE, TGL_FALSE);
|
||||
tglDepthMask(TGL_FALSE);
|
||||
|
||||
tglEnable(TGL_STENCIL_TEST);
|
||||
tglDisable(TGL_LIGHTING);
|
||||
tglDisable(TGL_TEXTURE_2D);
|
||||
tglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
tglSetShadowMaskBuf(_currentShadowArray->shadowMask);
|
||||
_currentShadowArray->planeList.begin();
|
||||
for (SectorListType::iterator i = _currentShadowArray->planeList.begin(); i != _currentShadowArray->planeList.end(); ++i) {
|
||||
Sector *shadowSector = i->sector;
|
||||
|
@ -575,21 +576,20 @@ void GfxTinyGL::drawShadowPlanes() {
|
|||
}
|
||||
tglEnd();
|
||||
}
|
||||
tglSetShadowMaskBuf(nullptr);
|
||||
tglDisable(TGL_SHADOW_MASK_MODE);
|
||||
tglDepthMask(TGL_TRUE);
|
||||
|
||||
tglDisable(TGL_STENCIL_TEST);
|
||||
tglColorMask(TGL_TRUE, TGL_TRUE, TGL_TRUE, TGL_TRUE);
|
||||
|
||||
tglPopMatrix();
|
||||
}
|
||||
|
||||
void GfxTinyGL::setShadowMode() {
|
||||
GfxBase::setShadowMode();
|
||||
tglEnable(TGL_SHADOW_MODE);
|
||||
}
|
||||
|
||||
void GfxTinyGL::clearShadowMode() {
|
||||
GfxBase::clearShadowMode();
|
||||
tglDisable(TGL_SHADOW_MODE);
|
||||
|
||||
tglDepthMask(TGL_TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ The changes made from the original version of TinyGL 0.4 are:
|
|||
* Removed unneeded code.
|
||||
* Introduced second 32-bit z-buffer for 3d objects only,
|
||||
and kept 16-bit only for static z-buffer bitmaps.
|
||||
* Added support for drawing in shadow mode (generate mask and polygon shadow - ztriangle_shadow.cpp file).
|
||||
* Added support for reading in RGB/BGR-textures, although the only internal format is still RGB565
|
||||
* Added TGL_BGR/TGL_RGB definitions to gl.h, verifying against SDL_opengl.h that the values are ok.
|
||||
* Added additional functions missing, like glColor4ub. (To make the code similar with the GL-code we use)
|
||||
|
|
|
@ -182,10 +182,13 @@ void tglFrontFace(int mode) {
|
|||
|
||||
void tglColorMask(TGLboolean r, TGLboolean g, TGLboolean b, TGLboolean a) {
|
||||
TinyGL::GLContext *c = TinyGL::gl_get_context();
|
||||
TinyGL::GLParam p[2];
|
||||
TinyGL::GLParam p[5];
|
||||
|
||||
p[0].op = TinyGL::OP_ColorMask;
|
||||
p[1].i = (r << 24) | (g << 16) | (b << 8) | (a << 0);
|
||||
p[1].i = r;
|
||||
p[2].i = g;
|
||||
p[3].i = b;
|
||||
p[4].i = a;
|
||||
|
||||
c->gl_add_op(p);
|
||||
}
|
||||
|
@ -768,15 +771,3 @@ void tglDebug(int mode) {
|
|||
TinyGL::GLContext *c = TinyGL::gl_get_context();
|
||||
c->print_flag = mode;
|
||||
}
|
||||
|
||||
void tglSetShadowMaskBuf(unsigned char *buf) {
|
||||
TinyGL::GLContext *c = TinyGL::gl_get_context();
|
||||
c->shadow_mask_buf = buf;
|
||||
}
|
||||
|
||||
void tglSetShadowColor(unsigned char r, unsigned char g, unsigned char b) {
|
||||
TinyGL::GLContext *c = TinyGL::gl_get_context();
|
||||
c->shadow_color_r = r << 8;
|
||||
c->shadow_color_g = g << 8;
|
||||
c->shadow_color_b = b << 8;
|
||||
}
|
||||
|
|
|
@ -395,16 +395,8 @@ void GLContext::gl_draw_triangle_fill(GLContext *c, GLVertex *p0, GLVertex *p1,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (c->color_mask == 0) {
|
||||
// FIXME: Accept more than just 0 or 1.
|
||||
if (!c->color_mask_red && !c->color_mask_green && !c->color_mask_blue && !c->color_mask_alpha) {
|
||||
c->fb->fillTriangleDepthOnly(&p0->zp, &p1->zp, &p2->zp);
|
||||
}
|
||||
if (c->shadow_mode & 1) {
|
||||
assert(c->shadow_mask_buf);
|
||||
c->fb->fillTriangleFlatShadowMask(&p0->zp, &p1->zp, &p2->zp);
|
||||
} else if (c->shadow_mode & 2) {
|
||||
assert(c->shadow_mask_buf);
|
||||
c->fb->fillTriangleFlatShadow(&p0->zp, &p1->zp, &p2->zp);
|
||||
} else if (c->texture_2d_enabled && c->current_texture && c->current_texture->images[0].pixmap) {
|
||||
#ifdef TINYGL_PROFILE
|
||||
count_triangles_textured++;
|
||||
|
|
|
@ -858,9 +858,6 @@ void tglTexCoordPointer(TGLint size, TGLenum type, TGLsizei stride, const TGLvoi
|
|||
void tglPolygonOffset(TGLfloat factor, TGLfloat units);
|
||||
|
||||
// custom extensions
|
||||
void tglSetShadowMaskBuf(unsigned char *buf);
|
||||
void tglSetShadowColor(unsigned char r, unsigned char g, unsigned char b);
|
||||
void tglEnableDirtyRects(bool enable);
|
||||
void tglDebug(int mode);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -229,9 +229,6 @@ void GLContext::init(int screenW, int screenH, Graphics::PixelFormat pixelFormat
|
|||
offset_factor = 0.0f;
|
||||
offset_units = 0.0f;
|
||||
|
||||
// shadow mode
|
||||
shadow_mode = 0;
|
||||
|
||||
// clear the resize callback function pointer
|
||||
gl_resize_viewport = nullptr;
|
||||
|
||||
|
@ -240,7 +237,8 @@ void GLContext::init(int screenW, int screenH, Graphics::PixelFormat pixelFormat
|
|||
specbuf_used_counter = 0;
|
||||
specbuf_num_buffers = 0;
|
||||
|
||||
color_mask = (1 << 24) | (1 << 16) | (1 << 8) | (1 << 0);
|
||||
// color mask
|
||||
color_mask_red = color_mask_green = color_mask_blue = color_mask_alpha = true;
|
||||
|
||||
const int kDrawCallMemory = 5 * 1024 * 1024;
|
||||
|
||||
|
|
|
@ -115,18 +115,6 @@ void GLContext::glopEnableDisable(GLParam *p) {
|
|||
else
|
||||
offset_states &= ~TGL_OFFSET_LINE;
|
||||
break;
|
||||
case TGL_SHADOW_MASK_MODE:
|
||||
if (v)
|
||||
shadow_mode |= 1;
|
||||
else
|
||||
shadow_mode &= ~1;
|
||||
break;
|
||||
case TGL_SHADOW_MODE:
|
||||
if (v)
|
||||
shadow_mode |= 2;
|
||||
else
|
||||
shadow_mode &= ~2;
|
||||
break;
|
||||
default:
|
||||
if (code >= TGL_LIGHT0 && code < TGL_LIGHT0 + T_MAX_LIGHTS) {
|
||||
gl_enable_disable_light(code - TGL_LIGHT0, v);
|
||||
|
@ -217,7 +205,10 @@ void GLContext::glopPolygonOffset(GLParam *p) {
|
|||
}
|
||||
|
||||
void GLContext::glopColorMask(GLParam *p) {
|
||||
color_mask = p[1].i;
|
||||
color_mask_red = p[1].i == TGL_TRUE;
|
||||
color_mask_green = p[2].i == TGL_TRUE;
|
||||
color_mask_blue = p[3].i == TGL_TRUE;
|
||||
color_mask_alpha = p[4].i == TGL_TRUE;
|
||||
}
|
||||
|
||||
void GLContext::glopDepthMask(GLParam *p) {
|
||||
|
|
|
@ -73,8 +73,6 @@ namespace TinyGL {
|
|||
static const int DRAW_DEPTH_ONLY = 0;
|
||||
static const int DRAW_FLAT = 1;
|
||||
static const int DRAW_SMOOTH = 2;
|
||||
static const int DRAW_SHADOW_MASK = 3;
|
||||
static const int DRAW_SHADOW = 4;
|
||||
|
||||
struct Buffer {
|
||||
byte *pbuf;
|
||||
|
@ -318,10 +316,6 @@ private:
|
|||
template <bool kDepthWrite, bool kEnableScissor, bool kStencilEnabled>
|
||||
FORCEINLINE void putPixelDepth(FrameBuffer *buffer, int buf, unsigned int *pz, byte *ps, int _a, int x, int y, unsigned int &z, int &dzdx);
|
||||
|
||||
template <bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled>
|
||||
FORCEINLINE void putPixelShadow(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, int x, int y, unsigned int &z,
|
||||
unsigned int &r, unsigned int &g, unsigned int &b, int &dzdx, unsigned char *pm);
|
||||
|
||||
template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled>
|
||||
FORCEINLINE void putPixelTextureMappingPerspective(FrameBuffer *buffer, int buf, const Graphics::TexelBuffer *texture,
|
||||
unsigned int wrap_s, unsigned int wrap_t, unsigned int *pz, byte *ps, int _a,
|
||||
|
@ -500,16 +494,6 @@ public:
|
|||
_enableScissor = false;
|
||||
}
|
||||
|
||||
FORCEINLINE void setShadowMaskBuf(byte *shadowBuffer) {
|
||||
_shadowMaskBuf = shadowBuffer;
|
||||
}
|
||||
|
||||
FORCEINLINE void setShadowRGB(int r, int g, int b) {
|
||||
_shadowColorR = r;
|
||||
_shadowColorG = g;
|
||||
_shadowColorB = b;
|
||||
}
|
||||
|
||||
FORCEINLINE void enableBlending(bool enable) {
|
||||
_blendingEnabled = enable;
|
||||
}
|
||||
|
@ -621,8 +605,6 @@ public:
|
|||
void fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
void fillTriangleFlat(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
void fillTriangleSmooth(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
void fillTriangleFlatShadowMask(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
void fillTriangleFlatShadow(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
|
||||
void plot(ZBufferPoint *p);
|
||||
void fillLine(ZBufferPoint *p1, ZBufferPoint *p2);
|
||||
|
@ -670,10 +652,6 @@ private:
|
|||
|
||||
const Graphics::TexelBuffer *_currentTexture;
|
||||
unsigned int _wrapS, _wrapT;
|
||||
byte *_shadowMaskBuf;
|
||||
int _shadowColorR;
|
||||
int _shadowColorG;
|
||||
int _shadowColorB;
|
||||
bool _blendingEnabled;
|
||||
int _sourceBlendingFactor;
|
||||
int _destinationBlendingFactor;
|
||||
|
|
|
@ -454,19 +454,17 @@ RasterizationDrawCall::RasterizationState RasterizationDrawCall::captureState()
|
|||
state.offsetStates = c->offset_states;
|
||||
state.offsetFactor = c->offset_factor;
|
||||
state.offsetUnits = c->offset_units;
|
||||
state.shadowMaskBuf = c->shadow_mask_buf;
|
||||
state.shadowColorR = c->shadow_color_r;
|
||||
state.shadowColorG = c->shadow_color_g;
|
||||
state.shadowColorB = c->shadow_color_b;
|
||||
|
||||
state.cullFaceEnabled = c->cull_face_enabled;
|
||||
state.beginType = c->begin_type;
|
||||
state.colorMask = c->color_mask;
|
||||
state.colorMaskRed = c->color_mask_red;
|
||||
state.colorMaskGreen = c->color_mask_green;
|
||||
state.colorMaskBlue = c->color_mask_blue;
|
||||
state.colorMaskAlpha = c->color_mask_alpha;
|
||||
state.currentFrontFace = c->current_front_face;
|
||||
state.currentShadeModel = c->current_shade_model;
|
||||
state.polygonModeBack = c->polygon_mode_back;
|
||||
state.polygonModeFront = c->polygon_mode_front;
|
||||
state.shadowMode = c->shadow_mode;
|
||||
state.texture2DEnabled = c->texture_2d_enabled;
|
||||
state.texture = c->current_texture;
|
||||
state.wrapS = c->texture_wrap_s;
|
||||
|
@ -497,8 +495,6 @@ void RasterizationDrawCall::applyState(const RasterizationDrawCall::Rasterizatio
|
|||
c->fb->setOffsetStates(state.offsetStates);
|
||||
c->fb->setOffsetFactor(state.offsetFactor);
|
||||
c->fb->setOffsetUnits(state.offsetUnits);
|
||||
c->fb->setShadowMaskBuf(state.shadowMaskBuf);
|
||||
c->fb->setShadowRGB(state.shadowColorB, state.shadowColorG, state.shadowColorB);
|
||||
|
||||
c->blending_enabled = state.enableBlending;
|
||||
c->source_blending_factor = state.sfactor;
|
||||
|
@ -520,20 +516,18 @@ void RasterizationDrawCall::applyState(const RasterizationDrawCall::Rasterizatio
|
|||
c->offset_states = state.offsetStates;
|
||||
c->offset_factor = state.offsetFactor;
|
||||
c->offset_units = state.offsetUnits;
|
||||
c->shadow_mask_buf = state.shadowMaskBuf;
|
||||
c->shadow_color_r = state.shadowColorR;
|
||||
c->shadow_color_g = state.shadowColorG;
|
||||
c->shadow_color_b = state.shadowColorB;
|
||||
|
||||
c->lighting_enabled = state.lightingEnabled;
|
||||
c->cull_face_enabled = state.cullFaceEnabled;
|
||||
c->begin_type = state.beginType;
|
||||
c->color_mask = state.colorMask;
|
||||
c->color_mask_red = state.colorMaskRed;
|
||||
c->color_mask_green = state.colorMaskGreen;
|
||||
c->color_mask_blue = state.colorMaskBlue;
|
||||
c->color_mask_alpha = state.colorMaskAlpha;
|
||||
c->current_front_face = state.currentFrontFace;
|
||||
c->current_shade_model = state.currentShadeModel;
|
||||
c->polygon_mode_back = state.polygonModeBack;
|
||||
c->polygon_mode_front = state.polygonModeFront;
|
||||
c->shadow_mode = state.shadowMode;
|
||||
c->texture_2d_enabled = state.texture2DEnabled;
|
||||
c->current_texture = state.texture;
|
||||
c->texture_wrap_s = state.wrapS;
|
||||
|
@ -743,16 +737,17 @@ bool RasterizationDrawCall::RasterizationState::operator==(const RasterizationSt
|
|||
offsetStates == other.offsetStates &&
|
||||
offsetFactor == other.offsetFactor &&
|
||||
offsetUnits == other.offsetUnits &&
|
||||
shadowMaskBuf == other.shadowMaskBuf &&
|
||||
lightingEnabled == other.lightingEnabled &&
|
||||
cullFaceEnabled == other.cullFaceEnabled &&
|
||||
beginType == other.beginType &&
|
||||
colorMask == other.colorMask &&
|
||||
colorMaskRed == other.colorMaskRed &&
|
||||
colorMaskGreen == other.colorMaskGreen &&
|
||||
colorMaskBlue == other.colorMaskBlue &&
|
||||
colorMaskAlpha == other.colorMaskAlpha &&
|
||||
currentFrontFace == other.currentFrontFace &&
|
||||
currentShadeModel == other.currentShadeModel &&
|
||||
polygonModeBack == other.polygonModeBack &&
|
||||
polygonModeFront == other.polygonModeFront &&
|
||||
shadowMode == other.shadowMode &&
|
||||
texture2DEnabled == other.texture2DEnabled &&
|
||||
texture == other.texture &&
|
||||
textureVersion == texture->versionNumber &&
|
||||
|
|
|
@ -107,14 +107,13 @@ private:
|
|||
int beginType;
|
||||
int currentFrontFace;
|
||||
int cullFaceEnabled;
|
||||
int colorMask;
|
||||
bool colorMaskRed;
|
||||
bool colorMaskGreen;
|
||||
bool colorMaskBlue;
|
||||
bool colorMaskAlpha;
|
||||
bool depthTestEnabled;
|
||||
int depthFunction;
|
||||
int depthWriteMask;
|
||||
int shadowMode;
|
||||
int shadowColorR;
|
||||
int shadowColorG;
|
||||
int shadowColorB;
|
||||
bool texture2DEnabled;
|
||||
int currentShadeModel;
|
||||
int polygonModeBack;
|
||||
|
@ -142,7 +141,6 @@ private:
|
|||
int stencilDppass;
|
||||
TinyGL::GLTexture *texture;
|
||||
uint wrapS, wrapT;
|
||||
byte *shadowMaskBuf;
|
||||
|
||||
bool operator==(const RasterizationState &other) const;
|
||||
};
|
||||
|
|
|
@ -277,12 +277,6 @@ struct GLContext {
|
|||
int alpha_test_func;
|
||||
int alpha_test_ref_val;
|
||||
|
||||
// shadow
|
||||
unsigned char *shadow_mask_buf;
|
||||
int shadow_color_r;
|
||||
int shadow_color_g;
|
||||
int shadow_color_b;
|
||||
|
||||
// Internal texture size
|
||||
int _textureSize;
|
||||
|
||||
|
@ -397,8 +391,6 @@ struct GLContext {
|
|||
float offset_units;
|
||||
int offset_states;
|
||||
|
||||
int shadow_mode;
|
||||
|
||||
// specular buffer. could probably be shared between contexts,
|
||||
// but that wouldn't be 100% thread safe
|
||||
GLSpecBuf *specbuf_first;
|
||||
|
@ -425,7 +417,10 @@ struct GLContext {
|
|||
int stencil_dpfail;
|
||||
int stencil_dppass;
|
||||
|
||||
int color_mask;
|
||||
bool color_mask_red;
|
||||
bool color_mask_green;
|
||||
bool color_mask_blue;
|
||||
bool color_mask_alpha;
|
||||
|
||||
Common::Rect _scissorRect;
|
||||
|
||||
|
|
|
@ -98,17 +98,12 @@ FORCEINLINE void FrameBuffer::putPixelDepth(FrameBuffer *buffer, int buf, unsign
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (kDepthWrite && buffer->compareDepth(z, pz[_a])) {
|
||||
pz[_a] = z;
|
||||
bool depthTestResult = buffer->compareDepth(z, pz[_a]);
|
||||
if (kStencilEnabled) {
|
||||
stencilOp(true, depthTestResult, ps + _a);
|
||||
}
|
||||
z += dzdx;
|
||||
}
|
||||
|
||||
template <bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled>
|
||||
FORCEINLINE void FrameBuffer::putPixelShadow(FrameBuffer *buffer, int buf, unsigned int *pz, int _a, int x, int y, unsigned int &z,
|
||||
unsigned int &r, unsigned int &g, unsigned int &b, int &dzdx, unsigned char *pm) {
|
||||
if ((!kEnableScissor || !buffer->scissorPixel(x + _a, y)) && buffer->compareDepth(z, pz[_a]) && pm[_a]) {
|
||||
buffer->writePixel<kAlphaTestEnabled, kBlendingEnabled, kDepthWrite>(buf + _a, 255, r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8), z);
|
||||
if (kDepthWrite && depthTestResult) {
|
||||
pz[_a] = z;
|
||||
}
|
||||
z += dzdx;
|
||||
}
|
||||
|
@ -167,7 +162,6 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
|||
ZBufferPoint *tp, *pr1 = 0, *pr2 = 0, *l1 = 0, *l2 = 0;
|
||||
float fdx1, fdx2, fdy1, fdy2, fz0, d1, d2;
|
||||
uint *pz1 = nullptr;
|
||||
byte *pm1 = nullptr;
|
||||
byte *ps1 = nullptr;
|
||||
int part, update_left = 1, update_right = 1;
|
||||
|
||||
|
@ -299,15 +293,6 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
|||
}
|
||||
|
||||
switch (kDrawLogic) {
|
||||
case DRAW_SHADOW_MASK:
|
||||
pm1 = _shadowMaskBuf + p0->y * _pbufWidth;
|
||||
break;
|
||||
case DRAW_SHADOW:
|
||||
pm1 = _shadowMaskBuf + p0->y * _pbufWidth;
|
||||
r1 = _shadowColorR;
|
||||
g1 = _shadowColorG;
|
||||
b1 = _shadowColorB;
|
||||
break;
|
||||
case DRAW_DEPTH_ONLY:
|
||||
break;
|
||||
case DRAW_FLAT:
|
||||
|
@ -424,8 +409,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
|||
while (nb_lines > 0) {
|
||||
int x = x1;
|
||||
{
|
||||
if (kDrawLogic == DRAW_DEPTH_ONLY ||
|
||||
(kDrawLogic == DRAW_FLAT && !(kInterpST || kInterpSTZ))) {
|
||||
if (kDrawLogic == DRAW_DEPTH_ONLY || (kDrawLogic == DRAW_FLAT && !(kInterpST || kInterpSTZ))) {
|
||||
int pp;
|
||||
int n;
|
||||
unsigned int *pz;
|
||||
|
@ -489,62 +473,6 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
|||
n -= 1;
|
||||
x += 1;
|
||||
}
|
||||
} else if (kDrawLogic == DRAW_SHADOW_MASK) {
|
||||
unsigned char *pm;
|
||||
int n;
|
||||
|
||||
n = (x2 >> 16) - x1;
|
||||
pm = pm1 + x1;
|
||||
while (n >= 3) {
|
||||
pm[0] = 0xff;
|
||||
pm[1] = 0xff;
|
||||
pm[2] = 0xff;
|
||||
pm[3] = 0xff;
|
||||
pm += 4;
|
||||
n -= 4;
|
||||
x += 4;
|
||||
}
|
||||
while (n >= 0) {
|
||||
pm[0] = 0xff;
|
||||
pm += 1;
|
||||
n -= 1;
|
||||
x += 1;
|
||||
}
|
||||
} else if (kDrawLogic == DRAW_SHADOW) {
|
||||
unsigned char *pm;
|
||||
int n;
|
||||
unsigned int *pz;
|
||||
unsigned int z;
|
||||
unsigned int r = r1;
|
||||
unsigned int g = g1;
|
||||
unsigned int b = b1;
|
||||
|
||||
n = (x2 >> 16) - x1;
|
||||
|
||||
int buf = pp1 + x1;
|
||||
|
||||
pm = pm1 + x1;
|
||||
pz = pz1 + x1;
|
||||
z = z1;
|
||||
while (n >= 3) {
|
||||
putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, dzdx, pm);
|
||||
putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 1, x, y, z, r, g, b, dzdx, pm);
|
||||
putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 2, x, y, z, r, g, b, dzdx, pm);
|
||||
putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 3, x, y, z, r, g, b, dzdx, pm);
|
||||
pz += 4;
|
||||
pm += 4;
|
||||
buf += 4;
|
||||
n -= 4;
|
||||
x += 4;
|
||||
}
|
||||
while (n >= 0) {
|
||||
putPixelShadow<kDepthWrite, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled>(this, buf, pz, 0, x, y, z, r, g, b, dzdx, pm);
|
||||
pz += 1;
|
||||
pm += 1;
|
||||
buf += 1;
|
||||
n -= 1;
|
||||
x += 1;
|
||||
}
|
||||
} else if (kDrawLogic == DRAW_SMOOTH && !(kInterpST || kInterpSTZ)) {
|
||||
unsigned int *pz;
|
||||
byte *ps = nullptr;
|
||||
|
@ -708,8 +636,6 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
|
|||
ps1 += _pbufWidth;
|
||||
}
|
||||
|
||||
if (kDrawLogic == DRAW_SHADOW || kDrawLogic == DRAW_SHADOW_MASK)
|
||||
pm1 += _pbufWidth;
|
||||
nb_lines--;
|
||||
y++;
|
||||
}
|
||||
|
@ -817,26 +743,4 @@ void FrameBuffer::fillTriangleTextureMappingPerspectiveFlat(ZBufferPoint *p0, ZB
|
|||
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_FLAT, false>(p0, p1, p2);
|
||||
}
|
||||
|
||||
void FrameBuffer::fillTriangleFlatShadowMask(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
|
||||
const bool interpZ = true;
|
||||
const bool interpRGB = false;
|
||||
const bool interpST = false;
|
||||
const bool interpSTZ = false;
|
||||
if (_depthWrite && _depthTestEnabled)
|
||||
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW_MASK, true>(p0, p1, p2);
|
||||
else
|
||||
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW_MASK, false>(p0, p1, p2);
|
||||
}
|
||||
|
||||
void FrameBuffer::fillTriangleFlatShadow(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
|
||||
const bool interpZ = true;
|
||||
const bool interpRGB = false;
|
||||
const bool interpST = false;
|
||||
const bool interpSTZ = false;
|
||||
if (_depthWrite && _depthTestEnabled)
|
||||
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW, true>(p0, p1, p2);
|
||||
else
|
||||
fillTriangle<interpRGB, interpZ, interpST, interpSTZ, DRAW_SHADOW, false>(p0, p1, p2);
|
||||
}
|
||||
|
||||
} // end of namespace TinyGL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue