/* Copyright (C) 2014 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 ScriptInterface;
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_WATERUGLY,
OPT_WATERFANCYEFFECTS,
OPT_WATERREALDEPTH,
OPT_WATERREFLECTION,
OPT_WATERREFRACTION,
OPT_SHADOWSONWATER,
OPT_SHADOWPCF,
OPT_PARTICLES,
OPT_GENTANGENTS,
OPT_PREFERGLSL,
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_WaterUgly;
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_Silhouettes;
bool m_GenTangents;
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 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; }
static void RegisterScriptFunctions(ScriptInterface& scriptInterface);
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 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