LCOV - code coverage report
Current view: top level - source/renderer - TerrainRenderer.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 301 0.0 %
Date: 2022-03-08 13:03:03 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "renderer/TerrainRenderer.h"
      21             : 
      22             : #include "graphics/Camera.h"
      23             : #include "graphics/Canvas2D.h"
      24             : #include "graphics/Decal.h"
      25             : #include "graphics/GameView.h"
      26             : #include "graphics/LightEnv.h"
      27             : #include "graphics/LOSTexture.h"
      28             : #include "graphics/Patch.h"
      29             : #include "graphics/Model.h"
      30             : #include "graphics/ShaderManager.h"
      31             : #include "graphics/TerritoryTexture.h"
      32             : #include "graphics/TextRenderer.h"
      33             : #include "graphics/TextureManager.h"
      34             : #include "maths/MathUtil.h"
      35             : #include "ps/CLogger.h"
      36             : #include "ps/CStrInternStatic.h"
      37             : #include "ps/Filesystem.h"
      38             : #include "ps/Game.h"
      39             : #include "ps/Profile.h"
      40             : #include "ps/World.h"
      41             : #include "renderer/backend/gl/Device.h"
      42             : #include "renderer/DecalRData.h"
      43             : #include "renderer/PatchRData.h"
      44             : #include "renderer/Renderer.h"
      45             : #include "renderer/RenderingOptions.h"
      46             : #include "renderer/SceneRenderer.h"
      47             : #include "renderer/ShadowMap.h"
      48             : #include "renderer/SkyManager.h"
      49             : #include "renderer/VertexArray.h"
      50             : #include "renderer/WaterManager.h"
      51             : 
      52             : /**
      53             :  * TerrainRenderer keeps track of which phase it is in, to detect
      54             :  * when Submit, PrepareForRendering etc. are called in the wrong order.
      55             :  */
      56             : enum Phase
      57             : {
      58             :     Phase_Submit,
      59             :     Phase_Render
      60             : };
      61             : 
      62             : 
      63             : /**
      64             :  * Struct TerrainRendererInternals: Internal variables used by the TerrainRenderer class.
      65             :  */
      66           0 : struct TerrainRendererInternals
      67             : {
      68             :     /// Which phase (submitting or rendering patches) are we in right now?
      69             :     Phase phase;
      70             : 
      71             :     /// Patches that were submitted for this frame
      72             :     std::vector<CPatchRData*> visiblePatches[CSceneRenderer::CULL_MAX];
      73             : 
      74             :     /// Decals that were submitted for this frame
      75             :     std::vector<CDecalRData*> visibleDecals[CSceneRenderer::CULL_MAX];
      76             : 
      77             :     /// Fancy water shader
      78             :     CShaderTechniquePtr fancyWaterTech;
      79             : 
      80             :     CSimulation2* simulation;
      81             : };
      82             : 
      83             : 
      84             : 
      85             : ///////////////////////////////////////////////////////////////////
      86             : // Construction/Destruction
      87           0 : TerrainRenderer::TerrainRenderer()
      88             : {
      89           0 :     m = new TerrainRendererInternals();
      90           0 :     m->phase = Phase_Submit;
      91           0 : }
      92             : 
      93           0 : TerrainRenderer::~TerrainRenderer()
      94             : {
      95           0 :     delete m;
      96           0 : }
      97             : 
      98           0 : void TerrainRenderer::SetSimulation(CSimulation2* simulation)
      99             : {
     100           0 :     m->simulation = simulation;
     101           0 : }
     102             : 
     103             : ///////////////////////////////////////////////////////////////////
     104             : // Submit a patch for rendering
     105           0 : void TerrainRenderer::Submit(int cullGroup, CPatch* patch)
     106             : {
     107           0 :     ENSURE(m->phase == Phase_Submit);
     108             : 
     109           0 :     CPatchRData* data = (CPatchRData*)patch->GetRenderData();
     110           0 :     if (data == 0)
     111             :     {
     112             :         // no renderdata for patch, create it now
     113           0 :         data = new CPatchRData(patch, m->simulation);
     114           0 :         patch->SetRenderData(data);
     115             :     }
     116           0 :     data->Update(m->simulation);
     117             : 
     118           0 :     m->visiblePatches[cullGroup].push_back(data);
     119           0 : }
     120             : 
     121             : ///////////////////////////////////////////////////////////////////
     122             : // Submit a decal for rendering
     123           0 : void TerrainRenderer::Submit(int cullGroup, CModelDecal* decal)
     124             : {
     125           0 :     ENSURE(m->phase == Phase_Submit);
     126             : 
     127           0 :     CDecalRData* data = (CDecalRData*)decal->GetRenderData();
     128           0 :     if (data == 0)
     129             :     {
     130             :         // no renderdata for decal, create it now
     131           0 :         data = new CDecalRData(decal, m->simulation);
     132           0 :         decal->SetRenderData(data);
     133             :     }
     134           0 :     data->Update(m->simulation);
     135             : 
     136           0 :     m->visibleDecals[cullGroup].push_back(data);
     137           0 : }
     138             : 
     139             : ///////////////////////////////////////////////////////////////////
     140             : // Prepare for rendering
     141           0 : void TerrainRenderer::PrepareForRendering()
     142             : {
     143           0 :     ENSURE(m->phase == Phase_Submit);
     144             : 
     145           0 :     m->phase = Phase_Render;
     146           0 : }
     147             : 
     148             : ///////////////////////////////////////////////////////////////////
     149             : // Clear submissions lists
     150           0 : void TerrainRenderer::EndFrame()
     151             : {
     152           0 :     ENSURE(m->phase == Phase_Render || m->phase == Phase_Submit);
     153             : 
     154           0 :     for (int i = 0; i < CSceneRenderer::CULL_MAX; ++i)
     155             :     {
     156           0 :         m->visiblePatches[i].clear();
     157           0 :         m->visibleDecals[i].clear();
     158             :     }
     159             : 
     160           0 :     m->phase = Phase_Submit;
     161           0 : }
     162             : 
     163           0 : void TerrainRenderer::RenderTerrainOverlayTexture(
     164             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     165             :     int cullGroup, CMatrix3D& textureMatrix,
     166             :     Renderer::Backend::GL::CTexture* texture)
     167             : {
     168             : #if CONFIG2_GLES
     169             : #warning TODO: implement TerrainRenderer::RenderTerrainOverlayTexture for GLES
     170             :     UNUSED2(deviceCommandContext);
     171             :     UNUSED2(cullGroup);
     172             :     UNUSED2(textureMatrix);
     173             :     UNUSED2(texture);
     174             : #else
     175           0 :     ENSURE(m->phase == Phase_Render);
     176             : 
     177           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     178             : 
     179           0 :     CShaderTechniquePtr debugOverlayTech =
     180           0 :         g_Renderer.GetShaderManager().LoadEffect(str_debug_overlay);
     181           0 :     debugOverlayTech->BeginPass();
     182           0 :     deviceCommandContext->SetGraphicsPipelineState(
     183             :         debugOverlayTech->GetGraphicsPipelineStateDesc());
     184           0 :     const CShaderProgramPtr& debugOverlayShader = debugOverlayTech->GetShader();
     185             : 
     186           0 :     debugOverlayShader->BindTexture(str_baseTex, texture);
     187           0 :     debugOverlayShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
     188           0 :     debugOverlayShader->Uniform(str_textureTransform, textureMatrix);
     189           0 :     CPatchRData::RenderStreams(deviceCommandContext, visiblePatches, debugOverlayShader, true);
     190             : 
     191             :     // To make the overlay visible over water, render an additional map-sized
     192             :     // water-height patch.
     193           0 :     CBoundingBoxAligned waterBounds;
     194           0 :     for (CPatchRData* data : visiblePatches)
     195           0 :         waterBounds += data->GetWaterBounds();
     196           0 :     if (!waterBounds.IsEmpty())
     197             :     {
     198             :         // Add a delta to avoid z-fighting.
     199           0 :         const float height = g_Renderer.GetSceneRenderer().GetWaterManager().m_WaterHeight + 0.05f;
     200           0 :         const float waterPos[] =
     201             :         {
     202           0 :             waterBounds[0].X, height, waterBounds[0].Z,
     203           0 :             waterBounds[1].X, height, waterBounds[0].Z,
     204           0 :             waterBounds[1].X, height, waterBounds[1].Z,
     205           0 :             waterBounds[0].X, height, waterBounds[0].Z,
     206           0 :             waterBounds[1].X, height, waterBounds[1].Z,
     207           0 :             waterBounds[0].X, height, waterBounds[1].Z
     208           0 :         };
     209             : 
     210           0 :         const GLsizei stride = sizeof(float) * 3;
     211           0 :         debugOverlayShader->VertexPointer(
     212           0 :             Renderer::Backend::Format::R32G32B32_SFLOAT, stride, waterPos);
     213           0 :         debugOverlayShader->TexCoordPointer(
     214           0 :             GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, waterPos);
     215           0 :         debugOverlayShader->AssertPointersBound();
     216             : 
     217           0 :         deviceCommandContext->Draw(0, 6);
     218             :     }
     219             : 
     220           0 :     debugOverlayTech->EndPass();
     221             : #endif
     222           0 : }
     223             : 
     224             : 
     225             : ///////////////////////////////////////////////////////////////////
     226             : 
     227             : /**
     228             :  * Set up all the uniforms for a shader pass.
     229             :  */
     230           0 : void TerrainRenderer::PrepareShader(const CShaderProgramPtr& shader, ShadowMap* shadow)
     231             : {
     232           0 :     CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
     233             : 
     234           0 :     shader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
     235           0 :     shader->Uniform(str_cameraPos, sceneRenderer.GetViewCamera().GetOrientation().GetTranslation());
     236             : 
     237           0 :     const CLightEnv& lightEnv = sceneRenderer.GetLightEnv();
     238             : 
     239           0 :     if (shadow)
     240           0 :         shadow->BindTo(shader);
     241             : 
     242           0 :     CLOSTexture& los = sceneRenderer.GetScene().GetLOSTexture();
     243           0 :     shader->BindTexture(str_losTex, los.GetTextureSmooth());
     244           0 :     shader->Uniform(str_losTransform, los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
     245             : 
     246           0 :     shader->Uniform(str_ambient, lightEnv.m_AmbientColor);
     247           0 :     shader->Uniform(str_sunColor, lightEnv.m_SunColor);
     248           0 :     shader->Uniform(str_sunDir, lightEnv.GetSunDir());
     249             : 
     250           0 :     shader->Uniform(str_fogColor, lightEnv.m_FogColor);
     251           0 :     shader->Uniform(str_fogParams, lightEnv.m_FogFactor, lightEnv.m_FogMax, 0.f, 0.f);
     252           0 : }
     253             : 
     254           0 : void TerrainRenderer::RenderTerrainShader(
     255             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     256             :     const CShaderDefines& context, int cullGroup, ShadowMap* shadow)
     257             : {
     258           0 :     ENSURE(m->phase == Phase_Render);
     259             : 
     260           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     261           0 :     std::vector<CDecalRData*>& visibleDecals = m->visibleDecals[cullGroup];
     262           0 :     if (visiblePatches.empty() && visibleDecals.empty())
     263           0 :         return;
     264             : 
     265             :     // render the solid black sides of the map first
     266           0 :     CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     267           0 :     techSolid->BeginPass();
     268           0 :     Renderer::Backend::GraphicsPipelineStateDesc solidPipelineStateDesc =
     269           0 :         techSolid->GetGraphicsPipelineStateDesc();
     270           0 :     solidPipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
     271           0 :     deviceCommandContext->SetGraphicsPipelineState(solidPipelineStateDesc);
     272             : 
     273           0 :     const CShaderProgramPtr& shaderSolid = techSolid->GetShader();
     274           0 :     shaderSolid->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
     275           0 :     shaderSolid->Uniform(str_color, 0.0f, 0.0f, 0.0f, 1.0f);
     276             : 
     277           0 :     CPatchRData::RenderSides(deviceCommandContext, visiblePatches, shaderSolid);
     278             : 
     279           0 :     techSolid->EndPass();
     280             : 
     281           0 :     CPatchRData::RenderBases(deviceCommandContext, visiblePatches, context, shadow);
     282             : 
     283             :     // render blend passes for each patch
     284           0 :     CPatchRData::RenderBlends(deviceCommandContext, visiblePatches, context, shadow);
     285             : 
     286           0 :     CDecalRData::RenderDecals(deviceCommandContext, visibleDecals, context, shadow);
     287             : 
     288             :     // restore OpenGL state
     289           0 :     deviceCommandContext->BindTexture(3, GL_TEXTURE_2D, 0);
     290           0 :     deviceCommandContext->BindTexture(2, GL_TEXTURE_2D, 0);
     291           0 :     deviceCommandContext->BindTexture(1, GL_TEXTURE_2D, 0);
     292             : }
     293             : 
     294             : 
     295             : ///////////////////////////////////////////////////////////////////
     296             : // Render un-textured patches as polygons
     297           0 : void TerrainRenderer::RenderPatches(
     298             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     299             :     int cullGroup, const CShaderDefines& defines, const CColor& color)
     300             : {
     301           0 :     ENSURE(m->phase == Phase_Render);
     302             : 
     303           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     304           0 :     if (visiblePatches.empty())
     305             :         return;
     306             : 
     307           0 :     GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain patches");
     308             : 
     309             : #if CONFIG2_GLES
     310             :     UNUSED2(deviceCommandContext);
     311             :     UNUSED2(defines);
     312             :     UNUSED2(color);
     313             :     #warning TODO: implement TerrainRenderer::RenderPatches for GLES
     314             : #else
     315             : 
     316           0 :     CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
     317           0 :     solidTech->BeginPass();
     318           0 :     deviceCommandContext->SetGraphicsPipelineState(
     319             :         solidTech->GetGraphicsPipelineStateDesc());
     320             : 
     321           0 :     const CShaderProgramPtr& solidShader = solidTech->GetShader();
     322           0 :     solidShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
     323           0 :     solidShader->Uniform(str_color, color);
     324             : 
     325           0 :     CPatchRData::RenderStreams(deviceCommandContext, visiblePatches, solidShader, false);
     326           0 :     solidTech->EndPass();
     327             : #endif
     328             : }
     329             : 
     330             : 
     331             : ///////////////////////////////////////////////////////////////////
     332             : // Render outlines of submitted patches as lines
     333           0 : void TerrainRenderer::RenderOutlines(
     334             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     335             :     int cullGroup)
     336             : {
     337           0 :     ENSURE(m->phase == Phase_Render);
     338             : 
     339           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     340           0 :     if (visiblePatches.empty())
     341             :         return;
     342             : 
     343           0 :     GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain outlines");
     344             : 
     345           0 :     for (size_t i = 0; i < visiblePatches.size(); ++i)
     346           0 :         visiblePatches[i]->RenderOutline();
     347             : }
     348             : 
     349             : 
     350             : ///////////////////////////////////////////////////////////////////
     351             : // Scissor rectangle of water patches
     352           0 : CBoundingBoxAligned TerrainRenderer::ScissorWater(int cullGroup, const CCamera& camera)
     353             : {
     354           0 :     CBoundingBoxAligned scissor;
     355           0 :     for (const CPatchRData* data : m->visiblePatches[cullGroup])
     356             :     {
     357           0 :         const CBoundingBoxAligned& waterBounds = data->GetWaterBounds();
     358           0 :         if (waterBounds.IsEmpty())
     359           0 :             continue;
     360             : 
     361           0 :         const CBoundingBoxAligned waterBoundsInViewPort =
     362           0 :             camera.GetBoundsInViewPort(waterBounds);
     363           0 :         if (!waterBoundsInViewPort.IsEmpty())
     364           0 :             scissor += waterBoundsInViewPort;
     365             :     }
     366           0 :     return CBoundingBoxAligned(
     367           0 :         CVector3D(Clamp(scissor[0].X, -1.0f, 1.0f), Clamp(scissor[0].Y, -1.0f, 1.0f), -1.0f),
     368           0 :         CVector3D(Clamp(scissor[1].X, -1.0f, 1.0f), Clamp(scissor[1].Y, -1.0f, 1.0f), 1.0f));
     369             : }
     370             : 
     371             : // Render fancy water
     372           0 : bool TerrainRenderer::RenderFancyWater(
     373             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     374             :     const CShaderDefines& context, int cullGroup, ShadowMap* shadow)
     375             : {
     376           0 :     PROFILE3_GPU("fancy water");
     377           0 :     GPU_SCOPED_LABEL(deviceCommandContext, "Render fancy water");
     378             : 
     379           0 :     CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
     380             : 
     381           0 :     WaterManager& waterManager = sceneRenderer.GetWaterManager();
     382           0 :     CShaderDefines defines = context;
     383             : 
     384             :     // If we're using fancy water, make sure its shader is loaded
     385           0 :     if (!m->fancyWaterTech || waterManager.m_NeedsReloading)
     386             :     {
     387           0 :         if (waterManager.m_WaterRealDepth)
     388           0 :             defines.Add(str_USE_REAL_DEPTH, str_1);
     389           0 :         if (waterManager.m_WaterFancyEffects)
     390           0 :             defines.Add(str_USE_FANCY_EFFECTS, str_1);
     391           0 :         if (waterManager.m_WaterRefraction)
     392           0 :             defines.Add(str_USE_REFRACTION, str_1);
     393           0 :         if (waterManager.m_WaterReflection)
     394           0 :             defines.Add(str_USE_REFLECTION, str_1);
     395             : 
     396           0 :         m->fancyWaterTech = g_Renderer.GetShaderManager().LoadEffect(str_water_high, defines);
     397             : 
     398           0 :         if (!m->fancyWaterTech)
     399             :         {
     400           0 :             LOGERROR("Failed to load water shader. Falling back to a simple water.\n");
     401           0 :             waterManager.m_RenderWater = false;
     402           0 :             return false;
     403             :         }
     404           0 :         waterManager.m_NeedsReloading = false;
     405             :     }
     406             : 
     407           0 :     CLOSTexture& losTexture = sceneRenderer.GetScene().GetLOSTexture();
     408             : 
     409             :     // Calculating the advanced informations about Foam and all if the quality calls for it.
     410             :     /*if (WaterMgr->m_NeedInfoUpdate && (WaterMgr->m_WaterFoam || WaterMgr->m_WaterCoastalWaves))
     411             :     {
     412             :         WaterMgr->m_NeedInfoUpdate = false;
     413             :         WaterMgr->CreateSuperfancyInfo();
     414             :     }*/
     415             : 
     416           0 :     const double time = waterManager.m_WaterTexTimer;
     417           0 :     const float repeatPeriod = waterManager.m_RepeatPeriod;
     418             : 
     419           0 :     m->fancyWaterTech->BeginPass();
     420           0 :     deviceCommandContext->SetGraphicsPipelineState(
     421           0 :         m->fancyWaterTech->GetGraphicsPipelineStateDesc());
     422           0 :     const CShaderProgramPtr& fancyWaterShader = m->fancyWaterTech->GetShader();
     423             : 
     424           0 :     const CCamera& camera = g_Renderer.GetSceneRenderer().GetViewCamera();
     425             : 
     426           0 :     const double period = 8.0;
     427             :     // TODO: move uploading to a prepare function during loading.
     428           0 :     const CTexturePtr& currentNormalTexture = waterManager.m_NormalMap[waterManager.GetCurrentTextureIndex(period)];
     429           0 :     const CTexturePtr& nextNormalTexture = waterManager.m_NormalMap[waterManager.GetNextTextureIndex(period)];
     430           0 :     currentNormalTexture->UploadBackendTextureIfNeeded(deviceCommandContext);
     431           0 :     nextNormalTexture->UploadBackendTextureIfNeeded(deviceCommandContext);
     432           0 :     fancyWaterShader->BindTexture(str_normalMap, currentNormalTexture->GetBackendTexture());
     433           0 :     fancyWaterShader->BindTexture(str_normalMap2, nextNormalTexture->GetBackendTexture());
     434             : 
     435           0 :     if (waterManager.m_WaterFancyEffects)
     436             :     {
     437           0 :         fancyWaterShader->BindTexture(str_waterEffectsTex, waterManager.m_FancyTexture.get());
     438             :     }
     439             : 
     440           0 :     if (waterManager.m_WaterRefraction && waterManager.m_WaterRealDepth)
     441             :     {
     442           0 :         fancyWaterShader->BindTexture(str_depthTex, waterManager.m_RefrFboDepthTexture.get());
     443           0 :         fancyWaterShader->Uniform(str_projInvTransform, waterManager.m_RefractionProjInvMatrix);
     444           0 :         fancyWaterShader->Uniform(str_viewInvTransform, waterManager.m_RefractionViewInvMatrix);
     445             :     }
     446             : 
     447           0 :     if (waterManager.m_WaterRefraction)
     448           0 :         fancyWaterShader->BindTexture(str_refractionMap, waterManager.m_RefractionTexture.get());
     449           0 :     if (waterManager.m_WaterReflection)
     450           0 :         fancyWaterShader->BindTexture(str_reflectionMap, waterManager.m_ReflectionTexture.get());
     451           0 :     fancyWaterShader->BindTexture(str_losTex, losTexture.GetTextureSmooth());
     452             : 
     453           0 :     const CLightEnv& lightEnv = sceneRenderer.GetLightEnv();
     454             : 
     455           0 :     fancyWaterShader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
     456             : 
     457           0 :     fancyWaterShader->BindTexture(str_skyCube, sceneRenderer.GetSkyManager().GetSkyCube());
     458             :     // TODO: check that this rotates in the right direction.
     459           0 :     CMatrix3D skyBoxRotation;
     460           0 :     skyBoxRotation.SetIdentity();
     461           0 :     skyBoxRotation.RotateY(M_PI + lightEnv.GetRotation());
     462           0 :     fancyWaterShader->Uniform(str_skyBoxRot, skyBoxRotation);
     463             : 
     464           0 :     if (waterManager.m_WaterRefraction)
     465           0 :         fancyWaterShader->Uniform(str_refractionMatrix, waterManager.m_RefractionMatrix);
     466           0 :     if (waterManager.m_WaterReflection)
     467           0 :         fancyWaterShader->Uniform(str_reflectionMatrix, waterManager.m_ReflectionMatrix);
     468             : 
     469           0 :     fancyWaterShader->Uniform(str_ambient, lightEnv.m_AmbientColor);
     470           0 :     fancyWaterShader->Uniform(str_sunDir, lightEnv.GetSunDir());
     471           0 :     fancyWaterShader->Uniform(str_sunColor, lightEnv.m_SunColor);
     472           0 :     fancyWaterShader->Uniform(str_color, waterManager.m_WaterColor);
     473           0 :     fancyWaterShader->Uniform(str_tint, waterManager.m_WaterTint);
     474           0 :     fancyWaterShader->Uniform(str_waviness, waterManager.m_Waviness);
     475           0 :     fancyWaterShader->Uniform(str_murkiness, waterManager.m_Murkiness);
     476           0 :     fancyWaterShader->Uniform(str_windAngle, waterManager.m_WindAngle);
     477           0 :     fancyWaterShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
     478           0 :     fancyWaterShader->Uniform(str_losTransform, losTexture.GetTextureMatrix()[0], losTexture.GetTextureMatrix()[12], 0.f, 0.f);
     479             : 
     480           0 :     fancyWaterShader->Uniform(str_cameraPos, camera.GetOrientation().GetTranslation());
     481             : 
     482           0 :     fancyWaterShader->Uniform(str_fogColor, lightEnv.m_FogColor);
     483           0 :     fancyWaterShader->Uniform(str_fogParams, lightEnv.m_FogFactor, lightEnv.m_FogMax, 0.f, 0.f);
     484           0 :     fancyWaterShader->Uniform(str_time, (float)time);
     485           0 :     fancyWaterShader->Uniform(str_screenSize, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0.0f, 0.0f);
     486             : 
     487           0 :     if (waterManager.m_WaterType == L"clap")
     488             :     {
     489           0 :         fancyWaterShader->Uniform(str_waveParams1, 30.0f,1.5f,20.0f,0.03f);
     490           0 :         fancyWaterShader->Uniform(str_waveParams2, 0.5f,0.0f,0.0f,0.0f);
     491             :     }
     492           0 :     else if (waterManager.m_WaterType == L"lake")
     493             :     {
     494           0 :         fancyWaterShader->Uniform(str_waveParams1, 8.5f,1.5f,15.0f,0.03f);
     495           0 :         fancyWaterShader->Uniform(str_waveParams2, 0.2f,0.0f,0.0f,0.07f);
     496             :     }
     497             :     else
     498             :     {
     499           0 :         fancyWaterShader->Uniform(str_waveParams1, 15.0f,0.8f,10.0f,0.1f);
     500           0 :         fancyWaterShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.3f);
     501             :     }
     502             : 
     503           0 :     if (shadow)
     504           0 :         shadow->BindTo(fancyWaterShader);
     505             : 
     506           0 :     for (CPatchRData* data : m->visiblePatches[cullGroup])
     507             :     {
     508           0 :         data->RenderWaterSurface(deviceCommandContext, fancyWaterShader, true);
     509           0 :         if (waterManager.m_WaterFancyEffects)
     510           0 :             data->RenderWaterShore(deviceCommandContext, fancyWaterShader);
     511             :     }
     512           0 :     m->fancyWaterTech->EndPass();
     513             : 
     514             :     return true;
     515             : }
     516             : 
     517           0 : void TerrainRenderer::RenderSimpleWater(
     518             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     519             :     int cullGroup)
     520             : {
     521             : #if CONFIG2_GLES
     522             :     UNUSED2(deviceCommandContext);
     523             :     UNUSED2(cullGroup);
     524             : #else
     525           0 :     PROFILE3_GPU("simple water");
     526           0 :     GPU_SCOPED_LABEL(deviceCommandContext, "Render Simple Water");
     527             : 
     528           0 :     const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager();
     529           0 :     CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
     530             : 
     531           0 :     const double time = waterManager.m_WaterTexTimer;
     532             : 
     533           0 :     CShaderDefines context;
     534           0 :     if (g_Renderer.GetSceneRenderer().GetWaterRenderMode() == WIREFRAME)
     535           0 :         context.Add(str_MODE_WIREFRAME, str_1);
     536             : 
     537           0 :     CShaderTechniquePtr waterSimpleTech =
     538           0 :         g_Renderer.GetShaderManager().LoadEffect(str_water_simple, context);
     539           0 :     waterSimpleTech->BeginPass();
     540           0 :     deviceCommandContext->SetGraphicsPipelineState(
     541             :         waterSimpleTech->GetGraphicsPipelineStateDesc());
     542           0 :     const CShaderProgramPtr& waterSimpleShader = waterSimpleTech->GetShader();
     543             : 
     544           0 :     const CTexturePtr& waterTexture = waterManager.m_WaterTexture[waterManager.GetCurrentTextureIndex(1.6)];
     545           0 :     waterTexture->UploadBackendTextureIfNeeded(deviceCommandContext);
     546           0 :     waterSimpleShader->BindTexture(str_baseTex, waterTexture->GetBackendTexture());
     547           0 :     waterSimpleShader->BindTexture(str_losTex, losTexture.GetTextureSmooth());
     548           0 :     waterSimpleShader->Uniform(str_transform, g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection());
     549           0 :     waterSimpleShader->Uniform(str_losTransform, losTexture.GetTextureMatrix()[0], losTexture.GetTextureMatrix()[12], 0.f, 0.f);
     550           0 :     waterSimpleShader->Uniform(str_time, static_cast<float>(time));
     551           0 :     waterSimpleShader->Uniform(str_color, waterManager.m_WaterColor);
     552             : 
     553           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     554           0 :     for (size_t i = 0; i < visiblePatches.size(); ++i)
     555             :     {
     556           0 :         CPatchRData* data = visiblePatches[i];
     557           0 :         data->RenderWaterSurface(deviceCommandContext, waterSimpleShader, false);
     558             :     }
     559             : 
     560           0 :     deviceCommandContext->BindTexture(1, GL_TEXTURE_2D, 0);
     561             : 
     562           0 :     waterSimpleTech->EndPass();
     563             : #endif
     564           0 : }
     565             : 
     566             : ///////////////////////////////////////////////////////////////////
     567             : // Render water that is part of the terrain
     568           0 : void TerrainRenderer::RenderWater(
     569             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     570             :     const CShaderDefines& context, int cullGroup, ShadowMap* shadow)
     571             : {
     572           0 :     const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager();
     573             : 
     574           0 :     if (!waterManager.WillRenderFancyWater())
     575           0 :         RenderSimpleWater(deviceCommandContext, cullGroup);
     576             :     else
     577           0 :         RenderFancyWater(deviceCommandContext, context, cullGroup, shadow);
     578           0 : }
     579             : 
     580           0 : void TerrainRenderer::RenderWaterFoamOccluders(
     581             :     Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
     582             :     int cullGroup)
     583             : {
     584           0 :     CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
     585           0 :     const WaterManager& waterManager = sceneRenderer.GetWaterManager();
     586           0 :     if (!waterManager.WillRenderFancyWater())
     587           0 :         return;
     588             : 
     589           0 :     GPU_SCOPED_LABEL(deviceCommandContext, "Render water foam occluders");
     590             : 
     591             :     // Render normals and foam to a framebuffer if we're using fancy effects.
     592           0 :     deviceCommandContext->SetFramebuffer(waterManager.m_FancyEffectsFramebuffer.get());
     593             : 
     594             :     // Overwrite waves that would be behind the ground.
     595           0 :     CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     596           0 :     dummyTech->BeginPass();
     597           0 :     Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
     598           0 :         dummyTech->GetGraphicsPipelineStateDesc();
     599           0 :     pipelineStateDesc.depthStencilState.depthTestEnabled = true;
     600           0 :     pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
     601           0 :     deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
     602           0 :     const CShaderProgramPtr& dummyShader = dummyTech->GetShader();
     603             : 
     604           0 :     dummyShader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
     605           0 :     dummyShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.0f);
     606           0 :     for (CPatchRData* data : m->visiblePatches[cullGroup])
     607           0 :         data->RenderWaterShore(deviceCommandContext, dummyShader);
     608           0 :     dummyTech->EndPass();
     609             : 
     610           0 :     deviceCommandContext->SetFramebuffer(
     611             :         deviceCommandContext->GetDevice()->GetCurrentBackbuffer());
     612             : }
     613             : 
     614           0 : void TerrainRenderer::RenderPriorities(CCanvas2D& canvas, int cullGroup)
     615             : {
     616           0 :     PROFILE("priorities");
     617             : 
     618           0 :     ENSURE(m->phase == Phase_Render);
     619             : 
     620           0 :     CTextRenderer textRenderer;
     621           0 :     textRenderer.SetCurrentFont(CStrIntern("mono-stroke-10"));
     622           0 :     textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 0.0f, 1.0f));
     623             : 
     624           0 :     std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
     625           0 :     for (size_t i = 0; i < visiblePatches.size(); ++i)
     626           0 :         visiblePatches[i]->RenderPriorities(textRenderer);
     627             : 
     628           0 :     canvas.DrawText(textRenderer);
     629           0 : }

Generated by: LCOV version 1.13