1
0
forked from 0ad/0ad

Moves culling mode and front face state management to DeviceCommandContext.

Tested By: Langbart
Differential Revision: https://code.wildfiregames.com/D4456
This was SVN commit r26259.
This commit is contained in:
Vladislav Belov 2022-01-27 17:25:37 +00:00
parent 299cb3d34b
commit d4d1bc039f
21 changed files with 370 additions and 200 deletions

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="arb"/>
<pass shader="arb/model_common">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="glsl"/>
<pass shader="glsl/model_common">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="MODE_SHADOWCAST || MODE_SILHOUETTEOCCLUDER"/>
<require shaders="arb"/>

View File

@ -6,6 +6,8 @@
<require shaders="arb"/>
<pass shader="arb/model_solid_tex">
<define name="REQUIRE_ALPHA_GEQUAL" value="0.4"/>
<!-- Disable face-culling for two-sided models -->
<cull mode="NONE"/>
</pass>
</technique>
@ -14,11 +16,11 @@
<require shaders="glsl"/>
<pass shader="glsl/model_solid_tex">
<define name="REQUIRE_ALPHA_GEQUAL" value="0.4"/>
<!-- Disable face-culling for two-sided models -->
<cull mode="NONE"/>
</pass>
</technique>
<!--
CRenderer::RenderSilhouettes skips alpha-blended models for
MODE_SILHOUETTEDISPLAY, so do a dummy non-blended behaviour here to
@ -37,6 +39,53 @@
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require context="ALPHABLEND_PASS_OPAQUE"/>
<require shaders="arb"/>
<pass shader="arb/model_common">
<define name="USE_TRANSPARENT" value="1"/>
<define name="REQUIRE_ALPHA_GEQUAL" value="0.6375"/>
<cull mode="NONE"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require context="ALPHABLEND_PASS_OPAQUE"/>
<require shaders="glsl"/>
<pass shader="glsl/model_common">
<define name="USE_TRANSPARENT" value="1"/>
<define name="REQUIRE_ALPHA_GEQUAL" value="0.6375"/>
<cull mode="NONE"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require context="ALPHABLEND_PASS_BLEND"/>
<require shaders="arb"/>
<pass shader="arb/model_common">
<define name="USE_TRANSPARENT" value="1"/>
<define name="REQUIRE_ALPHA_GEQUAL" value="0.05"/>
<blend src="src_alpha" dst="one_minus_src_alpha"/>
<depth func="less" mask="false"/>
<cull mode="NONE"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require context="ALPHABLEND_PASS_BLEND"/>
<require shaders="glsl"/>
<pass shader="glsl/model_common">
<define name="USE_TRANSPARENT" value="1"/>
<define name="REQUIRE_ALPHA_GEQUAL" value="0.05"/>
<blend src="src_alpha" dst="one_minus_src_alpha"/>
<depth func="less" mask="false"/>
<cull mode="NONE"/>
</pass>
</technique>
<technique>
<require context="ALPHABLEND_PASS_OPAQUE"/>

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="arb"/>
<pass shader="arb/terrain_base">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="glsl"/>
<pass shader="glsl/terrain_base">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require shaders="arb"/>
<pass shader="arb/terrain_base"/>

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="arb"/>
<pass shader="arb/terrain_blend">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="glsl"/>
<pass shader="glsl/terrain_blend">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require shaders="arb"/>
<pass shader="arb/terrain_blend"/>

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="arb"/>
<pass shader="arb/terrain_decal">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="PASS_REFLECTIONS"/>
<require shaders="glsl"/>
<pass shader="glsl/terrain_decal">
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require shaders="arb"/>
<pass shader="arb/terrain_decal"/>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<effect>
<technique>
<require context="PASS_SHADOWS || MODE_SILHOUETTEOCCLUDER"/>
<require shaders="arb"/>
<pass shader="arb/dummy">
<!-- See GLSL -->
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require context="PASS_SHADOWS || MODE_SILHOUETTEOCCLUDER"/>
<require shaders="glsl"/>
<pass shader="glsl/dummy">
<!--
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).
-->
<cull mode="FRONT"/>
</pass>
</technique>
<technique>
<require shaders="arb"/>
<pass shader="arb/dummy"/>
</technique>
<technique>
<require shaders="glsl"/>
<pass shader="glsl/dummy"/>
</technique>
</effect>

View File

@ -352,6 +352,7 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
#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 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
AT(constant);
AT(context);
AT(dst);
AT(front_face);
AT(func);
AT(mode);
AT(op);
AT(shader);
AT(shaders);
@ -493,6 +496,19 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin
}
}
}
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)
{
if (!Element.GetAttributes().GetNamedItem(at_func).empty())

View File

@ -56,6 +56,9 @@ X(MODE_SHADOWCAST)
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(sky_simple)
X(solid)
X(sunColor)
X(sunDir)
X(terrain_solid)
X(tex)
X(texSize)
X(textureTransform)

View File

@ -55,6 +55,7 @@ void SetGraphicsPipelineStateFromTechAndColor(
}
else
pipelineStateDesc.blendState.enabled = false;
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
}

