diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 97c5c09fd..2eabff2a3 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -130,7 +130,7 @@ void FGLModelRenderer::SetInterpolation(double inter) void FGLModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation) { FMaterial * tex = FMaterial::ValidateTexture(skin, false); - gl_RenderState.SetMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1, false); + gl_RenderState.ApplyMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); gl_RenderState.Apply(); if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3117a0988..bf439c675 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -505,7 +505,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer) if (mat == nullptr) continue; if (gltrans == -1 && cmd.mTranslation != nullptr) gltrans = cmd.mTranslation->GetUniqueIndex(); - gl_RenderState.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1, cmd.mDrawMode == F2DDrawer::DTM_AlphaTexture); + gl_RenderState.ApplyMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1); gl_RenderState.EnableTexture(true); // Canvas textures are stored upside down diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 1a4515781..8b014641c 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -228,6 +228,12 @@ void FGLRenderState::Apply() } } + if (mMaterial.mChanged) + { + ApplyMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader); + mMaterial.mChanged = false; + } + if (mStencil.mChanged) { int recursion = GLRenderer->mPortalState.GetRecursion(); @@ -242,6 +248,21 @@ void FGLRenderState::Apply() else glEnable(GL_DEPTH_TEST); + mStencil.mChanged = false; + } + + if (mBias.mChanged) + { + if (mBias.mFactor == 0 && mBias.mUnits == 0) + { + glDisable(GL_POLYGON_OFFSET_FILL); + } + else + { + glEnable(GL_POLYGON_OFFSET_FILL); + } + glPolygonOffset(mBias.mFactor, mBias.mUnits); + mBias.mChanged = false; } if (mVertexBuffer != mCurrentVertexBuffer) @@ -257,6 +278,7 @@ void FGLRenderState::Apply() void FGLRenderState::ApplyLightIndex(int index) { + if (index == -2) index = mLightIndex; // temporary workaround so that both old and new code can be handled. if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER) { index = GLRenderer->mLights->BindUBO(index); @@ -270,7 +292,7 @@ void FGLRenderState::ApplyLightIndex(int index) // //=========================================================================== -void FGLRenderState::SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) +void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader) { if (mat->tex->bHasCanvas) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 0d70ef90a..ec220d901 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -99,7 +99,7 @@ public: lastMaterial = nullptr; } - void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture); + void ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader); void Apply(); void ApplyLightIndex(int index); @@ -233,14 +233,6 @@ public: return mPassType == GBUFFER_PASS ? 3 : 1; } - void ApplyMaterial() - { - if (mMaterial.mChanged) - { - SetMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader, false); - mMaterial.mChanged = false; - } - } }; extern FGLRenderState gl_RenderState; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 6ad9b0109..d7808635a 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -280,8 +280,8 @@ void FDrawInfo::Draw(EDrawType dt, FRenderState &state, int index, int count, bo assert(&state == &gl_RenderState); if (apply) { - gl_RenderState.ApplyMaterial(); gl_RenderState.Apply(); + gl_RenderState.ApplyLightIndex(-2); } drawcalls.Clock(); glDrawArrays(dt2gl[dt], index, count); @@ -293,8 +293,8 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co assert(&state == &gl_RenderState); if (apply) { - gl_RenderState.ApplyMaterial(); gl_RenderState.Apply(); + gl_RenderState.ApplyLightIndex(-2); } drawcalls.Clock(); glDrawElements(dt2gl[dt], count, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 36775c2dd..34eb2918c 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -123,15 +123,11 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool istrans) // Push bleeding floor/ceiling textures back a little in the z-buffer // so they don't interfere with overlapping mid textures. - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f, 128.0f); - + gl_RenderState.SetDepthBias(1, 128); SetupFloodStencil(fnode->vertexindex); Draw(DT_TriangleFan, gl_RenderState, fnode->vertexindex + 4, 4); ClearFloodStencil(fnode->vertexindex); - - glPolygonOffset(0.0f, 0.0f); - glDisable(GL_POLYGON_OFFSET_FILL); + gl_RenderState.SetDepthBias(0, 0); fnode = fnode->next; } @@ -203,16 +199,16 @@ void FDrawInfo::DrawFlat(GLFlat *flat, int pass, bool trans) // trans only has m gl_RenderState.SetObjectColor(flat->FlatColor | 0xff000000); if (flat->sector->special != GLSector_Skybox) { - gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false); + gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_NONE, 0, -1); gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture); DrawSubsectors(flat, pass, false); gl_RenderState.EnableTextureMatrix(false); } else { - gl_RenderState.SetMaterial(flat->gltexture, CLAMP_XY, 0, -1, false); - gl_RenderState.ApplyLightIndex(flat->dynlightindex); - glDrawArrays(GL_TRIANGLE_FAN, flat->iboindex, 4); + gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_XY, 0, -1); + gl_RenderState.SetLightIndex(flat->dynlightindex); + Draw(DT_TriangleFan, gl_RenderState, flat->iboindex, 4); flatvertices += 4; flatprimitives++; } @@ -236,7 +232,7 @@ void FDrawInfo::DrawFlat(GLFlat *flat, int pass, bool trans) // trans only has m { if (!flat->gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(Alpha_GEqual, gl_mask_threshold); else gl_RenderState.AlphaFunc(Alpha_GEqual, 0.f); - gl_RenderState.SetMaterial(flat->gltexture, CLAMP_NONE, 0, -1, false); + gl_RenderState.ApplyMaterial(flat->gltexture, CLAMP_NONE, 0, -1); gl_RenderState.SetPlaneTextureRotation(&plane, flat->gltexture); DrawSubsectors(flat, pass, true); gl_RenderState.EnableTextureMatrix(false); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 401838548..477b1fa39 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -426,7 +426,7 @@ void GLHorizonPortal::DrawContents(HWDrawInfo *hwdi) } - gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); + gl_RenderState.ApplyMaterial(gltexture, CLAMP_NONE, 0, -1); gl_RenderState.SetObjectColor(origin->specialcolor); gl_RenderState.SetPlaneTextureRotation(sp, gltexture); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 3cc50edb8..8c0529255 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -120,7 +120,7 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in { if (tex) { - gl_RenderState.SetMaterial(tex, CLAMP_NONE, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_NONE, 0, -1); gl_RenderState.EnableModelMatrix(true); gl_RenderState.EnableTextureMatrix(true); @@ -159,25 +159,25 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // north tex = FMaterial::ValidateTexture(sb->faces[0], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(0), 4); // east tex = FMaterial::ValidateTexture(sb->faces[1], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(1), 4); // south tex = FMaterial::ValidateTexture(sb->faces[2], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(2), 4); // west tex = FMaterial::ValidateTexture(sb->faces[3], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(3), 4); } @@ -185,20 +185,20 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool { faces=1; tex = FMaterial::ValidateTexture(sb->faces[0], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(-1), 10); } // top tex = FMaterial::ValidateTexture(sb->faces[faces], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(sb->fliptop? 6:5), 4); // bottom tex = FMaterial::ValidateTexture(sb->faces[faces+1], false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, 0, -1); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_STRIP, GLRenderer->mSkyVBO->FaceStart(4), 4); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 36c4b4cab..4dfc1cf7f 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -195,7 +195,7 @@ void FDrawInfo::DrawSprite(GLSprite *sprite, int pass) gl_RenderState.SetFog(0, 0); } - if (sprite->gltexture) gl_RenderState.SetMaterial(sprite->gltexture, CLAMP_XY, sprite->translation, sprite->OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); + if (sprite->gltexture) gl_RenderState.ApplyMaterial(sprite->gltexture, CLAMP_XY, sprite->translation, sprite->OverrideShader); else if (!sprite->modelframe) gl_RenderState.EnableTexture(false); //SetColor(lightlevel, rel, Colormap, trans); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index e2e61ef18..50cc72400 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -104,7 +104,7 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall) glDepthFunc(GL_LEQUAL); FMaterial * pat=FMaterial::ValidateTexture(TexMan.mirrorTexture, false, false); - gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false); + gl_RenderState.ApplyMaterial(pat, CLAMP_NONE, 0, -1); wall->flags &= ~GLWall::GLWF_GLOW; RenderWall(wall, GLWall::RWF_BLANK); @@ -151,7 +151,7 @@ void FDrawInfo::RenderTexturedWall(GLWall *wall, int rflags) gl_RenderState.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor); } gl_RenderState.SetGlowPlanes(wall->topplane, wall->bottomplane); - gl_RenderState.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1, false); + gl_RenderState.ApplyMaterial(wall->gltexture, wall->flags & 3, 0, -1); if (wall->type == RENDERWALL_M2SNF) { @@ -468,7 +468,7 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal) } gl_SetRenderStyle(decal->RenderStyle, false, false); - gl_RenderState.SetMaterial(tex, CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); + gl_RenderState.ApplyMaterial(tex, CLAMP_XY, decal->Translation, -1); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 5a041805b..ded54d5af 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -71,7 +71,7 @@ void FDrawInfo::DrawPSprite (HUDSprite *huds) { float thresh = (huds->tex->tex->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold; gl_RenderState.AlphaFunc(Alpha_GEqual, thresh); - gl_RenderState.SetMaterial(huds->tex, CLAMP_XY_NOMIP, 0, huds->OverrideShader, !!(huds->RenderStyle.Flags & STYLEF_RedIsAlpha)); + gl_RenderState.ApplyMaterial(huds->tex, CLAMP_XY_NOMIP, 0, huds->OverrideShader); gl_RenderState.Apply(); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, huds->mx, 4); } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index b3ce1023b..757ae0114 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -343,7 +343,7 @@ IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(FTexture *tex) void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { - gl_RenderState.SetMaterial(mat, CLAMP_NONE, translation, false, false); + gl_RenderState.ApplyMaterial(mat, CLAMP_NONE, translation, false); } FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) diff --git a/src/hwrenderer/scene/hw_renderstate.h b/src/hwrenderer/scene/hw_renderstate.h index fa65d0fdc..c28052418 100644 --- a/src/hwrenderer/scene/hw_renderstate.h +++ b/src/hwrenderer/scene/hw_renderstate.h @@ -87,6 +87,20 @@ struct FStencilState } }; +struct FDepthBiasState +{ + float mFactor; + float mUnits; + bool mChanged; + + void Reset() + { + mFactor = 0; + mUnits = 0; + mChanged = false; + } +}; + class FRenderState { protected: @@ -118,10 +132,7 @@ protected: FMaterialState mMaterial; FStencilState mStencil; - - // fixed function state - float mBias[2]; - bool mBiasOn; + FDepthBiasState mBias; public: VSMatrix mModelMatrix; @@ -146,8 +157,9 @@ public: mLightParms[3] = -1.f; mSpecialEffect = EFF_NONE; mLightIndex = -1; - mBiasOn = false; mMaterial.Reset(); + mStencil.Reset(); + mBias.Reset(); mColor.Set(1.0f, 1.0f, 1.0f, 1.0f); mGlowTop.Set(0.0f, 0.0f, 0.0f, 0.0f); @@ -324,16 +336,16 @@ public: void SetDepthBias(float a, float b) { - mBias[0] = a; - mBias[1] = b; - mBiasOn = true; + mBias.mFactor = a; + mBias.mUnits = b; + mBias.mChanged = true; } void ClearDepthBias() { - mBias[0] = 0; - mBias[1] = 0; - mBiasOn = false; + mBias.mFactor = 0; + mBias.mUnits = 0; + mBias.mChanged = true; } void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader)