LCOV - code coverage report
Current view: top level - source/renderer - SkyManager.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 111 0.0 %
Date: 2021-09-24 14:46:47 Functions: 0 5 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             :  * Sky settings, texture management and rendering.
      20             :  */
      21             : 
      22             : #include "precompiled.h"
      23             : 
      24             : #include "renderer/SkyManager.h"
      25             : 
      26             : #include "graphics/LightEnv.h"
      27             : #include "graphics/ShaderManager.h"
      28             : #include "graphics/Terrain.h"
      29             : #include "graphics/TextureManager.h"
      30             : #include "lib/tex/tex.h"
      31             : #include "lib/timer.h"
      32             : #include "lib/res/graphics/ogl_tex.h"
      33             : #include "maths/MathUtil.h"
      34             : #include "ps/CLogger.h"
      35             : #include "ps/ConfigDB.h"
      36             : #include "ps/CStr.h"
      37             : #include "ps/CStrInternStatic.h"
      38             : #include "ps/Filesystem.h"
      39             : #include "ps/Game.h"
      40             : #include "ps/Loader.h"
      41             : #include "ps/World.h"
      42             : #include "renderer/Renderer.h"
      43             : #include "renderer/RenderingOptions.h"
      44             : 
      45             : #include <algorithm>
      46             : 
      47           0 : SkyManager::SkyManager()
      48           0 :     : m_RenderSky(true), m_SkyCubeMap(0)
      49             : {
      50           0 :     CFG_GET_VAL("showsky", m_RenderSky);
      51           0 : }
      52             : 
      53             : ///////////////////////////////////////////////////////////////////
      54             : // Load all sky textures
      55           0 : void SkyManager::LoadSkyTextures()
      56             : {
      57           0 :     static const CStrW images[NUMBER_OF_TEXTURES + 1] = {
      58             :         L"front",
      59             :         L"back",
      60             :         L"right",
      61             :         L"left",
      62             :         L"top",
      63             :         L"top"
      64           0 :     };
      65             :     /*for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i)
      66             :     {
      67             :         VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(s_imageNames[i])+L".dds");
      68             : 
      69             :         CTextureProperties textureProps(path);
      70             :         textureProps.SetWrap(GL_CLAMP_TO_EDGE);
      71             :         CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
      72             :         texture->Prefetch();
      73             :         m_SkyTexture[i] = texture;
      74             :     }*/
      75             : 
      76             :     ///////////////////////////////////////////////////////////////////////////
      77             :     // HACK: THE HORRIBLENESS HERE IS OVER 9000. The following code is a HUGE hack and will be removed completely
      78             :     // as soon as all the hardcoded GL_TEXTURE_2D references are corrected in the TextureManager/OGL/tex libs.
      79             : 
      80           0 :     glGenTextures(1, &m_SkyCubeMap);
      81           0 :     glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap);
      82             : 
      83           0 :     static const int types[] = {
      84             :         GL_TEXTURE_CUBE_MAP_POSITIVE_X,
      85             :         GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
      86             :         GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
      87             :         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
      88             :         GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
      89             :         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
      90             :     };
      91             : 
      92           0 :     for (size_t i = 0; i < NUMBER_OF_TEXTURES + 1; ++i)
      93             :     {
      94           0 :         VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(images[i])+L".dds");
      95             : 
      96           0 :         std::shared_ptr<u8> file;
      97           0 :         size_t fileSize;
      98           0 :         if (g_VFS->LoadFile(path, file, fileSize) != INFO::OK)
      99             :         {
     100           0 :             path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(images[i])+L".dds.cached.dds");
     101           0 :             if (g_VFS->LoadFile(path, file, fileSize) != INFO::OK)
     102             :             {
     103           0 :                 glDeleteTextures(1, &m_SkyCubeMap);
     104           0 :                 LOGERROR("Error creating sky cubemap.");
     105           0 :                 return;
     106             :             }
     107             :         }
     108             : 
     109           0 :         Tex tex;
     110           0 :         tex.decode(file, fileSize);
     111             : 
     112           0 :         tex.transform_to((tex.m_Flags | TEX_BOTTOM_UP | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS));
     113             : 
     114           0 :         u8* data = tex.get_data();
     115             : 
     116           0 :         if (types[i] == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || types[i] == GL_TEXTURE_CUBE_MAP_POSITIVE_Y)
     117             :         {
     118           0 :             std::vector<u8> rotated(tex.m_DataSize);
     119             : 
     120           0 :             for (size_t y = 0; y < tex.m_Height; ++y)
     121             :             {
     122           0 :                 for (size_t x = 0; x < tex.m_Width; ++x)
     123             :                 {
     124           0 :                     size_t invx = y, invy = tex.m_Width-x-1;
     125             : 
     126           0 :                     rotated[(y*tex.m_Width + x) * 4 + 0] = data[(invy*tex.m_Width + invx) * 4 + 0];
     127           0 :                     rotated[(y*tex.m_Width + x) * 4 + 1] = data[(invy*tex.m_Width + invx) * 4 + 1];
     128           0 :                     rotated[(y*tex.m_Width + x) * 4 + 2] = data[(invy*tex.m_Width + invx) * 4 + 2];
     129           0 :                     rotated[(y*tex.m_Width + x) * 4 + 3] = data[(invy*tex.m_Width + invx) * 4 + 3];
     130             :                 }
     131             :             }
     132             : 
     133           0 :             glTexImage2D(types[i], 0, GL_RGBA, tex.m_Width, tex.m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rotated[0]);
     134             :         }
     135             :         else
     136             :         {
     137           0 :             glTexImage2D(types[i], 0, GL_RGBA, tex.m_Width, tex.m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
     138             :         }
     139             :     }
     140             : 
     141           0 :     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     142           0 :     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     143           0 :     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     144           0 :     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     145             : #if CONFIG2_GLES
     146             : #warning TODO: fix SkyManager::LoadSkyTextures for GLES
     147             : #else
     148           0 :     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
     149             : #endif
     150           0 :     glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
     151             :     ///////////////////////////////////////////////////////////////////////////
     152             : }
     153             : 
     154             : 
     155             : ///////////////////////////////////////////////////////////////////
     156             : // Switch to a different sky set (while the game is running)
     157           0 : void SkyManager::SetSkySet(const CStrW& newSet)
     158             : {
     159           0 :     if (newSet == m_SkySet)
     160             :         return;
     161             : 
     162           0 :     if (m_SkyCubeMap)
     163             :     {
     164           0 :         glDeleteTextures(1, &m_SkyCubeMap);
     165           0 :         m_SkyCubeMap = 0;
     166             :     }
     167             : 
     168           0 :     m_SkySet = newSet;
     169             : 
     170           0 :     LoadSkyTextures();
     171             : }
     172             : 
     173             : ///////////////////////////////////////////////////////////////////
     174             : // Generate list of available skies
     175           0 : std::vector<CStrW> SkyManager::GetSkySets() const
     176             : {
     177           0 :     std::vector<CStrW> skies;
     178             : 
     179             :     // Find all subdirectories in art/textures/skies
     180             : 
     181           0 :     const VfsPath path(L"art/textures/skies/");
     182           0 :     DirectoryNames subdirectories;
     183           0 :     if (g_VFS->GetDirectoryEntries(path, 0, &subdirectories) != INFO::OK)
     184             :     {
     185           0 :         LOGERROR("Error opening directory '%s'", path.string8());
     186           0 :         return std::vector<CStrW>(1, GetSkySet()); // just return what we currently have
     187             :     }
     188             : 
     189           0 :     for(size_t i = 0; i < subdirectories.size(); i++)
     190           0 :         skies.push_back(subdirectories[i].string());
     191           0 :     sort(skies.begin(), skies.end());
     192             : 
     193           0 :     return skies;
     194             : }
     195             : 
     196             : ///////////////////////////////////////////////////////////////////
     197             : // Render sky
     198           0 : void SkyManager::RenderSky()
     199             : {
     200             : #if CONFIG2_GLES
     201             : #warning TODO: implement SkyManager::RenderSky for GLES
     202             : #else
     203           0 :     if (!m_RenderSky)
     204           0 :         return;
     205             : 
     206             :     // Draw the sky as a small box around the map, with depth write enabled.
     207             :     // This will be done before anything else is drawn so we'll be overlapped by
     208             :     // everything else.
     209             : 
     210             :     // Do nothing unless SetSkySet was called
     211           0 :     if (m_SkySet.empty())
     212             :         return;
     213             : 
     214           0 :     glDepthMask(GL_FALSE);
     215             : 
     216           0 :     const CCamera& camera = g_Renderer.GetViewCamera();
     217             : 
     218           0 :     CShaderTechniquePtr skytech =
     219           0 :         g_Renderer.GetShaderManager().LoadEffect(str_sky_simple);
     220           0 :     skytech->BeginPass();
     221           0 :     CShaderProgramPtr shader = skytech->GetShader();
     222           0 :     shader->BindTexture(str_baseTex, m_SkyCubeMap);
     223             : 
     224             :     // Translate so the sky center is at the camera space origin.
     225           0 :     CMatrix3D translate;
     226           0 :     translate.SetTranslation(camera.GetOrientation().GetTranslation());
     227             : 
     228             :     // Currently we have a hardcoded near plane in the projection matrix.
     229           0 :     CMatrix3D scale;
     230           0 :     scale.SetScaling(10.0f, 10.0f, 10.0f);
     231             : 
     232             :     // Rotate so that the "left" face, which contains the brightest part of
     233             :     // each skymap, is in the direction of the sun from our light
     234             :     // environment.
     235           0 :     CMatrix3D rotate;
     236           0 :     rotate.SetYRotation(M_PI + g_Renderer.GetLightEnv().GetRotation());
     237             : 
     238           0 :     shader->Uniform(
     239             :         str_transform,
     240           0 :         camera.GetViewProjection() * translate * rotate * scale);
     241             : 
     242           0 :     std::vector<GLfloat> vertexData;
     243             :     // 6 sides of cube with 4 vertices with 6 floats (3 uv and 3 position).
     244           0 :     vertexData.reserve(6 * 4 * 6);
     245             : #define ADD_VERTEX(U, V, W, X, Y, Z) \
     246             :     STMT( \
     247             :         vertexData.push_back(X); \
     248             :         vertexData.push_back(Y); \
     249             :         vertexData.push_back(Z); \
     250             :         vertexData.push_back(U); \
     251             :         vertexData.push_back(V); \
     252             :         vertexData.push_back(W);)
     253             : 
     254             :     // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
     255           0 :     ADD_VERTEX(+1, +1, +1, -1.0f, -1.0f, -1.0f);
     256           0 :     ADD_VERTEX(+1, +1, -1, -1.0f, -1.0f, +1.0f);
     257           0 :     ADD_VERTEX(+1, -1, -1, -1.0f, +1.0f, +1.0f);
     258           0 :     ADD_VERTEX(+1, -1, +1, -1.0f, +1.0f, -1.0f);
     259             : 
     260             :     // GL_TEXTURE_CUBE_MAP_POSITIVE_X
     261           0 :     ADD_VERTEX(-1, +1, -1, +1.0f, -1.0f, +1.0f);
     262           0 :     ADD_VERTEX(-1, +1, +1, +1.0f, -1.0f, -1.0f);
     263           0 :     ADD_VERTEX(-1, -1, +1, +1.0f, +1.0f, -1.0f);
     264           0 :     ADD_VERTEX(-1, -1, -1, +1.0f, +1.0f, +1.0f);
     265             : 
     266             :     // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
     267           0 :     ADD_VERTEX(-1, +1, +1, +1.0f, -1.0f, -1.0f);
     268           0 :     ADD_VERTEX(-1, +1, -1, +1.0f, -1.0f, +1.0f);
     269           0 :     ADD_VERTEX(+1, +1, -1, -1.0f, -1.0f, +1.0f);
     270           0 :     ADD_VERTEX(+1, +1, +1, -1.0f, -1.0f, -1.0f);
     271             : 
     272             :     // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
     273           0 :     ADD_VERTEX(+1, -1, +1, -1.0f, +1.0f, -1.0f);
     274           0 :     ADD_VERTEX(+1, -1, -1, -1.0f, +1.0f, +1.0f);
     275           0 :     ADD_VERTEX(-1, -1, -1, +1.0f, +1.0f, +1.0f);
     276           0 :     ADD_VERTEX(-1, -1, +1, +1.0f, +1.0f, -1.0f);
     277             : 
     278             :     // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
     279           0 :     ADD_VERTEX(-1, +1, +1, +1.0f, -1.0f, -1.0f);
     280           0 :     ADD_VERTEX(+1, +1, +1, -1.0f, -1.0f, -1.0f);
     281           0 :     ADD_VERTEX(+1, -1, +1, -1.0f, +1.0f, -1.0f);
     282           0 :     ADD_VERTEX(-1, -1, +1, +1.0f, +1.0f, -1.0f);
     283             : 
     284             :     // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
     285           0 :     ADD_VERTEX(+1, +1, -1, -1.0f, -1.0f, +1.0f);
     286           0 :     ADD_VERTEX(-1, +1, -1, +1.0f, -1.0f, +1.0f);
     287           0 :     ADD_VERTEX(-1, -1, -1, +1.0f, +1.0f, +1.0f);
     288           0 :     ADD_VERTEX(+1, -1, -1, -1.0f, +1.0f, +1.0f);
     289             : #undef ADD_VERTEX
     290             : 
     291           0 :     shader->VertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 6, &vertexData[0]);
     292           0 :     shader->TexCoordPointer(
     293           0 :         GL_TEXTURE0, 3, GL_FLOAT, sizeof(GLfloat) * 6, &vertexData[3]);
     294           0 :     shader->AssertPointersBound();
     295             : 
     296           0 :     glDrawArrays(GL_QUADS, 0, 6 * 4);
     297             : 
     298           0 :     skytech->EndPass();
     299             : 
     300           0 :     glDepthMask(GL_TRUE);
     301             : 
     302             : #endif
     303             : }

Generated by: LCOV version 1.13