Line data Source code
1 : /* Copyright (C) 2023 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 : #ifndef INCLUDED_RENDERER
19 : #define INCLUDED_RENDERER
20 :
21 : #include "graphics/Camera.h"
22 : #include "graphics/ShaderDefines.h"
23 : #include "graphics/ShaderProgramPtr.h"
24 : #include "ps/containers/Span.h"
25 : #include "ps/Singleton.h"
26 : #include "renderer/backend/IDeviceCommandContext.h"
27 : #include "renderer/backend/IShaderProgram.h"
28 : #include "renderer/RenderingOptions.h"
29 : #include "renderer/Scene.h"
30 :
31 : #include <memory>
32 :
33 : class CDebugRenderer;
34 : class CFontManager;
35 : class CPostprocManager;
36 : class CSceneRenderer;
37 : class CShaderManager;
38 : class CTextureManager;
39 : class CTimeManager;
40 :
41 : #define g_Renderer CRenderer::GetSingleton()
42 :
43 : /**
44 : * Higher level interface on top of the whole frame rendering. It does know
45 : * what should be rendered and via which renderer but shouldn't know how to
46 : * render a particular area, like UI or scene.
47 : */
48 : class CRenderer : public Singleton<CRenderer>
49 : {
50 : public:
51 : // stats class - per frame counts of number of draw calls, poly counts etc
52 : struct Stats
53 : {
54 : // set all stats to zero
55 6 : void Reset() { memset(this, 0, sizeof(*this)); }
56 : // number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
57 : size_t m_DrawCalls;
58 : // number of terrain triangles drawn
59 : size_t m_TerrainTris;
60 : // number of water triangles drawn
61 : size_t m_WaterTris;
62 : // number of (non-transparent) model triangles drawn
63 : size_t m_ModelTris;
64 : // number of overlay triangles drawn
65 : size_t m_OverlayTris;
66 : // number of splat passes for alphamapping
67 : size_t m_BlendSplats;
68 : // number of particles
69 : size_t m_Particles;
70 : };
71 :
72 : enum class ScreenShotType
73 : {
74 : NONE,
75 : DEFAULT,
76 : BIG
77 : };
78 :
79 : public:
80 : CRenderer();
81 : ~CRenderer();
82 :
83 : // open up the renderer: performs any necessary initialisation
84 : bool Open(int width, int height);
85 :
86 : // resize renderer view
87 : void Resize(int width, int height);
88 :
89 : // return view width
90 0 : int GetWidth() const { return m_Width; }
91 : // return view height
92 0 : int GetHeight() const { return m_Height; }
93 :
94 : void RenderFrame(bool needsPresent);
95 :
96 : // signal frame start
97 : void BeginFrame();
98 : // signal frame end
99 : void EndFrame();
100 :
101 : // trigger a reload of shaders (when parameters they depend on have changed)
102 : void MakeShadersDirty();
103 :
104 : // return stats accumulated for current frame
105 0 : Stats& GetStats() { return m_Stats; }
106 :
107 : CTextureManager& GetTextureManager();
108 :
109 : CShaderManager& GetShaderManager();
110 :
111 : CFontManager& GetFontManager();
112 :
113 : CTimeManager& GetTimeManager();
114 :
115 : CPostprocManager& GetPostprocManager();
116 :
117 : CSceneRenderer& GetSceneRenderer();
118 :
119 : CDebugRenderer& GetDebugRenderer();
120 :
121 : /**
122 : * Performs a complete frame without presenting to force loading all needed
123 : * resources. It's used for the first frame on a game start.
124 : * TODO: It might be better to preload resources without a complete frame
125 : * rendering.
126 : */
127 : void PreloadResourcesBeforeNextFrame();
128 :
129 : /**
130 : * Makes a screenshot on the next RenderFrame according of the given
131 : * screenshot type.
132 : */
133 : void MakeScreenShotOnNextFrame(ScreenShotType screenShotType);
134 :
135 : Renderer::Backend::IDeviceCommandContext* GetDeviceCommandContext();
136 :
137 : /**
138 : * Returns a cached vertex input layout. The renderer owns the layout to be
139 : * able to share it between different clients. As backend should have
140 : * as few different layouts as possible.
141 : * The function isn't cheap so it should be called as rarely as possible.
142 : * TODO: we need to make VertexArray less error prone by passing layout.
143 : */
144 : Renderer::Backend::IVertexInputLayout* GetVertexInputLayout(
145 : const PS::span<const Renderer::Backend::SVertexAttributeFormat> attributes);
146 :
147 : protected:
148 : friend class CPatchRData;
149 : friend class CDecalRData;
150 : friend class HWLightingModelRenderer;
151 : friend class ShaderModelVertexRenderer;
152 : friend class InstancingModelRenderer;
153 : friend class CRenderingOptions;
154 :
155 : bool ShouldRender() const;
156 :
157 : void RenderFrameImpl(const bool renderGUI, const bool renderLogger);
158 : void RenderFrame2D(const bool renderGUI, const bool renderLogger);
159 : void RenderScreenShot(const bool needsPresent);
160 : void RenderBigScreenShot(const bool needsPresent);
161 :
162 : // SetRenderPath: Select the preferred render path.
163 : // This may only be called before Open(), because the layout of vertex arrays and other
164 : // data may depend on the chosen render path.
165 : void SetRenderPath(RenderPath rp);
166 :
167 : void ReloadShaders();
168 :
169 : // Private data that is not needed by inline functions.
170 : class Internals;
171 : std::unique_ptr<Internals> m;
172 : // view width
173 : int m_Width = 0;
174 : // view height
175 : int m_Height = 0;
176 :
177 : // per-frame renderer stats
178 : Stats m_Stats;
179 :
180 : bool m_ShouldPreloadResourcesBeforeNextFrame = false;
181 :
182 : ScreenShotType m_ScreenShotType = ScreenShotType::NONE;
183 : };
184 :
185 : #endif // INCLUDED_RENDERER
|