LCOV - code coverage report
Current view: top level - source/graphics - GameView.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 4 143 2.8 %
Date: 2023-01-19 00:18:29 Functions: 3 40 7.5 %

          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 "GameView.h"
      21             : 
      22             : #include "graphics/CameraController.h"
      23             : #include "graphics/CinemaManager.h"
      24             : #include "graphics/ColladaManager.h"
      25             : #include "graphics/HFTracer.h"
      26             : #include "graphics/LOSTexture.h"
      27             : #include "graphics/LightEnv.h"
      28             : #include "graphics/MiniMapTexture.h"
      29             : #include "graphics/Model.h"
      30             : #include "graphics/ObjectManager.h"
      31             : #include "graphics/Patch.h"
      32             : #include "graphics/SkeletonAnimManager.h"
      33             : #include "graphics/SmoothedValue.h"
      34             : #include "graphics/Terrain.h"
      35             : #include "graphics/TerrainTextureManager.h"
      36             : #include "graphics/TerritoryTexture.h"
      37             : #include "graphics/Unit.h"
      38             : #include "graphics/UnitManager.h"
      39             : #include "lib/input.h"
      40             : #include "lib/timer.h"
      41             : #include "lobby/IXmppClient.h"
      42             : #include "maths/BoundingBoxAligned.h"
      43             : #include "maths/MathUtil.h"
      44             : #include "maths/Matrix3D.h"
      45             : #include "maths/Quaternion.h"
      46             : #include "ps/ConfigDB.h"
      47             : #include "ps/Filesystem.h"
      48             : #include "ps/Game.h"
      49             : #include "ps/Globals.h"
      50             : #include "ps/Hotkey.h"
      51             : #include "ps/Loader.h"
      52             : #include "ps/LoaderThunks.h"
      53             : #include "ps/Profile.h"
      54             : #include "ps/Pyrogenesis.h"
      55             : #include "ps/TouchInput.h"
      56             : #include "ps/World.h"
      57             : #include "renderer/Renderer.h"
      58             : #include "renderer/SceneRenderer.h"
      59             : #include "renderer/WaterManager.h"
      60             : #include "simulation2/Simulation2.h"
      61             : #include "simulation2/components/ICmpPosition.h"
      62             : #include "simulation2/components/ICmpRangeManager.h"
      63             : 
      64             : #include <memory>
      65             : 
      66           0 : class CGameViewImpl
      67             : {
      68             :     NONCOPYABLE(CGameViewImpl);
      69             : public:
      70           0 :     CGameViewImpl(CGame* game)
      71           0 :         : Game(game),
      72             :         ColladaManager(g_VFS), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager),
      73           0 :         ObjectManager(MeshManager, SkeletonAnimManager, *game->GetSimulation2()),
      74           0 :         LOSTexture(*game->GetSimulation2()),
      75           0 :         TerritoryTexture(*game->GetSimulation2()),
      76           0 :         MiniMapTexture(*game->GetSimulation2()),
      77             :         ViewCamera(),
      78             :         CullCamera(),
      79             :         LockCullCamera(false),
      80             :         Culling(true),
      81           0 :         CameraController(new CCameraController(ViewCamera))
      82             :     {
      83           0 :     }
      84             : 
      85             :     CGame* Game;
      86             :     CColladaManager ColladaManager;
      87             :     CMeshManager MeshManager;
      88             :     CSkeletonAnimManager SkeletonAnimManager;
      89             :     CObjectManager ObjectManager;
      90             :     CLOSTexture LOSTexture;
      91             :     CTerritoryTexture TerritoryTexture;
      92             :     CMiniMapTexture MiniMapTexture;
      93             : 
      94             :     /**
      95             :      * this camera controls the eye position when rendering
      96             :      */
      97             :     CCamera ViewCamera;
      98             : 
      99             :     /**
     100             :      * this camera controls the frustum that is used for culling
     101             :      * and shadow calculations
     102             :      *
     103             :      * Note that all code that works with camera movements should only change
     104             :      * m_ViewCamera. The render functions automatically sync the cull camera to
     105             :      * the view camera depending on the value of m_LockCullCamera.
     106             :      */
     107             :     CCamera CullCamera;
     108             : 
     109             :     /**
     110             :      * When @c true, the cull camera is locked in place.
     111             :      * When @c false, the cull camera follows the view camera.
     112             :      *
     113             :      * Exposed to JS as gameView.lockCullCamera
     114             :      */
     115             :     bool LockCullCamera;
     116             : 
     117             :     /**
     118             :      * When @c true, culling is enabled so that only models that have a chance of
     119             :      * being visible are sent to the renderer.
     120             :      * Otherwise, the entire world is sent to the renderer.
     121             :      *
     122             :      * Exposed to JS as gameView.culling
     123             :      */
     124             :     bool Culling;
     125             : 
     126             :     CCinemaManager CinemaManager;
     127             : 
     128             :     /**
     129             :      * Controller of the view's camera. We use a std::unique_ptr for an easy
     130             :      * on the fly replacement. It's guaranteed that the pointer is never nulllptr.
     131             :      */
     132             :     std::unique_ptr<ICameraController> CameraController;
     133             : };
     134             : 
     135             : #define IMPLEMENT_BOOLEAN_SETTING(NAME) \
     136             : bool CGameView::Get##NAME##Enabled() const \
     137             : { \
     138             :     return m->NAME; \
     139             : } \
     140             : \
     141             : void CGameView::Set##NAME##Enabled(bool Enabled) \
     142             : { \
     143             :     m->NAME = Enabled; \
     144             : }
     145             : 
     146           0 : IMPLEMENT_BOOLEAN_SETTING(Culling);
     147           0 : IMPLEMENT_BOOLEAN_SETTING(LockCullCamera);
     148             : 
     149           0 : bool CGameView::GetConstrainCameraEnabled() const
     150             : {
     151           0 :     return m->CameraController->GetConstrainCamera();
     152             : }
     153             : 
     154           0 : void CGameView::SetConstrainCameraEnabled(bool enabled)
     155             : {
     156           0 :     m->CameraController->SetConstrainCamera(enabled);
     157           0 : }
     158             : 
     159             : #undef IMPLEMENT_BOOLEAN_SETTING
     160             : 
     161           0 : CGameView::CGameView(CGame *pGame):
     162           0 :     m(new CGameViewImpl(pGame))
     163             : {
     164           0 :     m->CullCamera = m->ViewCamera;
     165           0 :     g_Renderer.GetSceneRenderer().SetSceneCamera(m->ViewCamera, m->CullCamera);
     166           0 : }
     167             : 
     168           0 : CGameView::~CGameView()
     169             : {
     170           0 :     UnloadResources();
     171             : 
     172           0 :     delete m;
     173           0 : }
     174             : 
     175           0 : void CGameView::SetViewport(const SViewPort& vp)
     176             : {
     177           0 :     m->CameraController->SetViewport(vp);
     178           0 : }
     179             : 
     180           0 : CObjectManager& CGameView::GetObjectManager()
     181             : {
     182           0 :     return m->ObjectManager;
     183             : }
     184             : 
     185           0 : CCamera* CGameView::GetCamera()
     186             : {
     187           0 :     return &m->ViewCamera;
     188             : }
     189             : 
     190           0 : CCinemaManager* CGameView::GetCinema()
     191             : {
     192           0 :     return &m->CinemaManager;
     193             : }
     194             : 
     195           0 : CLOSTexture& CGameView::GetLOSTexture()
     196             : {
     197           0 :     return m->LOSTexture;
     198             : }
     199             : 
     200           0 : CTerritoryTexture& CGameView::GetTerritoryTexture()
     201             : {
     202           0 :     return m->TerritoryTexture;
     203             : }
     204             : 
     205           0 : CMiniMapTexture& CGameView::GetMiniMapTexture()
     206             : {
     207           0 :     return m->MiniMapTexture;
     208             : }
     209             : 
     210           0 : int CGameView::Initialize()
     211             : {
     212           0 :     m->CameraController->LoadConfig();
     213           0 :     return 0;
     214             : }
     215             : 
     216           0 : void CGameView::RegisterInit()
     217             : {
     218             :     // CGameView init
     219           0 :     RegMemFun(this, &CGameView::Initialize, L"CGameView init", 1);
     220             : 
     221           0 :     RegMemFun(g_TexMan.GetSingletonPtr(), &CTerrainTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 60);
     222           0 : }
     223             : 
     224           0 : void CGameView::BeginFrame()
     225             : {
     226           0 :     if (m->LockCullCamera == false)
     227             :     {
     228             :         // Set up cull camera
     229           0 :         m->CullCamera = m->ViewCamera;
     230             :     }
     231           0 :     g_Renderer.GetSceneRenderer().SetSceneCamera(m->ViewCamera, m->CullCamera);
     232             : 
     233           0 :     m->Game->CachePlayerColors();
     234           0 : }
     235             : 
     236           0 : void CGameView::Prepare(
     237             :     Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
     238             : {
     239           0 :     g_Renderer.GetSceneRenderer().PrepareScene(deviceCommandContext, *this);
     240           0 : }
     241             : 
     242           0 : void CGameView::Render(
     243             :     Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
     244             : {
     245           0 :     g_Renderer.GetSceneRenderer().RenderScene(deviceCommandContext);
     246           0 : }
     247             : 
     248           0 : void CGameView::RenderOverlays(
     249             :     Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
     250             : {
     251           0 :     g_Renderer.GetSceneRenderer().RenderSceneOverlays(deviceCommandContext);
     252           0 : }
     253             : 
     254             : ///////////////////////////////////////////////////////////
     255             : // This callback is part of the Scene interface
     256             : // Submit all objects visible in the given frustum
     257           0 : void CGameView::EnumerateObjects(const CFrustum& frustum, SceneCollector* c)
     258             : {
     259             :     {
     260           0 :     PROFILE3("submit terrain");
     261             : 
     262           0 :     CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
     263           0 :     float waterHeight = g_Renderer.GetSceneRenderer().GetWaterManager().m_WaterHeight + 0.001f;
     264           0 :     const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide();
     265             : 
     266             :     // find out which patches will be drawn
     267           0 :     for (ssize_t j=0; j<patchesPerSide; ++j)
     268             :     {
     269           0 :         for (ssize_t i=0; i<patchesPerSide; ++i)
     270             :         {
     271           0 :             CPatch* patch=pTerrain->GetPatch(i,j);   // can't fail
     272             : 
     273             :             // If the patch is underwater, calculate a bounding box that also contains the water plane
     274           0 :             CBoundingBoxAligned bounds = patch->GetWorldBounds();
     275           0 :             if(bounds[1].Y < waterHeight)
     276           0 :                 bounds[1].Y = waterHeight;
     277             : 
     278           0 :             if (!m->Culling || frustum.IsBoxVisible(bounds))
     279           0 :                 c->Submit(patch);
     280             :         }
     281             :     }
     282             :     }
     283             : 
     284           0 :     m->Game->GetSimulation2()->RenderSubmit(*c, frustum, m->Culling);
     285           0 : }
     286             : 
     287           0 : void CGameView::UnloadResources()
     288             : {
     289           0 :     g_TexMan.UnloadTerrainTextures();
     290           0 :     g_Renderer.GetSceneRenderer().GetWaterManager().UnloadWaterTextures();
     291           0 : }
     292             : 
     293           0 : void CGameView::Update(const float deltaRealTime)
     294             : {
     295           0 :     m->MiniMapTexture.Update(deltaRealTime);
     296             : 
     297             :     // If camera movement is being handled by the touch-input system,
     298             :     // then we should stop to avoid conflicting with it
     299           0 :     if (g_TouchInput.IsEnabled())
     300           0 :         return;
     301             : 
     302           0 :     if (!g_app_has_focus)
     303           0 :         return;
     304             : 
     305           0 :     m->CinemaManager.Update(deltaRealTime);
     306           0 :     if (m->CinemaManager.IsEnabled())
     307           0 :         return;
     308             : 
     309           0 :     m->CameraController->Update(deltaRealTime);
     310             : }
     311             : 
     312           0 : CVector3D CGameView::GetCameraPivot() const
     313             : {
     314           0 :     return m->CameraController->GetCameraPivot();
     315             : }
     316             : 
     317           0 : CVector3D CGameView::GetCameraPosition() const
     318             : {
     319           0 :     return m->CameraController->GetCameraPosition();
     320             : }
     321             : 
     322           0 : CVector3D CGameView::GetCameraRotation() const
     323             : {
     324           0 :     return m->CameraController->GetCameraRotation();
     325             : }
     326             : 
     327           0 : float CGameView::GetCameraZoom() const
     328             : {
     329           0 :     return m->CameraController->GetCameraZoom();
     330             : }
     331             : 
     332           0 : void CGameView::SetCamera(const CVector3D& pos, float rotX, float rotY, float zoom)
     333             : {
     334           0 :     m->CameraController->SetCamera(pos, rotX, rotY, zoom);
     335           0 : }
     336             : 
     337           0 : void CGameView::MoveCameraTarget(const CVector3D& target)
     338             : {
     339           0 :     m->CameraController->MoveCameraTarget(target);
     340           0 : }
     341             : 
     342           0 : void CGameView::ResetCameraTarget(const CVector3D& target)
     343             : {
     344           0 :     m->CameraController->ResetCameraTarget(target);
     345           0 : }
     346             : 
     347           0 : void CGameView::FollowEntity(entity_id_t entity, bool firstPerson)
     348             : {
     349           0 :     m->CameraController->FollowEntity(entity, firstPerson);
     350           0 : }
     351             : 
     352           0 : entity_id_t CGameView::GetFollowedEntity()
     353             : {
     354           0 :     return m->CameraController->GetFollowedEntity();
     355             : }
     356             : 
     357           7 : InReaction game_view_handler(const SDL_Event_* ev)
     358             : {
     359             :     // put any events that must be processed even if inactive here
     360           7 :     if (!g_app_has_focus || !g_Game || !g_Game->IsGameStarted() || g_Game->GetView()->GetCinema()->IsEnabled())
     361           7 :         return IN_PASS;
     362             : 
     363           0 :     CGameView *pView=g_Game->GetView();
     364             : 
     365           0 :     return pView->HandleEvent(ev);
     366             : }
     367             : 
     368           0 : InReaction CGameView::HandleEvent(const SDL_Event_* ev)
     369             : {
     370           0 :     switch(ev->ev.type)
     371             :     {
     372           0 :     case SDL_HOTKEYPRESS:
     373             :     {
     374           0 :         std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
     375           0 :         CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
     376           0 :         if (hotkey == "wireframe")
     377             :         {
     378           0 :             if (g_XmppClient && g_rankedGame == true)
     379             :                 break;
     380           0 :             else if (sceneRenderer.GetModelRenderMode() == SOLID)
     381             :             {
     382           0 :                 sceneRenderer.SetTerrainRenderMode(EDGED_FACES);
     383           0 :                 sceneRenderer.SetWaterRenderMode(EDGED_FACES);
     384           0 :                 sceneRenderer.SetModelRenderMode(EDGED_FACES);
     385           0 :                 sceneRenderer.SetOverlayRenderMode(EDGED_FACES);
     386             :             }
     387           0 :             else if (sceneRenderer.GetModelRenderMode() == EDGED_FACES)
     388             :             {
     389           0 :                 sceneRenderer.SetTerrainRenderMode(WIREFRAME);
     390           0 :                 sceneRenderer.SetWaterRenderMode(WIREFRAME);
     391           0 :                 sceneRenderer.SetModelRenderMode(WIREFRAME);
     392           0 :                 sceneRenderer.SetOverlayRenderMode(WIREFRAME);
     393             :             }
     394             :             else
     395             :             {
     396           0 :                 sceneRenderer.SetTerrainRenderMode(SOLID);
     397           0 :                 sceneRenderer.SetWaterRenderMode(SOLID);
     398           0 :                 sceneRenderer.SetModelRenderMode(SOLID);
     399           0 :                 sceneRenderer.SetOverlayRenderMode(SOLID);
     400             :             }
     401           0 :             return IN_HANDLED;
     402           0 :         }
     403             :     }
     404             :     }
     405             : 
     406           0 :     return m->CameraController->HandleEvent(ev);
     407           3 : }

Generated by: LCOV version 1.13