1 /* Copyright (C) 2017 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  * higher level interface on top of OpenGL to render basic objects:
20  * terrain, models, sprites, particles etc.
21  */
22 
23 #ifndef INCLUDED_RENDERER
24 #define INCLUDED_RENDERER
25 
26 #include "graphics/Camera.h"
27 #include "graphics/SColor.h"
28 #include "graphics/ShaderProgramPtr.h"
29 #include "lib/file/vfs/vfs_path.h"
30 #include "lib/res/handle.h"
31 #include "ps/Singleton.h"
32 
33 #include "graphics/ShaderDefines.h"
34 #include "renderer/Scene.h"
35 
36 // necessary declarations
37 class CFontManager;
38 class CLightEnv;
39 class CMaterial;
40 class CMaterialManager;
41 class CModel;
42 class CParticleManager;
43 class CPatch;
44 class CPostprocManager;
45 class CShaderManager;
46 class CSimulation2;
47 class CTextureManager;
48 class CTimeManager;
49 class RenderPathVertexShader;
50 class ShadowMap;
51 class SkyManager;
52 class TerrainRenderer;
53 class WaterManager;
54 
55 // rendering modes
56 enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
57 
58 // transparency modes
59 enum ETransparentMode { TRANSPARENT, TRANSPARENT_OPAQUE, TRANSPARENT_BLEND };
60 
61 // access to sole renderer object
62 #define g_Renderer CRenderer::GetSingleton()
63 
64 ///////////////////////////////////////////////////////////////////////////////////////////
65 // CRenderer: base renderer class - primary interface to the rendering engine
66 struct CRendererInternals;
67 
68 class CRenderer :
69 	public Singleton<CRenderer>,
70 	private SceneCollector
71 {
72 public:
73 	// various enumerations and renderer related constants
74 	enum { NumAlphaMaps=14 };
75 	enum Option {
76 		OPT_NOVBO,
77 		OPT_SHADOWS,
78 		OPT_WATEREFFECTS,
79 		OPT_WATERFANCYEFFECTS,
80 		OPT_WATERREALDEPTH,
81 		OPT_WATERREFLECTION,
82 		OPT_WATERREFRACTION,
83 		OPT_SHADOWSONWATER,
84 		OPT_SHADOWPCF,
85 		OPT_PARTICLES,
86 		OPT_PREFERGLSL,
87 		OPT_FOG,
88 		OPT_SILHOUETTES,
89 		OPT_SHOWSKY,
90 		OPT_SMOOTHLOS,
91 		OPT_POSTPROC,
92 		OPT_DISPLAYFRUSTUM,
93 	};
94 
95 	enum CullGroup {
96 		CULL_DEFAULT,
97 		CULL_SHADOWS,
98 		CULL_REFLECTIONS,
99 		CULL_REFRACTIONS,
100 		CULL_SILHOUETTE_OCCLUDER,
101 		CULL_SILHOUETTE_CASTER,
102 		CULL_MAX
103 	};
104 
105 	enum RenderPath {
106 		// If no rendering path is configured explicitly, the renderer
107 		// will choose the path when Open() is called.
108 		RP_DEFAULT,
109 
110 		// Classic fixed function.
111 		RP_FIXED,
112 
113 		// Use new ARB/GLSL system
114 		RP_SHADER
115 	};
116 
117 	// stats class - per frame counts of number of draw calls, poly counts etc
118 	struct Stats {
119 		// set all stats to zero
ResetStats120 		void Reset() { memset(this, 0, sizeof(*this)); }
121 		// number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
122 		size_t m_DrawCalls;
123 		// number of terrain triangles drawn
124 		size_t m_TerrainTris;
125 		// number of water triangles drawn
126 		size_t m_WaterTris;
127 		// number of (non-transparent) model triangles drawn
128 		size_t m_ModelTris;
129 		// number of overlay triangles drawn
130 		size_t m_OverlayTris;
131 		// number of splat passes for alphamapping
132 		size_t m_BlendSplats;
133 		// number of particles
134 		size_t m_Particles;
135 	};
136 
137 	// renderer options
138 	struct Options {
139 		bool m_NoVBO;
140 		bool m_Shadows;
141 
142 		bool m_WaterEffects;
143 		bool m_WaterFancyEffects;
144 		bool m_WaterRealDepth;
145 		bool m_WaterRefraction;
146 		bool m_WaterReflection;
147 		bool m_WaterShadows;
148 
149 		RenderPath m_RenderPath;
150 		bool m_ShadowAlphaFix;
151 		bool m_ARBProgramShadow;
152 		bool m_ShadowPCF;
153 		bool m_Particles;
154 		bool m_PreferGLSL;
155 		bool m_ForceAlphaTest;
156 		bool m_GPUSkinning;
157 		bool m_Fog;
158 		bool m_Silhouettes;
159 		bool m_SmoothLOS;
160 		bool m_ShowSky;
161 		bool m_Postproc;
162 		bool m_DisplayFrustum;
163 	} m_Options;
164 
165 	struct Caps {
166 		bool m_VBO;
167 		bool m_ARBProgram;
168 		bool m_ARBProgramShadow;
169 		bool m_VertexShader;
170 		bool m_FragmentShader;
171 		bool m_Shadows;
172 		bool m_PrettyWater;
173 	};
174 
175 public:
176 	// constructor, destructor
177 	CRenderer();
178 	~CRenderer();
179 
180 	// open up the renderer: performs any necessary initialisation
181 	bool Open(int width,int height);
182 
183 	// resize renderer view
184 	void Resize(int width,int height);
185 
186 	// set/get boolean renderer option
187 	void SetOptionBool(enum Option opt, bool value);
188 	bool GetOptionBool(enum Option opt) const;
189 	void SetRenderPath(RenderPath rp);
GetRenderPath()190 	RenderPath GetRenderPath() const { return m_Options.m_RenderPath; }
191 	static CStr GetRenderPathName(RenderPath rp);
192 	static RenderPath GetRenderPathByName(const CStr& name);
193 
194 	// return view width
GetWidth()195 	int GetWidth() const { return m_Width; }
196 	// return view height
GetHeight()197 	int GetHeight() const { return m_Height; }
198 	// return view aspect ratio
GetAspect()199 	float GetAspect() const { return float(m_Width)/float(m_Height); }
200 
201 	// signal frame start
202 	void BeginFrame();
203 	// signal frame end
204 	void EndFrame();
205 
206 	/**
207 	 * Set simulation context for rendering purposes.
208 	 * Must be called at least once when the game has started and before
209 	 * frames are rendered.
210 	 */
211 	void SetSimulation(CSimulation2* simulation);
212 
213 	// set color used to clear screen in BeginFrame()
214 	void SetClearColor(SColor4ub color);
215 
216 	// trigger a reload of shaders (when parameters they depend on have changed)
217 	void MakeShadersDirty();
218 
219 	/**
220 	 * Set up the camera used for rendering the next scene; this includes
221 	 * setting OpenGL state like viewport, projection and modelview matrices.
222 	 *
223 	 * @param viewCamera this camera determines the eye position for rendering
224 	 * @param cullCamera this camera determines the frustum for culling in the renderer and
225 	 * for shadow calculations
226 	 */
227 	void SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera);
228 
229 	// set the viewport
230 	void SetViewport(const SViewPort &);
231 
232 	// get the last viewport
233 	SViewPort GetViewport();
234 
235 	/**
236 	 * Render the given scene immediately.
237 	 * @param scene a Scene object describing what should be rendered.
238 	 */
239 	void RenderScene(Scene& scene);
240 
241 	/**
242 	 * Return the scene that is currently being rendered.
243 	 * Only valid when the renderer is in a RenderScene call.
244 	 */
245 	Scene& GetScene();
246 
247 	/**
248 	 * Render text overlays on top of the scene.
249 	 * Assumes the caller has set up the GL environment for orthographic rendering
250 	 * with texturing and blending.
251 	 */
252 	void RenderTextOverlays();
253 
254 	// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
255 	// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
SetLightEnv(CLightEnv * lightenv)256 	void SetLightEnv(CLightEnv* lightenv) {
257 		m_LightEnv=lightenv;
258 	}
259 
260 	// set the mode to render subsequent terrain patches
SetTerrainRenderMode(ERenderMode mode)261 	void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode = mode; }
262 	// get the mode to render subsequent terrain patches
GetTerrainRenderMode()263 	ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; }
264 
265 	// set the mode to render subsequent water patches
SetWaterRenderMode(ERenderMode mode)266 	void SetWaterRenderMode(ERenderMode mode) { m_WaterRenderMode = mode; }
267 	// get the mode to render subsequent water patches
GetWaterRenderMode()268 	ERenderMode GetWaterRenderMode() const { return m_WaterRenderMode; }
269 
270 	// set the mode to render subsequent models
SetModelRenderMode(ERenderMode mode)271 	void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode = mode; }
272 	// get the mode to render subsequent models
GetModelRenderMode()273 	ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; }
274 
275 	// debugging
SetDisplayTerrainPriorities(bool enabled)276 	void SetDisplayTerrainPriorities(bool enabled) { m_DisplayTerrainPriorities = enabled; }
277 
278 	// bind a GL texture object to active unit
279 	void BindTexture(int unit, unsigned int tex);
280 
281 	// load the default set of alphamaps.
282 	// return a negative error code if anything along the way fails.
283 	// called via delay-load mechanism.
284 	int LoadAlphaMaps();
285 	void UnloadAlphaMaps();
286 
287 	// return stats accumulated for current frame
GetStats()288 	Stats& GetStats() { return m_Stats; }
289 
290 	// return the current light environment
GetLightEnv()291 	const CLightEnv &GetLightEnv() { return *m_LightEnv; }
292 
293 	// return the current view camera
GetViewCamera()294 	const CCamera& GetViewCamera() const { return m_ViewCamera; }
295 	// replace the current view camera
SetViewCamera(const CCamera & camera)296 	void SetViewCamera(const CCamera& camera) { m_ViewCamera = camera; }
297 
298 	// return the current cull camera
GetCullCamera()299 	const CCamera& GetCullCamera() const { return m_CullCamera; }
300 
301 	/**
302 	 * GetWaterManager: Return the renderer's water manager.
303 	 *
304 	 * @return the WaterManager object used by the renderer
305 	 */
GetWaterManager()306 	WaterManager* GetWaterManager() { return m_WaterManager; }
307 
308 	/**
309 	 * GetSkyManager: Return the renderer's sky manager.
310 	 *
311 	 * @return the SkyManager object used by the renderer
312 	 */
GetSkyManager()313 	SkyManager* GetSkyManager() { return m_SkyManager; }
314 
315 	CTextureManager& GetTextureManager();
316 
317 	CShaderManager& GetShaderManager();
318 
319 	CParticleManager& GetParticleManager();
320 
321 	TerrainRenderer& GetTerrainRenderer();
322 
323 	CMaterialManager& GetMaterialManager();
324 
325 	CFontManager& GetFontManager();
326 
GetSystemShaderDefines()327 	CShaderDefines GetSystemShaderDefines() { return m_SystemShaderDefines; }
328 
329 	CTimeManager& GetTimeManager();
330 
331 	CPostprocManager& GetPostprocManager();
332 
333 	/**
334 	 * GetCapabilities: Return which OpenGL capabilities are available and enabled.
335 	 *
336 	 * @return capabilities structure
337 	 */
GetCapabilities()338 	const Caps& GetCapabilities() const { return m_Caps; }
339 
340 	ShadowMap& GetShadowMap();
341 
342 	/**
343 	 * Resets the render state to default, that was before a game started
344 	 */
345 	void ResetState();
346 
347 protected:
348 	friend struct CRendererInternals;
349 	friend class CVertexBuffer;
350 	friend class CPatchRData;
351 	friend class CDecalRData;
352 	friend class FixedFunctionModelRenderer;
353 	friend class ModelRenderer;
354 	friend class PolygonSortModelRenderer;
355 	friend class SortModelRenderer;
356 	friend class RenderPathVertexShader;
357 	friend class HWLightingModelRenderer;
358 	friend class ShaderModelVertexRenderer;
359 	friend class InstancingModelRenderer;
360 	friend class ShaderInstancingModelRenderer;
361 	friend class TerrainRenderer;
362 	friend class WaterRenderer;
363 
364 	//BEGIN: Implementation of SceneCollector
365 	void Submit(CPatch* patch);
366 	void Submit(SOverlayLine* overlay);
367 	void Submit(SOverlayTexturedLine* overlay);
368 	void Submit(SOverlaySprite* overlay);
369 	void Submit(SOverlayQuad* overlay);
370 	void Submit(CModelDecal* decal);
371 	void Submit(CParticleEmitter* emitter);
372 	void Submit(SOverlaySphere* overlay);
373 	void SubmitNonRecursive(CModel* model);
374 	//END: Implementation of SceneCollector
375 
376 	// render any batched objects
377 	void RenderSubmissions(const CBoundingBoxAligned& waterScissor);
378 
379 	// patch rendering stuff
380 	void RenderPatches(const CShaderDefines& context, int cullGroup);
381 
382 	// model rendering stuff
383 	void RenderModels(const CShaderDefines& context, int cullGroup);
384 	void RenderTransparentModels(const CShaderDefines& context, int cullGroup, ETransparentMode transparentMode, bool disableFaceCulling);
385 
386 	void RenderSilhouettes(const CShaderDefines& context);
387 
388 	void RenderParticles(int cullGroup);
389 
390 	// shadow rendering stuff
391 	void RenderShadowMap(const CShaderDefines& context);
392 
393 	// render water reflection and refraction textures
394 	void RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor);
395 	void RenderRefractions(const CShaderDefines& context, const CBoundingBoxAligned& scissor);
396 
397 	void ComputeReflectionCamera(CCamera& camera, const CBoundingBoxAligned& scissor) const;
398 	void ComputeRefractionCamera(CCamera& camera, const CBoundingBoxAligned& scissor) const;
399 
400 	// debugging
401 	void DisplayFrustum();
402 
403 	// enable oblique frustum clipping with the given clip plane
404 	void SetObliqueFrustumClipping(CCamera& camera, const CVector4D& clipPlane) const;
405 
406 	void ReloadShaders();
407 	void RecomputeSystemShaderDefines();
408 
409 	// hotloading
410 	static Status ReloadChangedFileCB(void* param, const VfsPath& path);
411 
412 	// RENDERER DATA:
413 	/// Private data that is not needed by inline functions
414 	CRendererInternals* m;
415 	// view width
416 	int m_Width;
417 	// view height
418 	int m_Height;
419 	// current terrain rendering mode
420 	ERenderMode m_TerrainRenderMode;
421 	// current water rendering mode
422 	ERenderMode m_WaterRenderMode;
423 	// current model rendering mode
424 	ERenderMode m_ModelRenderMode;
425 
426 	CShaderDefines m_SystemShaderDefines;
427 
428 	SViewPort m_Viewport;
429 
430 	/**
431 	 * m_ViewCamera: determines the eye position for rendering
432 	 *
433 	 * @see CGameView::m_ViewCamera
434 	 */
435 	CCamera m_ViewCamera;
436 
437 	/**
438 	 * m_CullCamera: determines the frustum for culling and shadowmap calculations
439 	 *
440 	 * @see CGameView::m_ViewCamera
441 	 */
442 	CCamera m_CullCamera;
443 
444 	// only valid inside a call to RenderScene
445 	Scene* m_CurrentScene;
446 	int m_CurrentCullGroup;
447 
448 	// color used to clear screen in BeginFrame
449 	float m_ClearColor[4];
450 	// current lighting setup
451 	CLightEnv* m_LightEnv;
452 	// ogl_tex handle of composite alpha map (all the alpha maps packed into one texture)
453 	Handle m_hCompositeAlphaMap;
454 	// coordinates of each (untransformed) alpha map within the packed texture
455 	struct {
456 		float u0,u1,v0,v1;
457 	} m_AlphaMapCoords[NumAlphaMaps];
458 	// card capabilities
459 	Caps m_Caps;
460 	// build card cap bits
461 	void EnumCaps();
462 	// per-frame renderer stats
463 	Stats m_Stats;
464 
465 	/**
466 	 * m_WaterManager: the WaterManager object used for water textures and settings
467 	 * (e.g. water color, water height)
468 	 */
469 	WaterManager* m_WaterManager;
470 
471 	/**
472 	 * m_SkyManager: the SkyManager object used for sky textures and settings
473 	 */
474 	SkyManager* m_SkyManager;
475 
476 	/**
477 	 * Enable rendering of terrain tile priority text overlay, for debugging.
478 	 */
479 	bool m_DisplayTerrainPriorities;
480 
481 public:
482 	/**
483 	 * m_ShadowZBias: Z bias used when rendering shadows into a depth texture.
484 	 * This can be used to control shadowing artifacts.
485 	 *
486 	 * Can be accessed via JS as renderer.shadowZBias
487 	 * ShadowMap uses this for matrix calculation.
488 	 */
489 	float m_ShadowZBias;
490 
491 	/**
492 	 * m_ShadowMapSize: Size of shadow map, or 0 for default. Typically slow but useful
493 	 * for high-quality rendering. Changes don't take effect until the shadow map
494 	 * is regenerated.
495 	 *
496 	 * Can be accessed via JS as renderer.shadowMapSize
497 	 */
498 	int m_ShadowMapSize;
499 
500 	/**
501 	 * m_SkipSubmit: Disable the actual submission of rendering commands to OpenGL.
502 	 * All state setup is still performed as usual.
503 	 *
504 	 * Can be accessed via JS as renderer.skipSubmit
505 	 */
506 	bool m_SkipSubmit;
507 };
508 
509 
510 #endif
511