/* Copyright (C) 2017 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 . */ /* * higher level interface on top of OpenGL to render basic objects: * terrain, models, sprites, particles etc. */ #ifndef INCLUDED_RENDERER #define INCLUDED_RENDERER #include "graphics/Camera.h" #include "graphics/SColor.h" #include "graphics/ShaderProgramPtr.h" #include "lib/file/vfs/vfs_path.h" #include "lib/res/handle.h" #include "ps/Singleton.h" #include "graphics/ShaderDefines.h" #include "renderer/Scene.h" // necessary declarations class CFontManager; class CLightEnv; class CMaterial; class CMaterialManager; class CModel; class CParticleManager; class CPatch; class CPostprocManager; class CShaderManager; class CSimulation2; class CTextureManager; class CTimeManager; class RenderPathVertexShader; 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 }; // access to sole renderer object #define g_Renderer CRenderer::GetSingleton() /////////////////////////////////////////////////////////////////////////////////////////// // CRenderer: base renderer class - primary interface to the rendering engine struct CRendererInternals; class CRenderer : public Singleton, private SceneCollector { public: // various enumerations and renderer related constants enum { NumAlphaMaps=14 }; enum Option { OPT_NOVBO, OPT_SHADOWS, OPT_WATEREFFECTS, OPT_WATERFANCYEFFECTS, OPT_WATERREALDEPTH, OPT_WATERREFLECTION, OPT_WATERREFRACTION, OPT_SHADOWSONWATER, OPT_SHADOWPCF, OPT_PARTICLES, OPT_PREFERGLSL, OPT_FOG, OPT_SILHOUETTES, OPT_SHOWSKY, OPT_SMOOTHLOS, OPT_POSTPROC, OPT_DISPLAYFRUSTUM, }; enum CullGroup { CULL_DEFAULT, CULL_SHADOWS, CULL_REFLECTIONS, CULL_REFRACTIONS, CULL_SILHOUETTE_OCCLUDER, CULL_SILHOUETTE_CASTER, CULL_MAX }; enum RenderPath { // If no rendering path is configured explicitly, the renderer // will choose the path when Open() is called. RP_DEFAULT, // Classic fixed function. RP_FIXED, // Use new ARB/GLSL system RP_SHADER }; // stats class - per frame counts of number of draw calls, poly counts etc struct Stats { // set all stats to zero void Reset() { memset(this, 0, sizeof(*this)); } // number of draw calls per frame - total DrawElements + Begin/End immediate mode loops size_t m_DrawCalls; // number of terrain triangles drawn size_t m_TerrainTris; // number of water triangles drawn size_t m_WaterTris; // number of (non-transparent) model triangles drawn size_t m_ModelTris; // number of overlay triangles drawn size_t m_OverlayTris; // number of splat passes for alphamapping size_t m_BlendSplats; // number of particles size_t m_Particles; }; // renderer options struct Options { bool m_NoVBO; bool m_Shadows; bool m_WaterEffects; bool m_WaterFancyEffects; bool m_WaterRealDepth; bool m_WaterRefraction; bool m_WaterReflection; bool m_WaterShadows; RenderPath m_RenderPath; bool m_ShadowAlphaFix; bool m_ARBProgramShadow; bool m_ShadowPCF; bool m_Particles; bool m_PreferGLSL; bool m_ForceAlphaTest; bool m_GPUSkinning; bool m_Fog; bool m_Silhouettes; bool m_SmoothLOS; bool m_ShowSky; bool m_Postproc; bool m_DisplayFrustum; } m_Options; struct Caps { bool m_VBO; bool m_ARBProgram; bool m_ARBProgramShadow; bool m_VertexShader; bool m_FragmentShader; bool m_Shadows; bool m_PrettyWater; }; public: // constructor, destructor CRenderer(); ~CRenderer(); // open up the renderer: performs any necessary initialisation bool Open(int width,int height); // resize renderer view void Resize(int width,int height); // set/get boolean renderer option void SetOptionBool(enum Option opt, bool value); bool GetOptionBool(enum Option opt) const; void SetRenderPath(RenderPath rp); RenderPath GetRenderPath() const { return m_Options.m_RenderPath; } static CStr GetRenderPathName(RenderPath rp); static RenderPath GetRenderPathByName(const CStr& name); // return view width int GetWidth() const { return m_Width; } // return view height int GetHeight() const { return m_Height; } // return view aspect ratio float GetAspect() const { return float(m_Width)/float(m_Height); } // signal frame start void BeginFrame(); // signal frame end 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); // set color used to clear screen in BeginFrame() void SetClearColor(SColor4ub color); // 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); // set the viewport void SetViewport(const SViewPort &); // get the last viewport SViewPort GetViewport(); /** * Render the given scene immediately. * @param scene a Scene object describing what should be rendered. */ void RenderScene(Scene& scene); /** * 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(); // 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; } // debugging void SetDisplayTerrainPriorities(bool enabled) { m_DisplayTerrainPriorities = enabled; } // bind a GL texture object to active unit void BindTexture(int unit, unsigned int tex); // load the default set of alphamaps. // return a negative error code if anything along the way fails. // called via delay-load mechanism. int LoadAlphaMaps(); void UnloadAlphaMaps(); // return stats accumulated for current frame Stats& GetStats() { return m_Stats; } // 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() { return m_WaterManager; } /** * GetSkyManager: Return the renderer's sky manager. * * @return the SkyManager object used by the renderer */ SkyManager* GetSkyManager() { return m_SkyManager; } CTextureManager& GetTextureManager(); CShaderManager& GetShaderManager(); CParticleManager& GetParticleManager(); TerrainRenderer& GetTerrainRenderer(); CMaterialManager& GetMaterialManager(); CFontManager& GetFontManager(); CShaderDefines GetSystemShaderDefines() { return m_SystemShaderDefines; } CTimeManager& GetTimeManager(); CPostprocManager& GetPostprocManager(); /** * GetCapabilities: Return which OpenGL capabilities are available and enabled. * * @return capabilities structure */ const Caps& GetCapabilities() const { return m_Caps; } ShadowMap& GetShadowMap(); /** * Resets the render state to default, that was before a game started */ void ResetState(); protected: friend struct CRendererInternals; friend class CVertexBuffer; friend class CPatchRData; friend class CDecalRData; friend class FixedFunctionModelRenderer; friend class ModelRenderer; friend class PolygonSortModelRenderer; friend class SortModelRenderer; friend class RenderPathVertexShader; friend class HWLightingModelRenderer; friend class ShaderModelVertexRenderer; friend class InstancingModelRenderer; friend class ShaderInstancingModelRenderer; friend class TerrainRenderer; friend class WaterRenderer; //BEGIN: Implementation of SceneCollector void Submit(CPatch* patch); void Submit(SOverlayLine* overlay); void Submit(SOverlayTexturedLine* overlay); void Submit(SOverlaySprite* overlay); void Submit(SOverlayQuad* overlay); void Submit(CModelDecal* decal); void Submit(CParticleEmitter* emitter); void Submit(SOverlaySphere* overlay); void SubmitNonRecursive(CModel* model); //END: Implementation of SceneCollector // render any batched objects void RenderSubmissions(const CBoundingBoxAligned& waterScissor); // patch rendering stuff void RenderPatches(const CShaderDefines& context, int cullGroup); // model rendering stuff void RenderModels(const CShaderDefines& context, int cullGroup); void RenderTransparentModels(const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode, bool disableFaceCulling); void RenderSilhouettes(const CShaderDefines& context); void RenderParticles(int cullGroup); // shadow rendering stuff void RenderShadowMap(const CShaderDefines& context); // render water reflection and refraction textures void RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor); void RenderRefractions(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; void ReloadShaders(); void RecomputeSystemShaderDefines(); // hotloading static Status ReloadChangedFileCB(void* param, const VfsPath& path); // RENDERER DATA: /// Private data that is not needed by inline functions CRendererInternals* m; // view width int m_Width; // view height int m_Height; // current terrain rendering mode ERenderMode m_TerrainRenderMode; // current water rendering mode ERenderMode m_WaterRenderMode; // current model rendering mode ERenderMode m_ModelRenderMode; CShaderDefines m_SystemShaderDefines; SViewPort m_Viewport; /** * 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; // color used to clear screen in BeginFrame float m_ClearColor[4]; // current lighting setup CLightEnv* m_LightEnv; // ogl_tex handle of composite alpha map (all the alpha maps packed into one texture) Handle m_hCompositeAlphaMap; // coordinates of each (untransformed) alpha map within the packed texture struct { float u0,u1,v0,v1; } m_AlphaMapCoords[NumAlphaMaps]; // card capabilities Caps m_Caps; // build card cap bits void EnumCaps(); // per-frame renderer stats Stats m_Stats; /** * m_WaterManager: the WaterManager object used for water textures and settings * (e.g. water color, water height) */ WaterManager* m_WaterManager; /** * m_SkyManager: the SkyManager object used for sky textures and settings */ SkyManager* m_SkyManager; /** * Enable rendering of terrain tile priority text overlay, for debugging. */ bool m_DisplayTerrainPriorities; public: /** * m_ShadowZBias: Z bias used when rendering shadows into a depth texture. * This can be used to control shadowing artifacts. * * Can be accessed via JS as renderer.shadowZBias * ShadowMap uses this for matrix calculation. */ float m_ShadowZBias; /** * m_ShadowMapSize: Size of shadow map, or 0 for default. Typically slow but useful * for high-quality rendering. Changes don't take effect until the shadow map * is regenerated. * * Can be accessed via JS as renderer.shadowMapSize */ int m_ShadowMapSize; /** * m_SkipSubmit: Disable the actual submission of rendering commands to OpenGL. * All state setup is still performed as usual. * * Can be accessed via JS as renderer.skipSubmit */ bool m_SkipSubmit; }; #endif