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 308 0.0 %
Date: 2021-09-24 14:46:47 Functions: 0 18 0.0 %

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