From 162fed8f7d71801b0a77968c2c6d0d3e97e7cc62 Mon Sep 17 00:00:00 2001 From: vladislavbelov Date: Fri, 25 Feb 2022 22:05:06 +0000 Subject: [PATCH] Moves polygon mode handling to PipelineState and CDeviceCommandContext. git-svn-id: https://svn.wildfiregames.com/public/ps/trunk@26486 3db68df2-c116-0410-a063-a993310a9797 --- .../data/mods/public/shaders/effects/model.xml | 25 ++++- .../public/shaders/effects/model_transparent.xml | 34 +++++- .../{terrain_blend.xml => particle_solid.xml} | 19 ++-- .../mods/public/shaders/effects/terrain_base.xml | 18 +++ .../mods/public/shaders/effects/terrain_blend.xml | 19 ++++ .../mods/public/shaders/effects/terrain_decal.xml | 20 ++++ .../mods/public/shaders/effects/terrain_solid.xml | 15 +++ .../mods/public/shaders/effects/water_simple.xml | 19 ++++ source/graphics/ShaderManager.cpp | 9 ++ source/ps/CStrInternStatic.h | 1 + source/renderer/DebugRenderer.cpp | 11 +- source/renderer/DebugRenderer.h | 2 +- source/renderer/DecalRData.cpp | 1 + source/renderer/OverlayRenderer.cpp | 36 ++---- source/renderer/ParticleRenderer.cpp | 16 +-- source/renderer/ParticleRenderer.h | 2 +- source/renderer/PatchRData.cpp | 3 + source/renderer/SceneRenderer.cpp | 124 +++++---------------- source/renderer/TerrainOverlay.cpp | 11 +- source/renderer/TerrainRenderer.cpp | 30 ++--- source/renderer/TerrainRenderer.h | 4 +- source/renderer/backend/PipelineState.cpp | 11 ++ source/renderer/backend/PipelineState.h | 8 ++ .../renderer/backend/gl/DeviceCommandContext.cpp | 16 ++- 24 files changed, 277 insertions(+), 177 deletions(-) copy binaries/data/mods/public/shaders/effects/{terrain_blend.xml => particle_solid.xml} (53%) diff --git a/binaries/data/mods/public/shaders/effects/model.xml b/binaries/data/mods/public/shaders/effects/model.xml index c4cbfda10e..e0b9e995a5 100644 --- a/binaries/data/mods/public/shaders/effects/model.xml +++ b/binaries/data/mods/public/shaders/effects/model.xml @@ -37,13 +37,34 @@ - + + + - + + + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/model_transparent.xml b/binaries/data/mods/public/shaders/effects/model_transparent.xml index de1dba073e..f3df901147 100644 --- a/binaries/data/mods/public/shaders/effects/model_transparent.xml +++ b/binaries/data/mods/public/shaders/effects/model_transparent.xml @@ -48,15 +48,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/terrain_blend.xml b/binaries/data/mods/public/shaders/effects/particle_solid.xml similarity index 53% copy from binaries/data/mods/public/shaders/effects/terrain_blend.xml copy to binaries/data/mods/public/shaders/effects/particle_solid.xml index b582f44dc1..0a79e92fab 100644 --- a/binaries/data/mods/public/shaders/effects/terrain_blend.xml +++ b/binaries/data/mods/public/shaders/effects/particle_solid.xml @@ -2,33 +2,32 @@ - - - - + + + - - - - + + + + - + - + diff --git a/binaries/data/mods/public/shaders/effects/terrain_base.xml b/binaries/data/mods/public/shaders/effects/terrain_base.xml index bd1f6297d9..68e5005d8b 100644 --- a/binaries/data/mods/public/shaders/effects/terrain_base.xml +++ b/binaries/data/mods/public/shaders/effects/terrain_base.xml @@ -17,6 +17,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/terrain_blend.xml b/binaries/data/mods/public/shaders/effects/terrain_blend.xml index b582f44dc1..88e2dd6f7b 100644 --- a/binaries/data/mods/public/shaders/effects/terrain_blend.xml +++ b/binaries/data/mods/public/shaders/effects/terrain_blend.xml @@ -21,6 +21,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/terrain_decal.xml b/binaries/data/mods/public/shaders/effects/terrain_decal.xml index ad020a3ed5..c1116c7bf4 100644 --- a/binaries/data/mods/public/shaders/effects/terrain_decal.xml +++ b/binaries/data/mods/public/shaders/effects/terrain_decal.xml @@ -19,6 +19,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/terrain_solid.xml b/binaries/data/mods/public/shaders/effects/terrain_solid.xml index 7989a65676..9ff43c12ec 100644 --- a/binaries/data/mods/public/shaders/effects/terrain_solid.xml +++ b/binaries/data/mods/public/shaders/effects/terrain_solid.xml @@ -26,6 +26,21 @@ + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/effects/water_simple.xml b/binaries/data/mods/public/shaders/effects/water_simple.xml index 23a7de2115..89091ee2f0 100644 --- a/binaries/data/mods/public/shaders/effects/water_simple.xml +++ b/binaries/data/mods/public/shaders/effects/water_simple.xml @@ -3,6 +3,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp index 1fbcdb8b19..34e3e5b558 100644 --- a/source/graphics/ShaderManager.cpp +++ b/source/graphics/ShaderManager.cpp @@ -332,6 +332,7 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin EL(define); EL(depth); EL(pass); + EL(polygon); EL(require); EL(sort_by_distance); EL(stencil); @@ -515,6 +516,14 @@ bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefin Element.GetAttributes().GetNamedItem(at_mask) == "true"; } } + else if (Element.GetNodeName() == el_polygon) + { + if (!Element.GetAttributes().GetNamedItem(at_mode).empty()) + { + passPipelineStateDesc.rasterizationState.polygonMode = + Renderer::Backend::ParsePolygonMode(Element.GetAttributes().GetNamedItem(at_mode)); + } + } else if (Element.GetNodeName() == el_stencil) { if (!Element.GetAttributes().GetNamedItem(at_test).empty()) diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h index 2885679f90..aef4ba4404 100644 --- a/source/ps/CStrInternStatic.h +++ b/source/ps/CStrInternStatic.h @@ -56,6 +56,7 @@ X(MODE_SHADOWCAST) X(MODE_SILHOUETTEDISPLAY) X(MODE_SILHOUETTEOCCLUDER) X(MODE_WIREFRAME) +X(MODE_WIREFRAME_SOLID) X(PASS_REFLECTIONS) X(PASS_REFRACTIONS) X(PASS_SHADOWS) diff --git a/source/renderer/DebugRenderer.cpp b/source/renderer/DebugRenderer.cpp index 8d84367e90..14bb290864 100644 --- a/source/renderer/DebugRenderer.cpp +++ b/source/renderer/DebugRenderer.cpp @@ -40,7 +40,8 @@ namespace void SetGraphicsPipelineStateFromTechAndColor( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, - const CShaderTechniquePtr& tech, const CColor& color, const bool depthTestEnabled = true) + const CShaderTechniquePtr& tech, const CColor& color, const bool depthTestEnabled = true, + const bool wireframe = false) { Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc = tech->GetGraphicsPipelineStateDesc(); pipelineStateDesc.depthStencilState.depthTestEnabled = depthTestEnabled; @@ -56,6 +57,8 @@ void SetGraphicsPipelineStateFromTechAndColor( } else pipelineStateDesc.blendState.enabled = false; + if (wireframe) + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE; deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); } @@ -174,7 +177,7 @@ void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, con #endif } -void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates) +void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates, bool wireframe) { #if CONFIG2_GLES UNUSED2(camera); UNUSED2(color); UNUSED2(intermediates); @@ -194,7 +197,7 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo CShaderTechniquePtr overlayTech = g_Renderer.GetShaderManager().LoadEffect(str_debug_line); overlayTech->BeginPass(); - SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), overlayTech, color); + SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), overlayTech, color, true, wireframe); CShaderProgramPtr overlayShader = overlayTech->GetShader(); overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection()); @@ -322,7 +325,7 @@ void CDebugRenderer::DrawBoundingBoxOutline(const CBoundingBoxAligned& boundingB { CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid); shaderTech->BeginPass(); - SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), shaderTech, color); + SetGraphicsPipelineStateFromTechAndColor(g_Renderer.GetDeviceCommandContext(), shaderTech, color, true, true); CShaderProgramPtr shader = shaderTech->GetShader(); shader->Uniform(str_color, color); diff --git a/source/renderer/DebugRenderer.h b/source/renderer/DebugRenderer.h index cf156f27e8..1e10ede349 100644 --- a/source/renderer/DebugRenderer.h +++ b/source/renderer/DebugRenderer.h @@ -52,7 +52,7 @@ public: * @param intermediates determines how many intermediate distance planes should * be hinted at between the near and far planes */ - void DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates = 0); + void DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates = 0, bool wireframe = false); /** * Render the surfaces of the bound box as triangles. diff --git a/source/renderer/DecalRData.cpp b/source/renderer/DecalRData.cpp index d5f2e3d80f..69cd011468 100644 --- a/source/renderer/DecalRData.cpp +++ b/source/renderer/DecalRData.cpp @@ -92,6 +92,7 @@ void CDecalRData::RenderDecals( const std::vector& decals, const CShaderDefines& context, ShadowMap* shadow) { PROFILE3("render terrain decals"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain decals"); using Arena = Allocators::DynamicArena<256 * KiB>; diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp index eefd189ba2..bd8d603558 100644 --- a/source/renderer/OverlayRenderer.cpp +++ b/source/renderer/OverlayRenderer.cpp @@ -430,6 +430,8 @@ void OverlayRenderer::RenderTexturedOverlayLines(Renderer::Backend::GL::CDeviceC Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA; pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp = Renderer::Backend::BlendOp::ADD; + if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; shaderTechTexLineNormal->BeginPass(); deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); @@ -461,6 +463,8 @@ void OverlayRenderer::RenderTexturedOverlayLines(Renderer::Backend::GL::CDeviceC Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA; pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp = Renderer::Backend::BlendOp::ADD; + if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; shaderTechTexLineAlwaysVisible->BeginPass(); deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); @@ -491,10 +495,6 @@ void OverlayRenderer::RenderTexturedOverlayLines( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, const CShaderProgramPtr& shader, bool alwaysVisible) { -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -#endif for (size_t i = 0; i < m->texlines.size(); ++i) { SOverlayTexturedLine* line = m->texlines[i]; @@ -506,10 +506,6 @@ void OverlayRenderer::RenderTexturedOverlayLines( ENSURE(line->m_RenderData); line->m_RenderData->Render(deviceCommandContext, *line, shader); } -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif } void OverlayRenderer::RenderQuadOverlays( @@ -537,15 +533,12 @@ void OverlayRenderer::RenderQuadOverlays( Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA; pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp = Renderer::Backend::BlendOp::ADD; + if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; shaderTech->BeginPass(); deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); - CShaderProgramPtr shader = shaderTech->GetShader(); - -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -#endif + const CShaderProgramPtr& shader = shaderTech->GetShader(); CLOSTexture& los = g_Renderer.GetSceneRenderer().GetScene().GetLOSTexture(); @@ -604,11 +597,6 @@ void OverlayRenderer::RenderQuadOverlays( deviceCommandContext->BindTexture(0, GL_TEXTURE_2D, 0); CVertexBuffer::Unbind(deviceCommandContext); - -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif } void OverlayRenderer::RenderForegroundOverlays( @@ -622,9 +610,6 @@ void OverlayRenderer::RenderForegroundOverlays( UNUSED2(viewCamera); #warning TODO: implement OverlayRenderer::RenderForegroundOverlays for GLES #else - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - CVector3D right = -viewCamera.GetOrientation().GetLeft(); CVector3D up = viewCamera.GetOrientation().GetUp(); @@ -639,10 +624,12 @@ void OverlayRenderer::RenderForegroundOverlays( Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA; pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp = Renderer::Backend::BlendOp::ADD; + if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; tech->BeginPass(); deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); - CShaderProgramPtr shader = tech->GetShader(); + const CShaderProgramPtr& shader = tech->GetShader(); shader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection()); @@ -688,9 +675,6 @@ void OverlayRenderer::RenderForegroundOverlays( } tech->EndPass(); - - if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif } diff --git a/source/renderer/ParticleRenderer.cpp b/source/renderer/ParticleRenderer.cpp index a23b3f5af5..40b952b6f6 100644 --- a/source/renderer/ParticleRenderer.cpp +++ b/source/renderer/ParticleRenderer.cpp @@ -36,7 +36,7 @@ struct ParticleRendererInternals CShaderTechniquePtr techSubtract; CShaderTechniquePtr techOverlay; CShaderTechniquePtr techMultiply; - CShaderTechniquePtr techSolid; + CShaderTechniquePtr techWireframe; std::vector emitters[CSceneRenderer::CULL_MAX]; }; @@ -90,13 +90,15 @@ void ParticleRenderer::PrepareForRendering(const CShaderDefines& context) // Can't load the shader in the constructor because it's called before the // renderer initialisation is complete, so load it the first time through here - if (!m->techSolid) + if (!m->techWireframe) { m->techAdd = g_Renderer.GetShaderManager().LoadEffect(str_particle_add, context); m->techSubtract = g_Renderer.GetShaderManager().LoadEffect(str_particle_subtract, context); m->techOverlay = g_Renderer.GetShaderManager().LoadEffect(str_particle_overlay, context); m->techMultiply = g_Renderer.GetShaderManager().LoadEffect(str_particle_multiply, context); - m->techSolid = g_Renderer.GetShaderManager().LoadEffect(str_particle_solid, context); + CShaderDefines contextWithWireframe = context; + contextWithWireframe.Add(str_MODE_WIREFRAME, str_1); + m->techWireframe = g_Renderer.GetShaderManager().LoadEffect(str_particle_solid, contextWithWireframe); } ++m->frameNumber; @@ -126,15 +128,15 @@ void ParticleRenderer::PrepareForRendering(const CShaderDefines& context) void ParticleRenderer::RenderParticles( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, - int cullGroup, bool solidColor) + int cullGroup, bool wireframe) { CShaderTechnique* lastTech = nullptr; for (CParticleEmitter* emitter : m->emitters[cullGroup]) { CShaderTechnique* currentTech = nullptr; - if (solidColor) + if (wireframe) { - currentTech = m->techSolid.get(); + currentTech = m->techWireframe.get(); } else { @@ -173,6 +175,6 @@ void ParticleRenderer::RenderBounds(int cullGroup) { const CBoundingBoxAligned bounds = emitter->m_Type->CalculateBounds(emitter->GetPosition(), emitter->GetParticleBounds()); - g_Renderer.GetDebugRenderer().DrawBoundingBox(bounds, CColor(0.0f, 1.0f, 0.0f, 1.0f)); + g_Renderer.GetDebugRenderer().DrawBoundingBoxOutline(bounds, CColor(0.0f, 1.0f, 0.0f, 1.0f)); } } diff --git a/source/renderer/ParticleRenderer.h b/source/renderer/ParticleRenderer.h index 9ced407d7b..7910807dad 100644 --- a/source/renderer/ParticleRenderer.h +++ b/source/renderer/ParticleRenderer.h @@ -57,7 +57,7 @@ public: */ void RenderParticles( Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, - int cullGroup, bool solidColor = false); + int cullGroup, bool wireframe = false); /** * Render bounding boxes for all the submitted emitters. diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index d27fe12a64..b4cd84c4ab 100644 --- a/source/renderer/PatchRData.cpp +++ b/source/renderer/PatchRData.cpp @@ -714,6 +714,7 @@ void CPatchRData::RenderBases( const std::vector& patches, const CShaderDefines& context, ShadowMap* shadow) { PROFILE3("render terrain bases"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain bases"); Arena arena; @@ -865,6 +866,7 @@ void CPatchRData::RenderBlends( const std::vector& patches, const CShaderDefines& context, ShadowMap* shadow) { PROFILE3("render terrain blends"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain blends"); Arena arena; @@ -1158,6 +1160,7 @@ void CPatchRData::RenderSides( const std::vector& patches, const CShaderProgramPtr& shader) { PROFILE3("render terrain sides"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain sides"); CVertexBuffer* lastVB = nullptr; for (CPatchRData* patch : patches) diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp index efa2c8cb0a..031633a130 100644 --- a/source/renderer/SceneRenderer.cpp +++ b/source/renderer/SceneRenderer.cpp @@ -339,48 +339,27 @@ void CSceneRenderer::RenderPatches( PROFILE3_GPU("patches"); GPU_SCOPED_LABEL(deviceCommandContext, "Render patches"); -#if CONFIG2_GLES -#warning TODO: implement wireface/edged rendering mode GLES -#else - // switch on wireframe if we need it + // Switch on wireframe if we need it. + CShaderDefines localContext = context; if (m_TerrainRenderMode == WIREFRAME) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } -#endif + localContext.Add(str_MODE_WIREFRAME, str_1); - // render all the patches, including blend pass - m->terrainRenderer.RenderTerrainShader(deviceCommandContext, context, cullGroup, + // Render all the patches, including blend pass. + m->terrainRenderer.RenderTerrainShader(deviceCommandContext, localContext, cullGroup, g_RenderingOptions.GetShadows() ? &m->shadow : nullptr); -#if !CONFIG2_GLES - if (m_TerrainRenderMode == WIREFRAME) - { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else if (m_TerrainRenderMode == EDGED_FACES) + if (m_TerrainRenderMode == EDGED_FACES) { - // edged faces: need to make a second pass over the data: - // first switch on wireframe - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + localContext.Add(str_MODE_WIREFRAME, str_1); + // Edged faces: need to make a second pass over the data. - // setup some renderstate .. - glLineWidth(2.0f); + // Render tiles edges. + m->terrainRenderer.RenderPatches( + deviceCommandContext, cullGroup, localContext, CColor(0.5f, 0.5f, 1.0f, 1.0f)); - // render tiles edges - m->terrainRenderer.RenderPatches(deviceCommandContext, cullGroup, context, CColor(0.5f, 0.5f, 1.0f, 1.0f)); - - glLineWidth(4.0f); - - // render outline of each patch - m->terrainRenderer.RenderOutlines(cullGroup); - - // .. and restore the renderstates - glLineWidth(1.0f); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + // Render outline of each patch. + m->terrainRenderer.RenderOutlines(deviceCommandContext, cullGroup); } -#endif } void CSceneRenderer::RenderModels( @@ -392,32 +371,18 @@ void CSceneRenderer::RenderModels( int flags = 0; -#if !CONFIG2_GLES - if (m_ModelRenderMode == WIREFRAME) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } -#endif - - m->CallModelRenderers(deviceCommandContext, context, cullGroup, flags); + CShaderDefines localContext = context; -#if !CONFIG2_GLES if (m_ModelRenderMode == WIREFRAME) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else if (m_ModelRenderMode == EDGED_FACES) - { - CShaderDefines contextWireframe = context; - contextWireframe.Add(str_MODE_WIREFRAME, str_1); - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + localContext.Add(str_MODE_WIREFRAME, str_1); - m->CallModelRenderers(deviceCommandContext, contextWireframe, cullGroup, flags); + m->CallModelRenderers(deviceCommandContext, localContext, cullGroup, flags); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (m_ModelRenderMode == EDGED_FACES) + { + localContext.Add(str_MODE_WIREFRAME_SOLID, str_1); + m->CallModelRenderers(deviceCommandContext, localContext, cullGroup, flags); } -#endif } void CSceneRenderer::RenderTransparentModels( @@ -429,44 +394,31 @@ void CSceneRenderer::RenderTransparentModels( int flags = 0; -#if !CONFIG2_GLES - // switch on wireframe if we need it - if (m_ModelRenderMode == WIREFRAME) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } -#endif - CShaderDefines contextOpaque = context; contextOpaque.Add(str_ALPHABLEND_PASS_OPAQUE, str_1); CShaderDefines contextBlend = context; contextBlend.Add(str_ALPHABLEND_PASS_BLEND, str_1); + if (m_ModelRenderMode == WIREFRAME) + { + contextOpaque.Add(str_MODE_WIREFRAME, str_1); + contextBlend.Add(str_MODE_WIREFRAME, str_1); + } + if (transparentMode == TRANSPARENT || transparentMode == TRANSPARENT_OPAQUE) m->CallTranspModelRenderers(deviceCommandContext, contextOpaque, cullGroup, flags); if (transparentMode == TRANSPARENT || transparentMode == TRANSPARENT_BLEND) m->CallTranspModelRenderers(deviceCommandContext, contextBlend, cullGroup, flags); -#if !CONFIG2_GLES - if (m_ModelRenderMode == WIREFRAME) - { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else if (m_ModelRenderMode == EDGED_FACES) + if (m_ModelRenderMode == EDGED_FACES) { CShaderDefines contextWireframe = contextOpaque; contextWireframe.Add(str_MODE_WIREFRAME, str_1); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - m->CallTranspModelRenderers(deviceCommandContext, contextWireframe, cullGroup, flags); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } -#endif } // SetObliqueFrustumClipping: change the near plane to the given clip plane (in world space) @@ -791,20 +743,14 @@ void CSceneRenderer::RenderParticles( GPU_SCOPED_LABEL(deviceCommandContext, "Render particles"); m->particleRenderer.RenderParticles( - deviceCommandContext, cullGroup); + deviceCommandContext, cullGroup, m_ModelRenderMode == WIREFRAME); -#if !CONFIG2_GLES if (m_ModelRenderMode == EDGED_FACES) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - m->particleRenderer.RenderParticles( deviceCommandContext, cullGroup, true); m->particleRenderer.RenderBounds(cullGroup); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } -#endif } // RenderSubmissions: force rendering of any batched objects @@ -1006,22 +952,10 @@ void CSceneRenderer::EndFrame() m->Model.TranspUnskinned->EndFrame(); } -// DisplayFrustum: debug displays -// - white: cull camera frustum -// - red: bounds of shadow casting objects void CSceneRenderer::DisplayFrustum() { -#if CONFIG2_GLES -#warning TODO: implement CSceneRenderer::DisplayFrustum for GLES -#else g_Renderer.GetDebugRenderer().DrawCameraFrustum(m_CullCamera, CColor(1.0f, 1.0f, 1.0f, 0.25f), 2); - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - g_Renderer.GetDebugRenderer().DrawCameraFrustum(m_CullCamera, CColor(1.0f, 1.0f, 1.0f, 1.0f), 2); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif - - ogl_WarnIfError(); + g_Renderer.GetDebugRenderer().DrawCameraFrustum(m_CullCamera, CColor(1.0f, 1.0f, 1.0f, 1.0f), 2, true); } // Text overlay rendering diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp index 16e1eb480b..b4236a5457 100644 --- a/source/renderer/TerrainOverlay.cpp +++ b/source/renderer/TerrainOverlay.cpp @@ -152,7 +152,6 @@ void TerrainOverlay::RenderBeforeWater( //glDisable(GL_POLYGON_OFFSET_LINE); glDisable(GL_POLYGON_OFFSET_FILL); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif } @@ -238,7 +237,6 @@ void TerrainOverlay::RenderTile( overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data()); overlayShader->AssertPointersBound(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3); overlayTech->EndPass(); @@ -266,11 +264,6 @@ void TerrainOverlay::RenderTileOutline( #warning TODO: implement TerrainOverlay::RenderTileOutline for GLES #else - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - if (lineWidth != 1) - glLineWidth(static_cast(lineWidth)); - std::vector vertices; #define ADD(i, j) \ m_Terrain->CalcPosition(i, j, position); \ @@ -299,9 +292,13 @@ void TerrainOverlay::RenderTileOutline( Renderer::Backend::BlendOp::ADD; pipelineStateDesc.rasterizationState.cullMode = drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK; + pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE; overlayTech->BeginPass(); deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); + if (lineWidth != 1) + glLineWidth(static_cast(lineWidth)); + const CShaderProgramPtr& overlayShader = overlayTech->GetShader(); overlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection()); diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 8f0db6d83e..40e434583d 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -299,6 +299,8 @@ void TerrainRenderer::RenderPatches( if (visiblePatches.empty()) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain patches"); + #if CONFIG2_GLES UNUSED2(deviceCommandContext); UNUSED2(defines); @@ -323,7 +325,9 @@ void TerrainRenderer::RenderPatches( /////////////////////////////////////////////////////////////////// // Render outlines of submitted patches as lines -void TerrainRenderer::RenderOutlines(int cullGroup) +void TerrainRenderer::RenderOutlines( + Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, + int cullGroup) { ENSURE(m->phase == Phase_Render); @@ -331,6 +335,8 @@ void TerrainRenderer::RenderOutlines(int cullGroup) if (visiblePatches.empty()) return; + GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain outlines"); + for (size_t i = 0; i < visiblePatches.size(); ++i) visiblePatches[i]->RenderOutline(); } @@ -405,11 +411,6 @@ bool TerrainRenderer::RenderFancyWater( const double time = waterManager.m_WaterTexTimer; const float repeatPeriod = waterManager.m_RepeatPeriod; -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -#endif - m->fancyWaterTech->BeginPass(); deviceCommandContext->SetGraphicsPipelineState( m->fancyWaterTech->GetGraphicsPipelineStateDesc()); @@ -505,11 +506,6 @@ bool TerrainRenderer::RenderFancyWater( } m->fancyWaterTech->EndPass(); -#if !CONFIG2_GLES - if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif - return true; } @@ -527,13 +523,14 @@ void TerrainRenderer::RenderSimpleWater( const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager(); CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); - if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - const double time = waterManager.m_WaterTexTimer; + CShaderDefines context; + if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME) + context.Add(str_MODE_WIREFRAME, str_1); + CShaderTechniquePtr waterSimpleTech = - g_Renderer.GetShaderManager().LoadEffect(str_water_simple); + g_Renderer.GetShaderManager().LoadEffect(str_water_simple, context); waterSimpleTech->BeginPass(); deviceCommandContext->SetGraphicsPipelineState( waterSimpleTech->GetGraphicsPipelineStateDesc()); @@ -558,9 +555,6 @@ void TerrainRenderer::RenderSimpleWater( deviceCommandContext->BindTexture(1, GL_TEXTURE_2D, 0); waterSimpleTech->EndPass(); - - if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif } diff --git a/source/renderer/TerrainRenderer.h b/source/renderer/TerrainRenderer.h index 7afedf5e54..8757a85b96 100644 --- a/source/renderer/TerrainRenderer.h +++ b/source/renderer/TerrainRenderer.h @@ -127,7 +127,9 @@ public: * * @param filtered If true then only render objects that passed CullPatches. */ - void RenderOutlines(int cullGroup); + void RenderOutlines( + Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, + int cullGroup); /** * RenderWater: Render water for all patches that have been submitted diff --git a/source/renderer/backend/PipelineState.cpp b/source/renderer/backend/PipelineState.cpp index 3a2606b1f1..b1cc0d8411 100644 --- a/source/renderer/backend/PipelineState.cpp +++ b/source/renderer/backend/PipelineState.cpp @@ -54,6 +54,7 @@ GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc() desc.blendState.colorWriteMask = ColorWriteMask::RED | ColorWriteMask::GREEN | ColorWriteMask::BLUE | ColorWriteMask::ALPHA; + desc.rasterizationState.polygonMode = PolygonMode::FILL; desc.rasterizationState.cullMode = CullMode::BACK; desc.rasterizationState.frontFace = FrontFace::COUNTER_CLOCKWISE; return desc; @@ -116,6 +117,16 @@ BlendOp ParseBlendOp(const CStr& str) return BlendOp::ADD; } +PolygonMode ParsePolygonMode(const CStr& str) +{ + if (str == "FILL") + return PolygonMode::FILL; + else if (str == "LINE") + return PolygonMode::LINE; + debug_warn("Invalid polygon mode"); + return PolygonMode::FILL; +} + CullMode ParseCullMode(const CStr& str) { if (str == "NONE") diff --git a/source/renderer/backend/PipelineState.h b/source/renderer/backend/PipelineState.h index c5de53bd40..d14dc48430 100644 --- a/source/renderer/backend/PipelineState.h +++ b/source/renderer/backend/PipelineState.h @@ -130,6 +130,12 @@ struct BlendStateDesc uint8_t colorWriteMask; }; +enum class PolygonMode +{ + FILL, + LINE +}; + enum class CullMode { NONE, @@ -145,6 +151,7 @@ enum class FrontFace struct RasterizationStateDesc { + PolygonMode polygonMode; CullMode cullMode; FrontFace frontFace; }; @@ -166,6 +173,7 @@ StencilOp ParseStencilOp(const CStr& str); BlendFactor ParseBlendFactor(const CStr& str); BlendOp ParseBlendOp(const CStr& str); +PolygonMode ParsePolygonMode(const CStr& str); CullMode ParseCullMode(const CStr& str); FrontFace ParseFrontFace(const CStr& str); diff --git a/source/renderer/backend/gl/DeviceCommandContext.cpp b/source/renderer/backend/gl/DeviceCommandContext.cpp index 600113d310..1d0407ba6b 100644 --- a/source/renderer/backend/gl/DeviceCommandContext.cpp +++ b/source/renderer/backend/gl/DeviceCommandContext.cpp @@ -552,8 +552,20 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl( ApplyColorMask(nextBlendStateDesc.colorWriteMask); } - const RasterizationStateDesc& currentRasterizationStateDesc = m_GraphicsPipelineStateDesc.rasterizationState; - const RasterizationStateDesc& nextRasterizationStateDesc = pipelineStateDesc.rasterizationState; + const RasterizationStateDesc& currentRasterizationStateDesc = + m_GraphicsPipelineStateDesc.rasterizationState; + const RasterizationStateDesc& nextRasterizationStateDesc = + pipelineStateDesc.rasterizationState; + if (force || + currentRasterizationStateDesc.polygonMode != nextRasterizationStateDesc.polygonMode) + { +#if !CONFIG2_GLES + glPolygonMode( + GL_FRONT_AND_BACK, + nextRasterizationStateDesc.polygonMode == PolygonMode::LINE ? GL_LINE : GL_FILL); +#endif + } + if (force || currentRasterizationStateDesc.cullMode != nextRasterizationStateDesc.cullMode) { -- 2.11.4.GIT