/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_RENDERER_SCENERENDERER #define INCLUDED_RENDERER_SCENERENDERER #include "graphics/Camera.h" #include "graphics/ShaderDefines.h" #include "graphics/ShaderProgramPtr.h" #include "maths/BoundingBoxAligned.h" #include "ps/Singleton.h" #include "renderer/backend/IDeviceCommandContext.h" #include "renderer/RenderingOptions.h" #include "renderer/Scene.h" #include class CCanvas2D; class CLightEnv; class CMaterial; class CMaterialManager; class CModel; class CParticleManager; class CPatch; class CSimulation2; class ShadowMap; class SkyManager; class TerrainRenderer; class WaterManager; // rendering modes enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES }; // transparency modes enum ETransparentMode { TRANSPARENT, TRANSPARENT_OPAQUE, TRANSPARENT_BLEND }; class CSceneRenderer : public SceneCollector { public: enum CullGroup { CULL_DEFAULT, CULL_SHADOWS_CASCADE_0, CULL_SHADOWS_CASCADE_1, CULL_SHADOWS_CASCADE_2, CULL_SHADOWS_CASCADE_3, CULL_REFLECTIONS, CULL_REFRACTIONS, CULL_SILHOUETTE_OCCLUDER, CULL_SILHOUETTE_CASTER, CULL_MAX }; CSceneRenderer(Renderer::Backend::IDevice* device); ~CSceneRenderer(); void Initialize(); void Resize(int width, int height); void BeginFrame(); void EndFrame(); /** * Set simulation context for rendering purposes. * Must be called at least once when the game has started and before * frames are rendered. */ void SetSimulation(CSimulation2* simulation); // trigger a reload of shaders (when parameters they depend on have changed) void MakeShadersDirty(); /** * Set up the camera used for rendering the next scene; this includes * setting OpenGL state like viewport, projection and modelview matrices. * * @param viewCamera this camera determines the eye position for rendering * @param cullCamera this camera determines the frustum for culling in the renderer and * for shadow calculations */ void SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera); /** * Enumerate and submit all objects of the given scene which should be rendered. * Must be called before RenderScene. */ void PrepareScene( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Scene& scene); /** * Render submitted objects of the previously given scene. */ void RenderScene( Renderer::Backend::IDeviceCommandContext* deviceCommandContext); /** * Render overlays of the previously given scene. * Must be called after RenderScene. */ void RenderSceneOverlays( Renderer::Backend::IDeviceCommandContext* deviceCommandContext); /** * Return the scene that is currently being rendered. * Only valid when the renderer is in a RenderScene call. */ Scene& GetScene(); /** * Render text overlays on top of the scene. * Assumes the caller has set up the GL environment for orthographic rendering * with texturing and blending. */ void RenderTextOverlays(CCanvas2D& canvas); // set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer, // so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering) void SetLightEnv(CLightEnv* lightenv) { m_LightEnv = lightenv; } // set the mode to render subsequent terrain patches void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode = mode; } // get the mode to render subsequent terrain patches ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; } // set the mode to render subsequent water patches void SetWaterRenderMode(ERenderMode mode) { m_WaterRenderMode = mode; } // get the mode to render subsequent water patches ERenderMode GetWaterRenderMode() const { return m_WaterRenderMode; } // set the mode to render subsequent models void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode = mode; } // get the mode to render subsequent models ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; } // Get the mode to render subsequent overlays. ERenderMode GetOverlayRenderMode() const { return m_OverlayRenderMode; } // Set the mode to render subsequent overlays. void SetOverlayRenderMode(ERenderMode mode) { m_OverlayRenderMode = mode; } // debugging void SetDisplayTerrainPriorities(bool enabled) { m_DisplayTerrainPriorities = enabled; } // return the current light environment const CLightEnv &GetLightEnv() { return *m_LightEnv; } // return the current view camera const CCamera& GetViewCamera() const { return m_ViewCamera; } // replace the current view camera void SetViewCamera(const CCamera& camera) { m_ViewCamera = camera; } // return the current cull camera const CCamera& GetCullCamera() const { return m_CullCamera; } /** * GetWaterManager: Return the renderer's water manager. * * @return the WaterManager object used by the renderer */ WaterManager& GetWaterManager(); /** * GetSkyManager: Return the renderer's sky manager. * * @return the SkyManager object used by the renderer */ SkyManager& GetSkyManager(); CParticleManager& GetParticleManager(); TerrainRenderer& GetTerrainRenderer(); CMaterialManager& GetMaterialManager(); ShadowMap& GetShadowMap(); /** * Resets the render state to default, that was before a game started */ void ResetState(); void ReloadShaders(Renderer::Backend::IDevice* device); protected: void Submit(CPatch* patch) override; void Submit(SOverlayLine* overlay) override; void Submit(SOverlayTexturedLine* overlay) override; void Submit(SOverlaySprite* overlay) override; void Submit(SOverlayQuad* overlay) override; void Submit(CModelDecal* decal) override; void Submit(CParticleEmitter* emitter) override; void Submit(SOverlaySphere* overlay) override; void SubmitNonRecursive(CModel* model) override; /** * Update and upload all needed data for submitted objects. */ void PrepareSubmissions( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CBoundingBoxAligned& waterScissor); // render any batched objects void RenderSubmissions( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CBoundingBoxAligned& waterScissor); // patch rendering stuff void RenderPatches( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context, int cullGroup); // model rendering stuff void RenderModels( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context, int cullGroup); void RenderTransparentModels( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode); void RenderSilhouettes( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context); void RenderParticles( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, int cullGroup); // shadow rendering stuff void RenderShadowMap( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context); // render water reflection and refraction textures void RenderReflections( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context, const CBoundingBoxAligned& scissor); void RenderRefractions( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CShaderDefines& context, const CBoundingBoxAligned& scissor); void ComputeReflectionCamera(CCamera& camera, const CBoundingBoxAligned& scissor) const; void ComputeRefractionCamera(CCamera& camera, const CBoundingBoxAligned& scissor) const; // debugging void DisplayFrustum(); // enable oblique frustum clipping with the given clip plane void SetObliqueFrustumClipping(CCamera& camera, const CVector4D& clipPlane) const; // Private data that is not needed by inline functions. class Internals; std::unique_ptr m; // Current terrain rendering mode. ERenderMode m_TerrainRenderMode; // Current water rendering mode. ERenderMode m_WaterRenderMode; // Current model rendering mode. ERenderMode m_ModelRenderMode; // Current overlay rendering mode. ERenderMode m_OverlayRenderMode; /** * m_ViewCamera: determines the eye position for rendering * * @see CGameView::m_ViewCamera */ CCamera m_ViewCamera; /** * m_CullCamera: determines the frustum for culling and shadowmap calculations * * @see CGameView::m_ViewCamera */ CCamera m_CullCamera; // only valid inside a call to RenderScene Scene* m_CurrentScene; int m_CurrentCullGroup; CBoundingBoxAligned m_WaterScissor; // current lighting setup CLightEnv* m_LightEnv; /** * Enable rendering of terrain tile priority text overlay, for debugging. */ bool m_DisplayTerrainPriorities; }; #endif // INCLUDED_RENDERER_SCENERENDERER