Index: binaries/data/mods/public/shaders/effects/dummy.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/dummy.xml
+++ binaries/data/mods/public/shaders/effects/dummy.xml
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/model.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/model.xml
+++ binaries/data/mods/public/shaders/effects/model.xml
@@ -2,6 +2,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/model_transparent.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/model_transparent.xml
+++ binaries/data/mods/public/shaders/effects/model_transparent.xml
@@ -1,83 +1,132 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/terrain_base.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/terrain_base.xml
+++ binaries/data/mods/public/shaders/effects/terrain_base.xml
@@ -1,14 +1,30 @@
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/terrain_blend.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/terrain_blend.xml
+++ binaries/data/mods/public/shaders/effects/terrain_blend.xml
@@ -1,14 +1,30 @@
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/terrain_decal.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/terrain_decal.xml
+++ binaries/data/mods/public/shaders/effects/terrain_decal.xml
@@ -1,14 +1,30 @@
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: binaries/data/mods/public/shaders/effects/terrain_solid.xml
===================================================================
--- binaries/data/mods/public/shaders/effects/terrain_solid.xml
+++ binaries/data/mods/public/shaders/effects/terrain_solid.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: source/graphics/ShaderManager.cpp
===================================================================
--- source/graphics/ShaderManager.cpp
+++ source/graphics/ShaderManager.cpp
@@ -352,6 +352,7 @@
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
EL(blend);
+ EL(cull);
EL(define);
EL(depth);
EL(pass);
@@ -360,7 +361,9 @@
AT(constant);
AT(context);
AT(dst);
+ AT(front_face);
AT(func);
+ AT(mode);
AT(op);
AT(shader);
AT(shaders);
@@ -491,6 +494,19 @@
LOGERROR("Failed to parse blend constant: %s",
Element.GetAttributes().GetNamedItem(at_constant).c_str());
}
+ }
+ }
+ else if (Element.GetNodeName() == el_cull)
+ {
+ if (!Element.GetAttributes().GetNamedItem(at_mode).empty())
+ {
+ passPipelineStateDesc.rasterizationState.cullMode =
+ Renderer::Backend::ParseCullMode(Element.GetAttributes().GetNamedItem(at_mode));
+ }
+ if (!Element.GetAttributes().GetNamedItem(at_front_face).empty())
+ {
+ passPipelineStateDesc.rasterizationState.frontFace =
+ Renderer::Backend::ParseFrontFace(Element.GetAttributes().GetNamedItem(at_front_face));
}
}
else if (Element.GetNodeName() == el_depth)
Index: source/ps/CStrInternStatic.h
===================================================================
--- source/ps/CStrInternStatic.h
+++ source/ps/CStrInternStatic.h
@@ -56,6 +56,9 @@
X(MODE_SILHOUETTEDISPLAY)
X(MODE_SILHOUETTEOCCLUDER)
X(MODE_WIREFRAME)
+X(PASS_REFLECTIONS)
+X(PASS_REFRACTIONS)
+X(PASS_SHADOWS)
X(RENDER_DEBUG_MODE)
X(RENDER_DEBUG_MODE_AO)
X(RENDER_DEBUG_MODE_ALPHA)
@@ -165,6 +168,7 @@
X(solid)
X(sunColor)
X(sunDir)
+X(terrain_solid)
X(tex)
X(texSize)
X(textureTransform)
Index: source/renderer/DebugRenderer.cpp
===================================================================
--- source/renderer/DebugRenderer.cpp
+++ source/renderer/DebugRenderer.cpp
@@ -55,6 +55,7 @@
}
else
pipelineStateDesc.blendState.enabled = false;
+ pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
}
Index: source/renderer/PatchRData.cpp
===================================================================
--- source/renderer/PatchRData.cpp
+++ source/renderer/PatchRData.cpp
@@ -1133,8 +1133,6 @@
{
PROFILE3("render terrain sides");
- glDisable(GL_CULL_FACE);
-
CVertexBuffer* lastVB = nullptr;
for (CPatchRData* patch : patches)
{
@@ -1161,8 +1159,6 @@
}
CVertexBuffer::Unbind();
-
- glEnable(GL_CULL_FACE);
}
void CPatchRData::RenderPriorities(CTextRenderer& textRenderer)
Index: source/renderer/SceneRenderer.h
===================================================================
--- source/renderer/SceneRenderer.h
+++ source/renderer/SceneRenderer.h
@@ -208,7 +208,7 @@
const CShaderDefines& context, int cullGroup);
void RenderTransparentModels(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode, bool disableFaceCulling);
+ const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode);
void RenderSilhouettes(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
Index: source/renderer/SceneRenderer.cpp
===================================================================
--- source/renderer/SceneRenderer.cpp
+++ source/renderer/SceneRenderer.cpp
@@ -308,7 +308,10 @@
PROFILE3_GPU("shadow map");
OGL_SCOPED_DEBUG_GROUP("Render shadow map");
- CShaderDefines contextCast = context;
+ CShaderDefines shadowsContext = context;
+ shadowsContext.Add(str_PASS_SHADOWS, str_1);
+
+ CShaderDefines contextCast = shadowsContext;
contextCast.Add(str_MODE_SHADOWCAST, str_1);
m->shadow.BeginRender();
@@ -322,10 +325,7 @@
const int cullGroup = CULL_SHADOWS_CASCADE_0 + cascade;
{
PROFILE("render patches");
- glCullFace(GL_FRONT);
- glEnable(GL_CULL_FACE);
- m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup);
- glCullFace(GL_BACK);
+ m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, shadowsContext);
}
{
@@ -335,10 +335,7 @@
{
PROFILE("render transparent models");
- // disable face-culling for two-sided models
- glDisable(GL_CULL_FACE);
m->CallTranspModelRenderers(deviceCommandContext, contextCast, cullGroup, MODELFLAG_CASTSHADOWS);
- glEnable(GL_CULL_FACE);
}
}
@@ -386,7 +383,7 @@
glLineWidth(2.0f);
// render tiles edges
- m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, CColor(0.5f, 0.5f, 1.0f, 1.0f));
+ m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, context, CColor(0.5f, 0.5f, 1.0f, 1.0f));
glLineWidth(4.0f);
@@ -439,7 +436,7 @@
void CSceneRenderer::RenderTransparentModels(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode, bool disableFaceCulling)
+ const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode)
{
PROFILE3_GPU("transparent models");
OGL_SCOPED_DEBUG_GROUP("Render transparent models");
@@ -454,10 +451,6 @@
}
#endif
- // disable face culling for two-sided models in sub-renders
- if (disableFaceCulling)
- glDisable(GL_CULL_FACE);
-
CShaderDefines contextOpaque = context;
contextOpaque.Add(str_ALPHABLEND_PASS_OPAQUE, str_1);
@@ -470,9 +463,6 @@
if (transparentMode == TRANSPARENT || transparentMode == TRANSPARENT_BLEND)
m->CallTranspModelRenderers(deviceCommandContext, contextBlend, cullGroup, flags);
- if (disableFaceCulling)
- glEnable(GL_CULL_FACE);
-
#if !CONFIG2_GLES
if (m_ModelRenderMode == WIREFRAME)
{
@@ -651,8 +641,6 @@
glClearColor(0.5f, 0.5f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glFrontFace(GL_CW);
-
if (!g_RenderingOptions.GetWaterReflection())
{
m->skyManager.RenderSky(deviceCommandContext);
@@ -660,18 +648,19 @@
}
else
{
+ CShaderDefines reflectionsContext = context;
+ reflectionsContext.Add(str_PASS_REFLECTIONS, str_1);
// Render terrain and models
- RenderPatches(deviceCommandContext, context, CULL_REFLECTIONS);
+ RenderPatches(deviceCommandContext, reflectionsContext, CULL_REFLECTIONS);
ogl_WarnIfError();
- RenderModels(deviceCommandContext, context, CULL_REFLECTIONS);
+ RenderModels(deviceCommandContext, reflectionsContext, CULL_REFLECTIONS);
ogl_WarnIfError();
- RenderTransparentModels(deviceCommandContext, context, CULL_REFLECTIONS, TRANSPARENT, true);
+ RenderTransparentModels(deviceCommandContext, reflectionsContext, CULL_REFLECTIONS, TRANSPARENT);
ogl_WarnIfError();
}
- glFrontFace(GL_CCW);
// Particles are always oriented to face the camera in the vertex shader,
- // so they don't need the inverted glFrontFace
+ // so they don't need the inverted cull face.
if (g_RenderingOptions.GetParticles())
{
RenderParticles(deviceCommandContext, CULL_REFLECTIONS);
@@ -737,7 +726,7 @@
ogl_WarnIfError();
RenderModels(deviceCommandContext, context, CULL_REFRACTIONS);
ogl_WarnIfError();
- RenderTransparentModels(deviceCommandContext, context, CULL_REFRACTIONS, TRANSPARENT_OPAQUE, false);
+ RenderTransparentModels(deviceCommandContext, context, CULL_REFRACTIONS, TRANSPARENT_OPAQUE);
ogl_WarnIfError();
glDisable(GL_SCISSOR_TEST);
@@ -777,13 +766,7 @@
{
PROFILE("render patches");
-
- // To prevent units displaying silhouettes when parts of their model
- // protrude into the ground, only occlude with the back faces of the
- // terrain (so silhouettes will still display when behind hills)
- glCullFace(GL_FRONT);
- m->terrainRenderer.RenderPatches(deviceCommandContext, CULL_SILHOUETTE_OCCLUDER);
- glCullFace(GL_BACK);
+ m->terrainRenderer.RenderPatches(deviceCommandContext, CULL_SILHOUETTE_OCCLUDER, contextOccluder);
}
{
@@ -949,14 +932,14 @@
if (m->waterManager.WillRenderFancyWater())
{
// Render transparent stuff, but only the solid parts that can occlude block water.
- RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT_OPAQUE, false);
+ RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT_OPAQUE);
ogl_WarnIfError();
m->terrainRenderer.RenderWater(deviceCommandContext, context, cullGroup, &m->shadow);
ogl_WarnIfError();
// Render transparent stuff again, but only the blended parts that overlap water.
- RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT_BLEND, false);
+ RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT_BLEND);
ogl_WarnIfError();
}
else
@@ -965,14 +948,14 @@
ogl_WarnIfError();
// Render transparent stuff, so it can overlap models/terrain.
- RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT, false);
+ RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT);
ogl_WarnIfError();
}
}
else
{
// render transparent stuff, so it can overlap models/terrain
- RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT, false);
+ RenderTransparentModels(deviceCommandContext, context, cullGroup, TRANSPARENT);
ogl_WarnIfError();
}
@@ -1049,7 +1032,6 @@
#warning TODO: implement CSceneRenderer::DisplayFrustum for GLES
#else
glDepthMask(0);
- glDisable(GL_CULL_FACE);
g_Renderer.GetDebugRenderer().DrawCameraFrustum(m_CullCamera, CColor(1.0f, 1.0f, 1.0f, 0.25f), 2);
@@ -1057,7 +1039,6 @@
g_Renderer.GetDebugRenderer().DrawCameraFrustum(m_CullCamera, CColor(1.0f, 1.0f, 1.0f, 1.0f), 2);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glEnable(GL_CULL_FACE);
glDepthMask(1);
#endif
Index: source/renderer/ShadowMap.cpp
===================================================================
--- source/renderer/ShadowMap.cpp
+++ source/renderer/ShadowMap.cpp
@@ -727,7 +727,6 @@
void ShadowMap::RenderDebugBounds()
{
glDepthMask(0);
- glDisable(GL_CULL_FACE);
// Render various shadow bounds:
// Yellow = bounds of objects in view frustum that receive shadows
@@ -755,7 +754,6 @@
g_Renderer.GetDebugRenderer().DrawBrushOutline(frustumBrush, CColor(1.0f, 0.0f, 0.0f, 0.5f));
}
- glEnable(GL_CULL_FACE);
glDepthMask(1);
ogl_WarnIfError();
Index: source/renderer/SilhouetteRenderer.cpp
===================================================================
--- source/renderer/SilhouetteRenderer.cpp
+++ source/renderer/SilhouetteRenderer.cpp
@@ -451,7 +451,6 @@
return;
glDepthMask(0);
- glDisable(GL_CULL_FACE);
for (size_t i = 0; i < m_DebugBounds.size(); ++i)
g_Renderer.GetDebugRenderer().DrawBoundingBoxOutline(m_DebugBounds[i].bounds, m_DebugBounds[i].color);
@@ -468,17 +467,20 @@
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
shaderTech->BeginPass();
- deviceCommandContext->SetGraphicsPipelineState(
- shaderTech->GetGraphicsPipelineStateDesc());
+ Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
+ shaderTech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
+ deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
- CShaderProgramPtr shader = shaderTech->GetShader();
+ const CShaderProgramPtr& shader = shaderTech->GetShader();
shader->Uniform(str_transform, proj);
for (size_t i = 0; i < m_DebugRects.size(); ++i)
{
const DebugRect& r = m_DebugRects[i];
shader->Uniform(str_color, r.color);
- u16 verts[] = {
+ u16 verts[] =
+ {
r.x0, r.y0,
r.x1, r.y0,
r.x1, r.y1,
@@ -491,7 +493,6 @@
shaderTech->EndPass();
- glEnable(GL_CULL_FACE);
glDepthMask(1);
}
Index: source/renderer/TerrainOverlay.h
===================================================================
--- source/renderer/TerrainOverlay.h
+++ source/renderer/TerrainOverlay.h
@@ -136,38 +136,38 @@
* Draw a filled quad on top of the current tile.
*
* @param color color to draw. May be transparent (alpha < 1)
- * @param draw_hidden true if hidden tiles (i.e. those behind other tiles)
+ * @param drawHidden true if hidden tiles (i.e. those behind other tiles)
* should be drawn
*/
void RenderTile(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, bool draw_hidden);
+ const CColor& color, bool drawHidden);
/**
* Draw a filled quad on top of the given tile.
*/
void RenderTile(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, bool draw_hidden, ssize_t i, ssize_t j);
+ const CColor& color, bool drawHidden, ssize_t i, ssize_t j);
/**
* Draw an outlined quad on top of the current tile.
*
* @param color color to draw. May be transparent (alpha < 1)
- * @param line_width width of lines in pixels. 1 is a sensible value
- * @param draw_hidden true if hidden tiles (i.e. those behind other tiles)
+ * @param lineWidth width of lines in pixels. 1 is a sensible value
+ * @param drawHidden true if hidden tiles (i.e. those behind other tiles)
* should be drawn
*/
void RenderTileOutline(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, int line_width, bool draw_hidden);
+ const CColor& color, int lineWidth, bool drawHidden);
/**
* Draw an outlined quad on top of the given tile.
*/
void RenderTileOutline(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, int line_width, bool draw_hidden, ssize_t i, ssize_t j);
+ const CColor& color, int lineWidth, bool drawHidden, ssize_t i, ssize_t j);
private:
// Process all tiles
Index: source/renderer/TerrainOverlay.cpp
===================================================================
--- source/renderer/TerrainOverlay.cpp
+++ source/renderer/TerrainOverlay.cpp
@@ -151,7 +151,6 @@
EndRender();
// Clean up state changes
- glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
//glDisable(GL_POLYGON_OFFSET_LINE);
glDisable(GL_POLYGON_OFFSET_FILL);
@@ -162,28 +161,26 @@
void TerrainOverlay::RenderTile(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, bool draw_hidden)
+ const CColor& color, bool drawHidden)
{
- RenderTile(deviceCommandContext, color, draw_hidden, m_i, m_j);
+ RenderTile(deviceCommandContext, color, drawHidden, m_i, m_j);
}
void TerrainOverlay::RenderTile(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, bool draw_hidden, ssize_t i, ssize_t j)
+ const CColor& color, bool drawHidden, ssize_t i, ssize_t j)
{
// TODO: unnecessary computation calls has been removed but we should use
// a vertex buffer or a vertex shader with a texture.
// Not sure if it's possible on old OpenGL.
- if (draw_hidden)
+ if (drawHidden)
{
glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
}
else
{
glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
}
#if CONFIG2_GLES
@@ -238,6 +235,8 @@
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
Renderer::Backend::BlendOp::ADD;
+ pipelineStateDesc.rasterizationState.cullMode =
+ drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK;
overlayTech->BeginPass();
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
@@ -258,24 +257,22 @@
void TerrainOverlay::RenderTileOutline(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, int line_width, bool draw_hidden)
+ const CColor& color, int lineWidth, bool drawHidden)
{
- RenderTileOutline(deviceCommandContext, color, line_width, draw_hidden, m_i, m_j);
+ RenderTileOutline(deviceCommandContext, color, lineWidth, drawHidden, m_i, m_j);
}
void TerrainOverlay::RenderTileOutline(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- const CColor& color, int line_width, bool draw_hidden, ssize_t i, ssize_t j)
+ const CColor& color, int lineWidth, bool drawHidden, ssize_t i, ssize_t j)
{
- if (draw_hidden)
+ if (drawHidden)
{
glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
}
else
{
glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
}
#if CONFIG2_GLES
@@ -289,8 +286,8 @@
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- if (line_width != 1)
- glLineWidth((float)line_width);
+ if (lineWidth != 1)
+ glLineWidth(static_cast(lineWidth));
std::vector vertices;
#define ADD(i, j) \
@@ -317,10 +314,12 @@
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
Renderer::Backend::BlendOp::ADD;
+ pipelineStateDesc.rasterizationState.cullMode =
+ drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK;
overlayTech->BeginPass();
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
- CShaderProgramPtr overlayShader = overlayTech->GetShader();
+ const CShaderProgramPtr& overlayShader = overlayTech->GetShader();
overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
overlayShader->Uniform(str_color, color);
@@ -332,7 +331,7 @@
overlayTech->EndPass();
- if (line_width != 1)
+ if (lineWidth != 1)
glLineWidth(1.0f);
#endif
}
Index: source/renderer/TerrainRenderer.h
===================================================================
--- source/renderer/TerrainRenderer.h
+++ source/renderer/TerrainRenderer.h
@@ -115,7 +115,8 @@
*/
void RenderPatches(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- int cullGroup, const CColor& color = CColor(0.0f, 0.0f, 0.0f, 1.0f));
+ int cullGroup, const CShaderDefines& defines,
+ const CColor& color = CColor(0.0f, 0.0f, 0.0f, 1.0f));
/**
* RenderOutlines: Render the outline of patches as lines.
Index: source/renderer/TerrainRenderer.cpp
===================================================================
--- source/renderer/TerrainRenderer.cpp
+++ source/renderer/TerrainRenderer.cpp
@@ -265,8 +265,10 @@
// render the solid black sides of the map first
CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect(str_solid);
techSolid->BeginPass();
- deviceCommandContext->SetGraphicsPipelineState(
- techSolid->GetGraphicsPipelineStateDesc());
+ Renderer::Backend::GraphicsPipelineStateDesc solidPipelineStateDesc =
+ techSolid->GetGraphicsPipelineStateDesc();
+ solidPipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
+ deviceCommandContext->SetGraphicsPipelineState(solidPipelineStateDesc);
const CShaderProgramPtr& shaderSolid = techSolid->GetShader();
shaderSolid->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
@@ -299,7 +301,7 @@
// Render un-textured patches as polygons
void TerrainRenderer::RenderPatches(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
- int cullGroup, const CColor& color)
+ int cullGroup, const CShaderDefines& defines, const CColor& color)
{
ENSURE(m->phase == Phase_Render);
@@ -313,17 +315,17 @@
#warning TODO: implement TerrainRenderer::RenderPatches for GLES
#else
- CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_dummy);
- dummyTech->BeginPass();
+ CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
+ solidTech->BeginPass();
deviceCommandContext->SetGraphicsPipelineState(
- dummyTech->GetGraphicsPipelineStateDesc());
+ solidTech->GetGraphicsPipelineStateDesc());
- const CShaderProgramPtr& dummyShader = dummyTech->GetShader();
- dummyShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
- dummyShader->Uniform(str_color, color);
+ const CShaderProgramPtr& solidShader = solidTech->GetShader();
+ solidShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
+ solidShader->Uniform(str_color, color);
- CPatchRData::RenderStreams(visiblePatches, dummyShader, STREAM_POS);
- dummyTech->EndPass();
+ CPatchRData::RenderStreams(visiblePatches, solidShader, STREAM_POS);
+ solidTech->EndPass();
#endif
}
@@ -603,12 +605,13 @@
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
- glDisable(GL_CULL_FACE);
// Overwrite waves that would be behind the ground.
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
dummyTech->BeginPass();
- deviceCommandContext->SetGraphicsPipelineState(
- dummyTech->GetGraphicsPipelineStateDesc());
+ Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
+ dummyTech->GetGraphicsPipelineStateDesc();
+ pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
+ deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
const CShaderProgramPtr& dummyShader = dummyTech->GetShader();
dummyShader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
@@ -617,7 +620,6 @@
data->RenderWaterShore(dummyShader);
dummyTech->EndPass();
- glEnable(GL_CULL_FACE);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
Index: source/renderer/backend/PipelineState.h
===================================================================
--- source/renderer/backend/PipelineState.h
+++ source/renderer/backend/PipelineState.h
@@ -74,10 +74,30 @@
CColor constant;
};
+enum class CullMode
+{
+ NONE,
+ FRONT,
+ BACK
+};
+
+enum class FrontFace
+{
+ COUNTER_CLOCKWISE,
+ CLOCKWISE
+};
+
+struct RasterizationStateDesc
+{
+ CullMode cullMode;
+ FrontFace frontFace;
+};
+
// TODO: Add a shader program to the graphics pipeline state.
struct GraphicsPipelineStateDesc
{
BlendStateDesc blendState;
+ RasterizationStateDesc rasterizationState;
};
// We don't provide additional helpers intentionally because all custom states
@@ -86,6 +106,9 @@
BlendFactor ParseBlendFactor(const CStr& str);
BlendOp ParseBlendOp(const CStr& str);
+
+CullMode ParseCullMode(const CStr& str);
+FrontFace ParseFrontFace(const CStr& str);
} // namespace Backend
Index: source/renderer/backend/PipelineState.cpp
===================================================================
--- source/renderer/backend/PipelineState.cpp
+++ source/renderer/backend/PipelineState.cpp
@@ -28,6 +28,7 @@
GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc()
{
GraphicsPipelineStateDesc desc{};
+
desc.blendState.enabled = false;
desc.blendState.srcColorBlendFactor = desc.blendState.srcAlphaBlendFactor =
BlendFactor::ONE;
@@ -35,6 +36,9 @@
BlendFactor::ZERO;
desc.blendState.colorBlendOp = desc.blendState.alphaBlendOp = BlendOp::ADD;
desc.blendState.constant = CColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ desc.rasterizationState.cullMode = CullMode::BACK;
+ desc.rasterizationState.frontFace = FrontFace::COUNTER_CLOCKWISE;
return desc;
}
@@ -77,6 +81,22 @@
#undef CASE
debug_warn("Invalid blend op");
return BlendOp::ADD;
+}
+
+CullMode ParseCullMode(const CStr& str)
+{
+ if (str == "NONE")
+ return CullMode::NONE;
+ else if (str == "FRONT")
+ return CullMode::FRONT;
+ return CullMode::BACK;
+}
+
+FrontFace ParseFrontFace(const CStr& str)
+{
+ if (str == "CLOCKWISE")
+ return FrontFace::CLOCKWISE;
+ return FrontFace::COUNTER_CLOCKWISE;
}
} // namespace Backend
Index: source/renderer/backend/gl/Device.cpp
===================================================================
--- source/renderer/backend/gl/Device.cpp
+++ source/renderer/backend/gl/Device.cpp
@@ -199,9 +199,6 @@
// Setup default state.
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
- glCullFace(GL_BACK);
- glFrontFace(GL_CCW);
- glEnable(GL_CULL_FACE);
return device;
}
Index: source/renderer/backend/gl/DeviceCommandContext.cpp
===================================================================
--- source/renderer/backend/gl/DeviceCommandContext.cpp
+++ source/renderer/backend/gl/DeviceCommandContext.cpp
@@ -194,6 +194,33 @@
nextBlendStateDesc.constant.a);
}
+ const RasterizationStateDesc& currentRasterizationStateDesc = m_GraphicsPipelineStateDesc.rasterizationState;
+ const RasterizationStateDesc& nextRasterizationStateDesc = pipelineStateDesc.rasterizationState;
+ if (force ||
+ currentRasterizationStateDesc.cullMode != nextRasterizationStateDesc.cullMode)
+ {
+ if (nextRasterizationStateDesc.cullMode == CullMode::NONE)
+ {
+ glDisable(GL_CULL_FACE);
+ }
+ else
+ {
+ if (force || currentRasterizationStateDesc.cullMode == CullMode::NONE)
+ glEnable(GL_CULL_FACE);
+ glCullFace(nextRasterizationStateDesc.cullMode == CullMode::FRONT ? GL_FRONT : GL_BACK);
+ }
+ }
+
+ if (force ||
+ currentRasterizationStateDesc.frontFace != nextRasterizationStateDesc.frontFace)
+ {
+ if (nextRasterizationStateDesc.frontFace == FrontFace::CLOCKWISE)
+ glFrontFace(GL_CW);
+ else
+ glFrontFace(GL_CCW);
+ }
+
+
m_GraphicsPipelineStateDesc = pipelineStateDesc;
}