TINYGL,GRIM: Replace custom shadows to stencil buffer solution

This commit is contained in:
Paweł Kołodziejski 2021-12-10 18:37:24 +01:00
parent 0e4075ff77
commit c66ca22cbb
No known key found for this signature in database
GPG key ID: 0BDADC9E74440FF7
15 changed files with 77 additions and 265 deletions

View file

@ -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;

View file

@ -58,8 +58,6 @@ struct Shadow {
Common::String name;
Math::Vector3d pos;
SectorListType planeList;
byte *shadowMask;
int shadowMaskSize;
bool active;
bool dontNegate;
Color color;

View file

@ -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();

View file

@ -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);
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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++;

View file

@ -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

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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 &&

View file

@ -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;
};

View file

@ -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;

View file

@ -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