View File

@ -1133,8 +1133,6 @@ void CPatchRData::RenderSides(const std::vector<CPatchRData*>& patches, const CS
{
PROFILE3("render terrain sides");
glDisable(GL_CULL_FACE);
CVertexBuffer* lastVB = nullptr;
for (CPatchRData* patch : patches)
{
@ -1161,8 +1159,6 @@ void CPatchRData::RenderSides(const std::vector<CPatchRData*>& patches, const CS
}
CVertexBuffer::Unbind();
glEnable(GL_CULL_FACE);
}
void CPatchRData::RenderPriorities(CTextRenderer& textRenderer)

View File

@ -308,7 +308,10 @@ void CSceneRenderer::RenderShadowMap(
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 @@ void CSceneRenderer::RenderShadowMap(
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 @@ void CSceneRenderer::RenderShadowMap(
{
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 @@ void CSceneRenderer::RenderPatches(
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::RenderModels(
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 @@ void CSceneRenderer::RenderTransparentModels(
}
#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 @@ void CSceneRenderer::RenderTransparentModels(
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 @@ void CSceneRenderer::RenderReflections(
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 @@ void CSceneRenderer::RenderReflections(
}
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 @@ void CSceneRenderer::RenderRefractions(
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 @@ void CSceneRenderer::RenderSilhouettes(
{
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 @@ void CSceneRenderer::RenderSubmissions(
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 @@ void CSceneRenderer::RenderSubmissions(
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 @@ void CSceneRenderer::DisplayFrustum()
#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 @@ void CSceneRenderer::DisplayFrustum()
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

View File

@ -208,7 +208,7 @@ protected:
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,

View File

@ -727,7 +727,6 @@ void ShadowMap::SetDepthTextureBits(int bits)
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 @@ void ShadowMap::RenderDebugBounds()
g_Renderer.GetDebugRenderer().DrawBrushOutline(frustumBrush, CColor(1.0f, 0.0f, 0.0f, 0.5f));
}
glEnable(GL_CULL_FACE);
glDepthMask(1);
ogl_WarnIfError();

View File

@ -451,7 +451,6 @@ void SilhouetteRenderer::RenderDebugOverlays(
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 @@ void SilhouetteRenderer::RenderDebugOverlays(
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 @@ void SilhouetteRenderer::RenderDebugOverlays(
shaderTech->EndPass();
glEnable(GL_CULL_FACE);
glDepthMask(1);
}

View File

@ -151,7 +151,6 @@ void TerrainOverlay::RenderBeforeWater(
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::RenderBeforeWater(
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 @@ void TerrainOverlay::RenderTile(
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,30 +257,28 @@ void TerrainOverlay::RenderTile(
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
UNUSED2(deviceCommandContext);
UNUSED2(color);
UNUSED2(line_width);
UNUSED2(lineWidth);
UNUSED2(i);
UNUSED2(j);
#warning TODO: implement TerrainOverlay::RenderTileOutline for GLES
@ -289,8 +286,8 @@ void TerrainOverlay::RenderTileOutline(
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (line_width != 1)
glLineWidth((float)line_width);
if (lineWidth != 1)
glLineWidth(static_cast<float>(lineWidth));
std::vector<float> vertices;
#define ADD(i, j) \
@ -317,10 +314,12 @@ void TerrainOverlay::RenderTileOutline(
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 @@ void TerrainOverlay::RenderTileOutline(
overlayTech->EndPass();
if (line_width != 1)
if (lineWidth != 1)
glLineWidth(1.0f);
#endif
}

View File

@ -136,38 +136,38 @@ protected:
* Draw a filled quad on top of the current tile.
*
* @param color color to draw. May be transparent (alpha &lt; 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 &lt; 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

View File

@ -265,8 +265,10 @@ void TerrainRenderer::RenderTerrainShader(
// 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 @@ void TerrainRenderer::RenderTerrainShader(
// 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);
@ -309,21 +311,22 @@ void TerrainRenderer::RenderPatches(
#if CONFIG2_GLES
UNUSED2(deviceCommandContext);
UNUSED2(defines);
UNUSED2(color);
#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 +606,13 @@ void TerrainRenderer::RenderWaterFoamOccluders(
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 +621,6 @@ void TerrainRenderer::RenderWaterFoamOccluders(
data->RenderWaterShore(dummyShader);
dummyTech->EndPass();
glEnable(GL_CULL_FACE);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

View File

@ -115,7 +115,8 @@ public:
*/
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.

View File

@ -199,9 +199,6 @@ std::unique_ptr<CDevice> CDevice::Create(SDL_Window* window, const bool arb)
// Setup default state.
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
return device;
}

View File

@ -194,6 +194,32 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
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;
}