diff --git a/binaries/data/mods/mod/shaders/effects/canvas2d.xml b/binaries/data/mods/mod/shaders/effects/canvas2d.xml
index 27610eaa1c..5589ff8c64 100644
--- a/binaries/data/mods/mod/shaders/effects/canvas2d.xml
+++ b/binaries/data/mods/mod/shaders/effects/canvas2d.xml
@@ -4,7 +4,7 @@
-
+
@@ -12,7 +12,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/bloom.xml b/binaries/data/mods/public/shaders/effects/bloom.xml
index 831fae1549..57cf89b150 100644
--- a/binaries/data/mods/public/shaders/effects/bloom.xml
+++ b/binaries/data/mods/public/shaders/effects/bloom.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/cas.xml b/binaries/data/mods/public/shaders/effects/cas.xml
index 03bb183674..798ebb4809 100644
--- a/binaries/data/mods/public/shaders/effects/cas.xml
+++ b/binaries/data/mods/public/shaders/effects/cas.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/debug_overlay.xml b/binaries/data/mods/public/shaders/effects/debug_overlay.xml
index d1f9e1a4c2..42a8501fed 100644
--- a/binaries/data/mods/public/shaders/effects/debug_overlay.xml
+++ b/binaries/data/mods/public/shaders/effects/debug_overlay.xml
@@ -5,7 +5,7 @@
-
+
@@ -14,7 +14,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/fxaa.xml b/binaries/data/mods/public/shaders/effects/fxaa.xml
index afaceae1c1..84ec599bb8 100644
--- a/binaries/data/mods/public/shaders/effects/fxaa.xml
+++ b/binaries/data/mods/public/shaders/effects/fxaa.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/model.xml b/binaries/data/mods/public/shaders/effects/model.xml
index c7aa2e4623..c4cbfda10e 100644
--- a/binaries/data/mods/public/shaders/effects/model.xml
+++ b/binaries/data/mods/public/shaders/effects/model.xml
@@ -52,6 +52,7 @@
+
@@ -61,6 +62,7 @@
+
diff --git a/binaries/data/mods/public/shaders/effects/model_transparent.xml b/binaries/data/mods/public/shaders/effects/model_transparent.xml
index d17656850d..de1dba073e 100644
--- a/binaries/data/mods/public/shaders/effects/model_transparent.xml
+++ b/binaries/data/mods/public/shaders/effects/model_transparent.xml
@@ -33,6 +33,7 @@
+
@@ -41,6 +42,7 @@
+
diff --git a/binaries/data/mods/public/shaders/effects/postproc/DOF.xml b/binaries/data/mods/public/shaders/effects/postproc/DOF.xml
index 6576493d13..5de6fed399 100644
--- a/binaries/data/mods/public/shaders/effects/postproc/DOF.xml
+++ b/binaries/data/mods/public/shaders/effects/postproc/DOF.xml
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/binaries/data/mods/public/shaders/effects/postproc/hdr.xml b/binaries/data/mods/public/shaders/effects/postproc/hdr.xml
index bfc15265b7..96893dde63 100644
--- a/binaries/data/mods/public/shaders/effects/postproc/hdr.xml
+++ b/binaries/data/mods/public/shaders/effects/postproc/hdr.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/binaries/data/mods/public/shaders/effects/water_high.xml b/binaries/data/mods/public/shaders/effects/water_high.xml
index ef56ddb9bb..adb3e03cf3 100644
--- a/binaries/data/mods/public/shaders/effects/water_high.xml
+++ b/binaries/data/mods/public/shaders/effects/water_high.xml
@@ -3,6 +3,7 @@
+
diff --git a/binaries/data/mods/public/shaders/effects/water_simple.xml b/binaries/data/mods/public/shaders/effects/water_simple.xml
index 3ad9cd7d27..23a7de2115 100644
--- a/binaries/data/mods/public/shaders/effects/water_simple.xml
+++ b/binaries/data/mods/public/shaders/effects/water_simple.xml
@@ -1,14 +1,18 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/shaders/effects/water_waves.xml b/binaries/data/mods/public/shaders/effects/water_waves.xml
index f411885d79..8cea786580 100644
--- a/binaries/data/mods/public/shaders/effects/water_waves.xml
+++ b/binaries/data/mods/public/shaders/effects/water_waves.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/source/graphics/CinemaManager.cpp b/source/graphics/CinemaManager.cpp
index 38c280575a..affa5114e1 100644
--- a/source/graphics/CinemaManager.cpp
+++ b/source/graphics/CinemaManager.cpp
@@ -22,7 +22,6 @@
#include "graphics/Camera.h"
#include "graphics/Color.h"
#include "graphics/GameView.h"
-#include "lib/ogl.h"
#include "maths/MathUtil.h"
#include "maths/Quaternion.h"
#include "maths/Vector3D.h"
@@ -73,8 +72,6 @@ void CCinemaManager::DrawPaths() const
if (!cmpCinemaManager)
return;
- glDisable(GL_DEPTH_TEST);
-
for (const std::pair& p : cmpCinemaManager->GetPaths())
{
DrawSpline(p.second, CColor(0.2f, 0.2f, 1.f, 0.9f), 128);
@@ -86,8 +83,6 @@ void CCinemaManager::DrawPaths() const
DrawSpline(p.second.GetTargetSpline(), CColor(1.f, 0.3f, 0.4f, 0.9f), 128);
DrawNodes(p.second.GetTargetSpline(), CColor(1.f, 0.1f, 0.f, 1.f));
}
-
- glEnable(GL_DEPTH_TEST);
}
void CCinemaManager::DrawSpline(const RNSpline& spline, const CColor& splineColor, int smoothness) const
@@ -105,7 +100,7 @@ void CCinemaManager::DrawSpline(const RNSpline& spline, const CColor& splineColo
const float time = start * i / spline.MaxDistance.ToFloat();
line.emplace_back(spline.GetPosition(time));
}
- g_Renderer.GetDebugRenderer().DrawLine(line, splineColor, 0.2f);
+ g_Renderer.GetDebugRenderer().DrawLine(line, splineColor, 0.2f, false);
// Height indicator
if (g_Game && g_Game->GetWorld() && g_Game->GetWorld()->GetTerrain())
@@ -115,7 +110,7 @@ void CCinemaManager::DrawSpline(const RNSpline& spline, const CColor& splineColo
const float time = start * i / spline.MaxDistance.ToFloat();
const CVector3D tmp = spline.GetPosition(time);
const float groundY = g_Game->GetWorld()->GetTerrain()->GetExactGroundLevel(tmp.X, tmp.Z);
- g_Renderer.GetDebugRenderer().DrawLine(tmp, CVector3D(tmp.X, groundY, tmp.Z), splineColor, 0.1f);
+ g_Renderer.GetDebugRenderer().DrawLine(tmp, CVector3D(tmp.X, groundY, tmp.Z), splineColor, 0.1f, false);
}
}
}
diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp
index fcc3be4014..53fabdde14 100644
--- a/source/graphics/ShaderManager.cpp
+++ b/source/graphics/ShaderManager.cpp
@@ -333,12 +333,17 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
EL(pass);
EL(require);
EL(sort_by_distance);
+ EL(stencil);
+ AT(compare);
AT(constant);
AT(context);
+ AT(depth_fail);
AT(dst);
+ AT(fail);
AT(front_face);
AT(func);
AT(mask);
+ AT(mask_read);
AT(mask_red);
AT(mask_green);
AT(mask_blue);
@@ -346,9 +351,12 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
AT(mode);
AT(name);
AT(op);
+ AT(pass);
+ AT(reference);
AT(shader);
AT(shaders);
AT(src);
+ AT(test);
AT(value);
#undef AT
#undef EL
@@ -494,6 +502,12 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
}
else if (Element.GetNodeName() == el_depth)
{
+ if (!Element.GetAttributes().GetNamedItem(at_test).empty())
+ {
+ passPipelineStateDesc.depthStencilState.depthTestEnabled =
+ Element.GetAttributes().GetNamedItem(at_test) == "TRUE";
+ }
+
if (!Element.GetAttributes().GetNamedItem(at_func).empty())
{
passPipelineStateDesc.depthStencilState.depthCompareOp =
@@ -506,6 +520,55 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
Element.GetAttributes().GetNamedItem(at_mask) == "true";
}
}
+ else if (Element.GetNodeName() == el_stencil)
+ {
+ if (!Element.GetAttributes().GetNamedItem(at_test).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilTestEnabled =
+ Element.GetAttributes().GetNamedItem(at_test) == "TRUE";
+ }
+
+ if (!Element.GetAttributes().GetNamedItem(at_reference).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilReference =
+ Element.GetAttributes().GetNamedItem(at_reference).ToULong();
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_mask_read).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilReadMask =
+ Element.GetAttributes().GetNamedItem(at_mask_read).ToULong();
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_mask).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilWriteMask =
+ Element.GetAttributes().GetNamedItem(at_mask).ToULong();
+ }
+
+ if (!Element.GetAttributes().GetNamedItem(at_compare).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilFrontFace.compareOp =
+ passPipelineStateDesc.depthStencilState.stencilBackFace.compareOp =
+ Renderer::Backend::ParseCompareOp(Element.GetAttributes().GetNamedItem(at_compare));
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_fail).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilFrontFace.failOp =
+ passPipelineStateDesc.depthStencilState.stencilBackFace.failOp =
+ Renderer::Backend::ParseStencilOp(Element.GetAttributes().GetNamedItem(at_fail));
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_pass).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilFrontFace.passOp =
+ passPipelineStateDesc.depthStencilState.stencilBackFace.passOp =
+ Renderer::Backend::ParseStencilOp(Element.GetAttributes().GetNamedItem(at_pass));
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_depth_fail).empty())
+ {
+ passPipelineStateDesc.depthStencilState.stencilFrontFace.depthFailOp =
+ passPipelineStateDesc.depthStencilState.stencilBackFace.depthFailOp =
+ Renderer::Backend::ParseStencilOp(Element.GetAttributes().GetNamedItem(at_depth_fail));
+ }
+ }
}
pass.SetPipelineStateDesc(passPipelineStateDesc);
diff --git a/source/renderer/DebugRenderer.cpp b/source/renderer/DebugRenderer.cpp
index 0a728a23a2..26424daa05 100644
--- a/source/renderer/DebugRenderer.cpp
+++ b/source/renderer/DebugRenderer.cpp
@@ -40,9 +40,10 @@ namespace
void SetGraphicsPipelineStateFromTechAndColor(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CShaderTechniquePtr& tech, const CColor& color)
+ const CShaderTechniquePtr& tech, const CColor& color, const bool depthTestEnabled = true)
{
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc = tech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.depthStencilState.depthTestEnabled = depthTestEnabled;
if (color.a != 1.0f)
{
pipelineStateDesc.blendState.enabled = true;
@@ -61,15 +62,19 @@ void SetGraphicsPipelineStateFromTechAndColor(
} // anonymous namespace
-void CDebugRenderer::DrawLine(const CVector3D& from, const CVector3D& to, const CColor& color, const float width)
+void CDebugRenderer::DrawLine(
+ const CVector3D& from, const CVector3D& to, const CColor& color,
+ const float width, const bool depthTestEnabled)
{
if (from == to)
return;
- DrawLine({from, to}, color, width);
+ DrawLine({from, to}, color, width, depthTestEnabled);
}
-void CDebugRenderer::DrawLine(const std::vector& line, const CColor& color, const float width)
+void CDebugRenderer::DrawLine(
+ const std::vector& line, const CColor& color,
+ const float width, const bool depthTestEnabled)
{
#if CONFIG2_GLES
UNUSED2(line); UNUSED2(color); UNUSED2(width);
@@ -78,7 +83,7 @@ void CDebugRenderer::DrawLine(const std::vector& line, const CColor&
CShaderTechniquePtr debugLineTech =
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
debugLineTech->BeginPass();
- SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), debugLineTech, color);
+ SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), debugLineTech, color, depthTestEnabled);
const CCamera& viewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
diff --git a/source/renderer/DebugRenderer.h b/source/renderer/DebugRenderer.h
index 40493c0959..cf156f27e8 100644
--- a/source/renderer/DebugRenderer.h
+++ b/source/renderer/DebugRenderer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2021 Wildfire Games.
+/* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -36,8 +36,10 @@ public:
/**
* Render the line in world space.
*/
- void DrawLine(const CVector3D& from, const CVector3D& to, const CColor& color, const float width);
- void DrawLine(const std::vector& line, const CColor& color, const float width);
+ void DrawLine(const CVector3D& from, const CVector3D& to,
+ const CColor& color, const float width, const bool depthTestEnabled = true);
+ void DrawLine(const std::vector& line,
+ const CColor& color, const float width, const bool depthTestEnabled = true);
/**
* Render the circle in world space oriented to the view camera.
diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp
index f7d10486f4..51e423ce05 100644
--- a/source/renderer/OverlayRenderer.cpp
+++ b/source/renderer/OverlayRenderer.cpp
@@ -622,7 +622,6 @@ void OverlayRenderer::RenderForegroundOverlays(
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glActiveTextureARB(GL_TEXTURE0);
- glDisable(GL_DEPTH_TEST);
CVector3D right = -viewCamera.GetOrientation().GetLeft();
CVector3D up = viewCamera.GetOrientation().GetUp();
@@ -630,6 +629,7 @@ void OverlayRenderer::RenderForegroundOverlays(
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_foreground_overlay);
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
tech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.depthStencilState.depthTestEnabled = false;
pipelineStateDesc.blendState.enabled = true;
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
Renderer::Backend::BlendFactor::SRC_ALPHA;
@@ -673,8 +673,6 @@ void OverlayRenderer::RenderForegroundOverlays(
tech->EndPass();
- glEnable(GL_DEPTH_TEST);
-
if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp
index af2680a149..c04fe89dd6 100644
--- a/source/renderer/PostprocManager.cpp
+++ b/source/renderer/PostprocManager.cpp
@@ -427,8 +427,6 @@ void CPostprocManager::ApplyEffect(
else
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
- glDisable(GL_DEPTH_TEST);
-
shaderTech1->BeginPass(pass);
deviceCommandContext->SetGraphicsPipelineState(
shaderTech1->GetGraphicsPipelineStateDesc(pass));
@@ -487,8 +485,6 @@ void CPostprocManager::ApplyEffect(
shaderTech1->EndPass(pass);
- glEnable(GL_DEPTH_TEST);
-
m_WhichBuffer = !m_WhichBuffer;
}
diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp
index 7fb41a0490..bc009a68ba 100644
--- a/source/renderer/Renderer.cpp
+++ b/source/renderer/Renderer.cpp
@@ -517,8 +517,6 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
ogl_WarnIfError();
}
- glDisable(GL_DEPTH_TEST);
-
if (renderGUI)
{
OGL_SCOPED_DEBUG_GROUP("Draw GUI");
@@ -549,8 +547,6 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
g_ProfileViewer.RenderProfile();
ogl_WarnIfError();
- glEnable(GL_DEPTH_TEST);
-
EndFrame();
const Stats& stats = GetStats();
diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp
index e6d79de3e6..256a243198 100644
--- a/source/renderer/SceneRenderer.cpp
+++ b/source/renderer/SceneRenderer.cpp
@@ -785,10 +785,6 @@ void CSceneRenderer::RenderSilhouettes(
// Since we can't sort, we'll use the stencil buffer to ensure we only draw
// a pixel once (using the color of whatever model happens to be drawn first).
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_NOTEQUAL, 1, (GLuint)-1);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
{
PROFILE("render model casters");
m->CallModelRenderers(deviceCommandContext, contextDisplay, CULL_SILHOUETTE_CASTER, 0);
@@ -798,9 +794,6 @@ void CSceneRenderer::RenderSilhouettes(
PROFILE("render transparent casters");
m->CallTranspModelRenderers(deviceCommandContext, contextDisplay, CULL_SILHOUETTE_CASTER, 0);
}
-
- // Restore state
- glDisable(GL_STENCIL_TEST);
}
void CSceneRenderer::RenderParticles(
diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp
index 1489e807cf..f35a2519ac 100644
--- a/source/renderer/ShadowMap.cpp
+++ b/source/renderer/ShadowMap.cpp
@@ -755,8 +755,6 @@ void ShadowMap::RenderDebugTexture(
if (!m->Texture)
return;
- glDisable(GL_DEPTH_TEST);
-
#if !CONFIG2_GLES
g_Renderer.BindTexture(0, m->Texture->GetHandle());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@@ -799,8 +797,6 @@ void ShadowMap::RenderDebugTexture(
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
#endif
- glEnable(GL_DEPTH_TEST);
-
ogl_WarnIfError();
}
diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp
index f2f9c3803a..31ab6edccf 100644
--- a/source/renderer/TerrainOverlay.cpp
+++ b/source/renderer/TerrainOverlay.cpp
@@ -149,8 +149,6 @@ void TerrainOverlay::RenderBeforeWater(
EndRender();
- // Clean up state changes
- glEnable(GL_DEPTH_TEST);
//glDisable(GL_POLYGON_OFFSET_LINE);
glDisable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -172,15 +170,6 @@ void TerrainOverlay::RenderTile(
// a vertex buffer or a vertex shader with a texture.
// Not sure if it's possible on old OpenGL.
- if (drawHidden)
- {
- glDisable(GL_DEPTH_TEST);
- }
- else
- {
- glEnable(GL_DEPTH_TEST);
- }
-
#if CONFIG2_GLES
UNUSED2(deviceCommandContext);
UNUSED2(color);
@@ -226,6 +215,7 @@ void TerrainOverlay::RenderTile(
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
overlayTech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.depthStencilState.depthTestEnabled = !drawHidden;
pipelineStateDesc.blendState.enabled = true;
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
Renderer::Backend::BlendFactor::SRC_ALPHA;
@@ -264,15 +254,6 @@ void TerrainOverlay::RenderTileOutline(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
const CColor& color, int lineWidth, bool drawHidden, ssize_t i, ssize_t j)
{
- if (drawHidden)
- {
- glDisable(GL_DEPTH_TEST);
- }
- else
- {
- glEnable(GL_DEPTH_TEST);
- }
-
#if CONFIG2_GLES
UNUSED2(deviceCommandContext);
UNUSED2(color);
@@ -305,6 +286,7 @@ void TerrainOverlay::RenderTileOutline(
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
overlayTech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.depthStencilState.depthTestEnabled = !drawHidden;
pipelineStateDesc.blendState.enabled = true;
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
Renderer::Backend::BlendFactor::SRC_ALPHA;
diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp
index 553c92c04e..f5a258a897 100644
--- a/source/renderer/TerrainRenderer.cpp
+++ b/source/renderer/TerrainRenderer.cpp
@@ -174,8 +174,6 @@ void TerrainRenderer::RenderTerrainOverlayTexture(
std::vector& visiblePatches = m->visiblePatches[cullGroup];
- glDisable(GL_DEPTH_TEST);
-
CShaderTechniquePtr debugOverlayTech =
g_Renderer.GetShaderManager().LoadEffect(str_debug_overlay);
debugOverlayTech->BeginPass();
@@ -188,8 +186,6 @@ void TerrainRenderer::RenderTerrainOverlayTexture(
debugOverlayShader->Uniform(str_textureTransform, textureMatrix);
CPatchRData::RenderStreams(visiblePatches, debugOverlayShader, STREAM_POS | STREAM_POSTOUV0);
- glEnable(GL_DEPTH_TEST);
-
// To make the overlay visible over water, render an additional map-sized
// water-height patch.
CBoundingBoxAligned waterBounds;
@@ -407,8 +403,6 @@ bool TerrainRenderer::RenderFancyWater(
const double time = waterManager.m_WaterTexTimer;
const float repeatPeriod = waterManager.m_RepeatPeriod;
- glEnable(GL_DEPTH_TEST);
-
#if !CONFIG2_GLES
if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -526,8 +520,6 @@ void TerrainRenderer::RenderSimpleWater(
const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager();
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
- glEnable(GL_DEPTH_TEST);
-
if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -591,13 +583,12 @@ void TerrainRenderer::RenderWaterFoamOccluders(
// Render normals and foam to a framebuffer if we're using fancy effects.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterManager.m_FancyEffectsFBO);
- glEnable(GL_DEPTH_TEST);
-
// Overwrite waves that would be behind the ground.
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
dummyTech->BeginPass();
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
dummyTech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.depthStencilState.depthTestEnabled = true;
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
const CShaderProgramPtr& dummyShader = dummyTech->GetShader();
diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp
index 818147ea85..617d71901d 100644
--- a/source/renderer/WaterManager.cpp
+++ b/source/renderer/WaterManager.cpp
@@ -816,8 +816,6 @@ void WaterManager::RenderWaves(
glClearColor(0.0f,0.0f, 0.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
-
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_water_waves);
tech->BeginPass();
deviceCommandContext->SetGraphicsPipelineState(
diff --git a/source/renderer/backend/PipelineState.cpp b/source/renderer/backend/PipelineState.cpp
index 4d1dd0afb2..0c5d3b6368 100644
--- a/source/renderer/backend/PipelineState.cpp
+++ b/source/renderer/backend/PipelineState.cpp
@@ -19,6 +19,8 @@
#include "PipelineState.h"
+#include
+
namespace Renderer
{
@@ -29,8 +31,18 @@ GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc()
{
GraphicsPipelineStateDesc desc{};
+ desc.depthStencilState.depthTestEnabled = true;
desc.depthStencilState.depthCompareOp = CompareOp::LESS_OR_EQUAL;
desc.depthStencilState.depthWriteEnabled = true;
+ desc.depthStencilState.stencilTestEnabled = false;
+ desc.depthStencilState.stencilFrontFace.failOp = StencilOp::KEEP;
+ desc.depthStencilState.stencilFrontFace.passOp = StencilOp::KEEP;
+ desc.depthStencilState.stencilFrontFace.depthFailOp = StencilOp::KEEP;
+ desc.depthStencilState.stencilFrontFace.compareOp = CompareOp::ALWAYS;
+ desc.depthStencilState.stencilBackFace = desc.depthStencilState.stencilFrontFace;
+ desc.depthStencilState.stencilReadMask = desc.depthStencilState.stencilWriteMask =
+ std::numeric_limits::max();
+ desc.depthStencilState.stencilReference = 0;
desc.blendState.enabled = false;
desc.blendState.srcColorBlendFactor = desc.blendState.srcAlphaBlendFactor =
@@ -64,6 +76,22 @@ CompareOp ParseCompareOp(const CStr& str)
return CompareOp::NEVER;
}
+StencilOp ParseStencilOp(const CStr& str)
+{
+#define CASE(NAME) if (str == #NAME) return StencilOp::NAME
+ CASE(KEEP);
+ CASE(ZERO);
+ CASE(REPLACE);
+ CASE(INCREMENT_AND_CLAMP);
+ CASE(DECREMENT_AND_CLAMP);
+ CASE(INVERT);
+ CASE(INCREMENT_AND_WRAP);
+ CASE(DECREMENT_AND_WRAP);
+#undef CASE
+ debug_warn("Invalid stencil op");
+ return StencilOp::KEEP;
+}
+
BlendFactor ParseBlendFactor(const CStr& str)
{
// TODO: it might make sense to use upper case in XML for consistency.
diff --git a/source/renderer/backend/PipelineState.h b/source/renderer/backend/PipelineState.h
index c6cc6841dd..1eba8deadd 100644
--- a/source/renderer/backend/PipelineState.h
+++ b/source/renderer/backend/PipelineState.h
@@ -48,10 +48,48 @@ enum class CompareOp
ALWAYS
};
+enum class StencilOp
+{
+ // Keeps the current value.
+ KEEP,
+ // Sets the value to zero.
+ ZERO,
+ // Sets the value to reference.
+ REPLACE,
+ // Increments the value and clamps to the maximum representable unsigned
+ // value.
+ INCREMENT_AND_CLAMP,
+ // Decrements the value and clamps to zero.
+ DECREMENT_AND_CLAMP,
+ // Bitwise inverts the value.
+ INVERT,
+ // Increments the value and wraps it to zero when incrementing the maximum
+ // representable unsigned value.
+ INCREMENT_AND_WRAP,
+ // Decrements the value and wraps it to the maximum representable unsigned
+ // value when decrementing zero.
+ DECREMENT_AND_WRAP
+};
+
+struct StencilOpState
+{
+ StencilOp failOp;
+ StencilOp passOp;
+ StencilOp depthFailOp;
+ CompareOp compareOp;
+};
+
struct DepthStencilStateDesc
{
+ bool depthTestEnabled;
CompareOp depthCompareOp;
bool depthWriteEnabled;
+ bool stencilTestEnabled;
+ uint32_t stencilReadMask;
+ uint32_t stencilWriteMask;
+ uint32_t stencilReference;
+ StencilOpState stencilFrontFace;
+ StencilOpState stencilBackFace;
};
// TODO: add per constant description.
@@ -144,6 +182,8 @@ GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc();
CompareOp ParseCompareOp(const CStr& str);
+StencilOp ParseStencilOp(const CStr& str);
+
BlendFactor ParseBlendFactor(const CStr& str);
BlendOp ParseBlendOp(const CStr& str);
diff --git a/source/renderer/backend/gl/Device.cpp b/source/renderer/backend/gl/Device.cpp
index c4809169cf..32653cce87 100644
--- a/source/renderer/backend/gl/Device.cpp
+++ b/source/renderer/backend/gl/Device.cpp
@@ -196,9 +196,6 @@ std::unique_ptr CDevice::Create(SDL_Window* window, const bool arb)
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- // Setup default state.
- glEnable(GL_DEPTH_TEST);
-
return device;
}
diff --git a/source/renderer/backend/gl/DeviceCommandContext.cpp b/source/renderer/backend/gl/DeviceCommandContext.cpp
index f1d7728502..19ed2cb0bf 100644
--- a/source/renderer/backend/gl/DeviceCommandContext.cpp
+++ b/source/renderer/backend/gl/DeviceCommandContext.cpp
@@ -31,6 +31,24 @@ namespace Backend
namespace GL
{
+namespace
+{
+
+bool operator==(const StencilOpState& lhs, const StencilOpState& rhs)
+{
+ return
+ lhs.failOp == rhs.failOp &&
+ lhs.passOp == rhs.passOp &&
+ lhs.depthFailOp == rhs.depthFailOp &&
+ lhs.compareOp == rhs.compareOp;
+}
+bool operator!=(const StencilOpState& lhs, const StencilOpState& rhs)
+{
+ return !operator==(lhs, rhs);
+}
+
+} // anonymous namespace
+
// static
std::unique_ptr CDeviceCommandContext::Create()
{
@@ -138,15 +156,90 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
{
const DepthStencilStateDesc& currentDepthStencilStateDesc = m_GraphicsPipelineStateDesc.depthStencilState;
const DepthStencilStateDesc& nextDepthStencilStateDesc = pipelineStateDesc.depthStencilState;
+ if (force || currentDepthStencilStateDesc.depthTestEnabled != nextDepthStencilStateDesc.depthTestEnabled)
+ {
+ if (nextDepthStencilStateDesc.depthTestEnabled)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
+ }
if (force || currentDepthStencilStateDesc.depthCompareOp != nextDepthStencilStateDesc.depthCompareOp)
{
- glDepthFunc(Mapping::DepthFuncFromCompareOp(nextDepthStencilStateDesc.depthCompareOp));
+ glDepthFunc(Mapping::FromCompareOp(nextDepthStencilStateDesc.depthCompareOp));
}
if (force || currentDepthStencilStateDesc.depthWriteEnabled != nextDepthStencilStateDesc.depthWriteEnabled)
{
glDepthMask(nextDepthStencilStateDesc.depthWriteEnabled ? GL_TRUE : GL_FALSE);
}
+ if (force || currentDepthStencilStateDesc.stencilTestEnabled != nextDepthStencilStateDesc.stencilTestEnabled)
+ {
+ if (nextDepthStencilStateDesc.stencilTestEnabled)
+ glEnable(GL_STENCIL_TEST);
+ else
+ glDisable(GL_STENCIL_TEST);
+ }
+ if (force ||
+ currentDepthStencilStateDesc.stencilFrontFace != nextDepthStencilStateDesc.stencilFrontFace ||
+ currentDepthStencilStateDesc.stencilBackFace != nextDepthStencilStateDesc.stencilBackFace)
+ {
+ if (nextDepthStencilStateDesc.stencilFrontFace == nextDepthStencilStateDesc.stencilBackFace)
+ {
+ glStencilOp(
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.failOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.depthFailOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.passOp));
+ }
+ else
+ {
+ if (force || currentDepthStencilStateDesc.stencilFrontFace != nextDepthStencilStateDesc.stencilFrontFace)
+ {
+ glStencilOpSeparate(
+ GL_FRONT,
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.failOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.depthFailOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilFrontFace.passOp));
+ }
+ if (force || currentDepthStencilStateDesc.stencilBackFace != nextDepthStencilStateDesc.stencilBackFace)
+ {
+ glStencilOpSeparate(
+ GL_BACK,
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilBackFace.failOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilBackFace.depthFailOp),
+ Mapping::FromStencilOp(nextDepthStencilStateDesc.stencilBackFace.passOp));
+ }
+ }
+ }
+ if (force || currentDepthStencilStateDesc.stencilWriteMask != nextDepthStencilStateDesc.stencilWriteMask)
+ {
+ glStencilMask(nextDepthStencilStateDesc.stencilWriteMask);
+ }
+ if (force ||
+ currentDepthStencilStateDesc.stencilReference != nextDepthStencilStateDesc.stencilReference ||
+ currentDepthStencilStateDesc.stencilReadMask != nextDepthStencilStateDesc.stencilReadMask ||
+ currentDepthStencilStateDesc.stencilFrontFace.compareOp != nextDepthStencilStateDesc.stencilFrontFace.compareOp ||
+ currentDepthStencilStateDesc.stencilBackFace.compareOp != nextDepthStencilStateDesc.stencilBackFace.compareOp)
+ {
+ if (nextDepthStencilStateDesc.stencilFrontFace.compareOp == nextDepthStencilStateDesc.stencilBackFace.compareOp)
+ {
+ glStencilFunc(
+ Mapping::FromCompareOp(nextDepthStencilStateDesc.stencilFrontFace.compareOp),
+ nextDepthStencilStateDesc.stencilReference,
+ nextDepthStencilStateDesc.stencilReadMask);
+ }
+ else
+ {
+ glStencilFuncSeparate(GL_FRONT,
+ Mapping::FromCompareOp(nextDepthStencilStateDesc.stencilFrontFace.compareOp),
+ nextDepthStencilStateDesc.stencilReference,
+ nextDepthStencilStateDesc.stencilReadMask);
+ glStencilFuncSeparate(GL_BACK,
+ Mapping::FromCompareOp(nextDepthStencilStateDesc.stencilBackFace.compareOp),
+ nextDepthStencilStateDesc.stencilReference,
+ nextDepthStencilStateDesc.stencilReadMask);
+ }
+ }
+
const BlendStateDesc& currentBlendStateDesc = m_GraphicsPipelineStateDesc.blendState;
const BlendStateDesc& nextBlendStateDesc = pipelineStateDesc.blendState;
if (force || currentBlendStateDesc.enabled != nextBlendStateDesc.enabled)
diff --git a/source/renderer/backend/gl/Mapping.cpp b/source/renderer/backend/gl/Mapping.cpp
index 1fc777d9fe..841025a0e0 100644
--- a/source/renderer/backend/gl/Mapping.cpp
+++ b/source/renderer/backend/gl/Mapping.cpp
@@ -34,12 +34,12 @@ namespace GL
namespace Mapping
{
-GLenum DepthFuncFromCompareOp(const CompareOp compareOp)
+GLenum FromCompareOp(const CompareOp compareOp)
{
- GLenum detphFunc = GL_NEVER;
+ GLenum op = GL_NEVER;
switch (compareOp)
{
-#define CASE(NAME, GL_NAME) case CompareOp::NAME: detphFunc = GL_NAME; break
+#define CASE(NAME, GL_NAME) case CompareOp::NAME: op = GL_NAME; break
CASE(NEVER, GL_NEVER);
CASE(LESS, GL_LESS);
CASE(EQUAL, GL_EQUAL);
@@ -50,7 +50,26 @@ GLenum DepthFuncFromCompareOp(const CompareOp compareOp)
CASE(ALWAYS, GL_ALWAYS);
#undef CASE
}
- return detphFunc;
+ return op;
+}
+
+GLenum FromStencilOp(const StencilOp stencilOp)
+{
+ GLenum op = GL_KEEP;
+ switch (stencilOp)
+ {
+#define CASE(NAME, GL_NAME) case StencilOp::NAME: op = GL_NAME; break
+ CASE(KEEP, GL_KEEP);
+ CASE(ZERO, GL_ZERO);
+ CASE(REPLACE, GL_REPLACE);
+ CASE(INCREMENT_AND_CLAMP, GL_INCR);
+ CASE(DECREMENT_AND_CLAMP, GL_DECR);
+ CASE(INVERT, GL_INVERT);
+ CASE(INCREMENT_AND_WRAP, GL_INCR_WRAP);
+ CASE(DECREMENT_AND_WRAP, GL_DECR_WRAP);
+#undef CASE
+ }
+ return op;
}
GLenum FromBlendFactor(const BlendFactor blendFactor)
diff --git a/source/renderer/backend/gl/Mapping.h b/source/renderer/backend/gl/Mapping.h
index 56a6a07f80..631f81958d 100644
--- a/source/renderer/backend/gl/Mapping.h
+++ b/source/renderer/backend/gl/Mapping.h
@@ -33,7 +33,9 @@ namespace GL
namespace Mapping
{
-GLenum DepthFuncFromCompareOp(const CompareOp compareOp);
+GLenum FromCompareOp(const CompareOp compareOp);
+
+GLenum FromStencilOp(const StencilOp stencilOp);
GLenum FromBlendFactor(const BlendFactor blendFactor);
diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp
index abe0d29d5c..21ded5f163 100644
--- a/source/tools/atlas/GameInterface/ActorViewer.cpp
+++ b/source/tools/atlas/GameInterface/ActorViewer.cpp
@@ -524,10 +524,8 @@ void ActorViewer::Render()
g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), m);
- glDisable(GL_DEPTH_TEST);
g_Logger->Render();
g_ProfileViewer.RenderProfile();
- glEnable(GL_DEPTH_TEST);
g_Renderer.EndFrame();
diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp
index 76e374f583..5571f199cf 100644
--- a/source/tools/atlas/GameInterface/View.cpp
+++ b/source/tools/atlas/GameInterface/View.cpp
@@ -247,11 +247,15 @@ void AtlasViewGame::DrawCinemaPathTool()
const float axisLength = scale / 10.0f;
const float lineWidth = scale / 1e3f;
- glDisable(GL_DEPTH_TEST);
- g_Renderer.GetDebugRenderer().DrawLine(focus, focus + CVector3D(axisLength, 0, 0), CColor(1.0f, 0.0f, 0.0f, 1.0f), lineWidth);
- g_Renderer.GetDebugRenderer().DrawLine(focus, focus + CVector3D(0, axisLength, 0), CColor(0.0f, 1.0f, 0.0f, 1.0f), lineWidth);
- g_Renderer.GetDebugRenderer().DrawLine(focus, focus + CVector3D(0, 0, axisLength), CColor(0.0f, 0.0f, 1.0f, 1.0f), lineWidth);
- glEnable(GL_DEPTH_TEST);
+ g_Renderer.GetDebugRenderer().DrawLine(
+ focus, focus + CVector3D(axisLength, 0, 0),
+ CColor(1.0f, 0.0f, 0.0f, 1.0f), lineWidth, false);
+ g_Renderer.GetDebugRenderer().DrawLine(
+ focus, focus + CVector3D(0, axisLength, 0),
+ CColor(0.0f, 1.0f, 0.0f, 1.0f), lineWidth, false);
+ g_Renderer.GetDebugRenderer().DrawLine(
+ focus, focus + CVector3D(0, 0, axisLength),
+ CColor(0.0f, 0.0f, 1.0f, 1.0f), lineWidth, false);
}
void AtlasViewGame::DrawOverlays(CCanvas2D& canvas)