Changeset View
Changeset View
Standalone View
Standalone View
source/renderer/Renderer.cpp
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
#include "graphics/Texture.h" | #include "graphics/Texture.h" | ||||
#include "graphics/TextureManager.h" | #include "graphics/TextureManager.h" | ||||
#include "renderer/HWLightingModelRenderer.h" | #include "renderer/HWLightingModelRenderer.h" | ||||
#include "renderer/InstancingModelRenderer.h" | #include "renderer/InstancingModelRenderer.h" | ||||
#include "renderer/ModelRenderer.h" | #include "renderer/ModelRenderer.h" | ||||
#include "renderer/OverlayRenderer.h" | #include "renderer/OverlayRenderer.h" | ||||
#include "renderer/ParticleRenderer.h" | #include "renderer/ParticleRenderer.h" | ||||
#include "renderer/PostprocManager.h" | #include "renderer/PostprocManager.h" | ||||
#include "renderer/RenderingOptions.h" | |||||
#include "renderer/RenderModifiers.h" | #include "renderer/RenderModifiers.h" | ||||
#include "renderer/ShadowMap.h" | #include "renderer/ShadowMap.h" | ||||
#include "renderer/SilhouetteRenderer.h" | #include "renderer/SilhouetteRenderer.h" | ||||
#include "renderer/SkyManager.h" | #include "renderer/SkyManager.h" | ||||
#include "renderer/TerrainOverlay.h" | #include "renderer/TerrainOverlay.h" | ||||
#include "renderer/TerrainRenderer.h" | #include "renderer/TerrainRenderer.h" | ||||
#include "renderer/TimeManager.h" | #include "renderer/TimeManager.h" | ||||
#include "renderer/VertexBufferManager.h" | #include "renderer/VertexBufferManager.h" | ||||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
/** | /** | ||||
* Renders all non-alpha-blended models with the given context. | * Renders all non-alpha-blended models with the given context. | ||||
*/ | */ | ||||
void CallModelRenderers(const CShaderDefines& context, int cullGroup, int flags) | void CallModelRenderers(const CShaderDefines& context, int cullGroup, int flags) | ||||
{ | { | ||||
CShaderDefines contextSkinned = context; | CShaderDefines contextSkinned = context; | ||||
if (g_Renderer.m_Options.m_GPUSkinning) | if (g_RenderingOptions.GetGPUSkinning()) | ||||
{ | { | ||||
contextSkinned.Add(str_USE_INSTANCING, str_1); | contextSkinned.Add(str_USE_INSTANCING, str_1); | ||||
contextSkinned.Add(str_USE_GPU_SKINNING, str_1); | contextSkinned.Add(str_USE_GPU_SKINNING, str_1); | ||||
} | } | ||||
Model.NormalSkinned->Render(Model.ModShader, contextSkinned, cullGroup, flags); | Model.NormalSkinned->Render(Model.ModShader, contextSkinned, cullGroup, flags); | ||||
if (Model.NormalUnskinned != Model.NormalSkinned) | if (Model.NormalUnskinned != Model.NormalSkinned) | ||||
{ | { | ||||
CShaderDefines contextUnskinned = context; | CShaderDefines contextUnskinned = context; | ||||
contextUnskinned.Add(str_USE_INSTANCING, str_1); | contextUnskinned.Add(str_USE_INSTANCING, str_1); | ||||
Model.NormalUnskinned->Render(Model.ModShader, contextUnskinned, cullGroup, flags); | Model.NormalUnskinned->Render(Model.ModShader, contextUnskinned, cullGroup, flags); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Renders all alpha-blended models with the given context. | * Renders all alpha-blended models with the given context. | ||||
*/ | */ | ||||
void CallTranspModelRenderers(const CShaderDefines& context, int cullGroup, int flags) | void CallTranspModelRenderers(const CShaderDefines& context, int cullGroup, int flags) | ||||
{ | { | ||||
CShaderDefines contextSkinned = context; | CShaderDefines contextSkinned = context; | ||||
if (g_Renderer.m_Options.m_GPUSkinning) | if (g_RenderingOptions.GetGPUSkinning()) | ||||
{ | { | ||||
contextSkinned.Add(str_USE_INSTANCING, str_1); | contextSkinned.Add(str_USE_INSTANCING, str_1); | ||||
contextSkinned.Add(str_USE_GPU_SKINNING, str_1); | contextSkinned.Add(str_USE_GPU_SKINNING, str_1); | ||||
} | } | ||||
Model.TranspSkinned->Render(Model.ModShader, contextSkinned, cullGroup, flags); | Model.TranspSkinned->Render(Model.ModShader, contextSkinned, cullGroup, flags); | ||||
if (Model.TranspUnskinned != Model.TranspSkinned) | if (Model.TranspUnskinned != Model.TranspSkinned) | ||||
{ | { | ||||
Show All 19 Lines | CRenderer::CRenderer() | ||||
m_TerrainRenderMode = SOLID; | m_TerrainRenderMode = SOLID; | ||||
m_WaterRenderMode = SOLID; | m_WaterRenderMode = SOLID; | ||||
m_ModelRenderMode = SOLID; | m_ModelRenderMode = SOLID; | ||||
m_ClearColor[0] = m_ClearColor[1] = m_ClearColor[2] = m_ClearColor[3] = 0; | m_ClearColor[0] = m_ClearColor[1] = m_ClearColor[2] = m_ClearColor[3] = 0; | ||||
m_DisplayTerrainPriorities = false; | m_DisplayTerrainPriorities = false; | ||||
m_SkipSubmit = false; | m_SkipSubmit = false; | ||||
m_Options.m_NoVBO = false; | |||||
m_Options.m_RenderPath = RP_DEFAULT; | |||||
m_Options.m_Shadows = false; | |||||
m_Options.m_WaterEffects = false; | |||||
m_Options.m_WaterFancyEffects = false; | |||||
m_Options.m_WaterRealDepth = false; | |||||
m_Options.m_WaterRefraction = false; | |||||
m_Options.m_WaterReflection = false; | |||||
m_Options.m_WaterShadows = false; | |||||
m_Options.m_ShadowAlphaFix = true; | |||||
m_Options.m_ARBProgramShadow = true; | |||||
m_Options.m_ShadowPCF = false; | |||||
m_Options.m_Particles = false; | |||||
m_Options.m_Silhouettes = false; | |||||
m_Options.m_PreferGLSL = false; | |||||
m_Options.m_Fog = false; | |||||
m_Options.m_ForceAlphaTest = false; | |||||
m_Options.m_GPUSkinning = false; | |||||
m_Options.m_SmoothLOS = false; | |||||
m_Options.m_Postproc = false; | |||||
m_Options.m_ShowSky = false; | |||||
m_Options.m_DisplayFrustum = false; | |||||
// TODO: be more consistent in use of the config system | |||||
CFG_GET_VAL("preferglsl", m_Options.m_PreferGLSL); | |||||
CFG_GET_VAL("forcealphatest", m_Options.m_ForceAlphaTest); | |||||
CFG_GET_VAL("gpuskinning", m_Options.m_GPUSkinning); | |||||
CFG_GET_VAL("smoothlos", m_Options.m_SmoothLOS); | |||||
CFG_GET_VAL("postproc", m_Options.m_Postproc); | |||||
CStr skystring = "0 0 0"; | CStr skystring = "0 0 0"; | ||||
CColor skycolor; | CColor skycolor; | ||||
CFG_GET_VAL("skycolor", skystring); | CFG_GET_VAL("skycolor", skystring); | ||||
if (skycolor.ParseString(skystring, 255.f)) | if (skycolor.ParseString(skystring, 255.f)) | ||||
SetClearColor(skycolor.AsSColor4ub()); | SetClearColor(skycolor.AsSColor4ub()); | ||||
#if CONFIG2_GLES | #if CONFIG2_GLES | ||||
// Override config option since GLES only supports GLSL | // Override config option since GLES only supports GLSL | ||||
m_Options.m_PreferGLSL = true; | g_RenderingOptions.GetPreferGLSL() = true; | ||||
#endif | #endif | ||||
m_ShadowZBias = 0.02f; | m_ShadowZBias = 0.02f; | ||||
m_ShadowMapSize = 0; | m_ShadowMapSize = 0; | ||||
m_LightEnv = NULL; | m_LightEnv = NULL; | ||||
m_CurrentScene = NULL; | m_CurrentScene = NULL; | ||||
Show All 27 Lines | void CRenderer::EnumCaps() | ||||
m_Caps.m_ARBProgram = false; | m_Caps.m_ARBProgram = false; | ||||
m_Caps.m_ARBProgramShadow = false; | m_Caps.m_ARBProgramShadow = false; | ||||
m_Caps.m_VertexShader = false; | m_Caps.m_VertexShader = false; | ||||
m_Caps.m_FragmentShader = false; | m_Caps.m_FragmentShader = false; | ||||
m_Caps.m_Shadows = false; | m_Caps.m_Shadows = false; | ||||
m_Caps.m_PrettyWater = false; | m_Caps.m_PrettyWater = false; | ||||
// now start querying extensions | // now start querying extensions | ||||
if (!m_Options.m_NoVBO && ogl_HaveExtension("GL_ARB_vertex_buffer_object")) | if (!g_RenderingOptions.GetNoVBO() && ogl_HaveExtension("GL_ARB_vertex_buffer_object")) | ||||
m_Caps.m_VBO = true; | m_Caps.m_VBO = true; | ||||
if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL)) | if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL)) | ||||
{ | { | ||||
m_Caps.m_ARBProgram = true; | m_Caps.m_ARBProgram = true; | ||||
if (ogl_HaveExtension("GL_ARB_fragment_program_shadow")) | if (ogl_HaveExtension("GL_ARB_fragment_program_shadow")) | ||||
m_Caps.m_ARBProgramShadow = true; | m_Caps.m_ARBProgramShadow = true; | ||||
} | } | ||||
Show All 23 Lines | if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_shader", "GL_ARB_fragment_shader", "GL_EXT_framebuffer_object", NULL)) | ||||
m_Caps.m_PrettyWater = true; | m_Caps.m_PrettyWater = true; | ||||
#endif | #endif | ||||
} | } | ||||
void CRenderer::RecomputeSystemShaderDefines() | void CRenderer::RecomputeSystemShaderDefines() | ||||
{ | { | ||||
CShaderDefines defines; | CShaderDefines defines; | ||||
if (GetRenderPath() == RP_SHADER && m_Caps.m_ARBProgram) | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER && m_Caps.m_ARBProgram) | ||||
defines.Add(str_SYS_HAS_ARB, str_1); | defines.Add(str_SYS_HAS_ARB, str_1); | ||||
if (GetRenderPath() == RP_SHADER && m_Caps.m_VertexShader && m_Caps.m_FragmentShader) | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER && m_Caps.m_VertexShader && m_Caps.m_FragmentShader) | ||||
defines.Add(str_SYS_HAS_GLSL, str_1); | defines.Add(str_SYS_HAS_GLSL, str_1); | ||||
if (m_Options.m_PreferGLSL) | if (g_RenderingOptions.GetPreferGLSL()) | ||||
defines.Add(str_SYS_PREFER_GLSL, str_1); | defines.Add(str_SYS_PREFER_GLSL, str_1); | ||||
m_SystemShaderDefines = defines; | m_SystemShaderDefines = defines; | ||||
} | } | ||||
void CRenderer::ReloadShaders() | void CRenderer::ReloadShaders() | ||||
{ | { | ||||
ENSURE(m->IsOpen); | ENSURE(m->IsOpen); | ||||
m->globalContext = m_SystemShaderDefines; | m->globalContext = m_SystemShaderDefines; | ||||
if (m_Caps.m_Shadows && m_Options.m_Shadows) | if (m_Caps.m_Shadows && g_RenderingOptions.GetShadows()) | ||||
{ | { | ||||
m->globalContext.Add(str_USE_SHADOW, str_1); | m->globalContext.Add(str_USE_SHADOW, str_1); | ||||
if (m_Caps.m_ARBProgramShadow && m_Options.m_ARBProgramShadow) | if (m_Caps.m_ARBProgramShadow && g_RenderingOptions.GetARBProgramShadow()) | ||||
m->globalContext.Add(str_USE_FP_SHADOW, str_1); | m->globalContext.Add(str_USE_FP_SHADOW, str_1); | ||||
if (m_Options.m_ShadowPCF) | if (g_RenderingOptions.GetShadowPCF()) | ||||
m->globalContext.Add(str_USE_SHADOW_PCF, str_1); | m->globalContext.Add(str_USE_SHADOW_PCF, str_1); | ||||
#if !CONFIG2_GLES | #if !CONFIG2_GLES | ||||
m->globalContext.Add(str_USE_SHADOW_SAMPLER, str_1); | m->globalContext.Add(str_USE_SHADOW_SAMPLER, str_1); | ||||
#endif | #endif | ||||
} | } | ||||
if (m_LightEnv) | if (m_LightEnv) | ||||
m->globalContext.Add(CStrIntern("LIGHTING_MODEL_" + m_LightEnv->GetLightingModel()), str_1); | m->globalContext.Add(CStrIntern("LIGHTING_MODEL_" + m_LightEnv->GetLightingModel()), str_1); | ||||
if (m_Options.m_PreferGLSL && m_Options.m_Fog) | if (g_RenderingOptions.GetPreferGLSL() && g_RenderingOptions.GetFog()) | ||||
m->globalContext.Add(str_USE_FOG, str_1); | m->globalContext.Add(str_USE_FOG, str_1); | ||||
m->Model.ModShader = LitRenderModifierPtr(new ShaderRenderModifier()); | m->Model.ModShader = LitRenderModifierPtr(new ShaderRenderModifier()); | ||||
bool cpuLighting = (GetRenderPath() == RP_FIXED); | bool cpuLighting = (g_RenderingOptions.GetRenderPath() == RenderPath::FIXED); | ||||
m->Model.VertexRendererShader = ModelVertexRendererPtr(new ShaderModelVertexRenderer(cpuLighting)); | m->Model.VertexRendererShader = ModelVertexRendererPtr(new ShaderModelVertexRenderer(cpuLighting)); | ||||
m->Model.VertexInstancingShader = ModelVertexRendererPtr(new InstancingModelRenderer(false, m_Options.m_PreferGLSL)); | m->Model.VertexInstancingShader = ModelVertexRendererPtr(new InstancingModelRenderer(false, g_RenderingOptions.GetPreferGLSL())); | ||||
if (GetRenderPath() == RP_SHADER && m_Options.m_GPUSkinning) // TODO: should check caps and GLSL etc too | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER && g_RenderingOptions.GetGPUSkinning()) // TODO: should check caps and GLSL etc too | ||||
{ | { | ||||
m->Model.VertexGPUSkinningShader = ModelVertexRendererPtr(new InstancingModelRenderer(true, m_Options.m_PreferGLSL)); | m->Model.VertexGPUSkinningShader = ModelVertexRendererPtr(new InstancingModelRenderer(true, g_RenderingOptions.GetPreferGLSL())); | ||||
m->Model.NormalSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader)); | m->Model.NormalSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader)); | ||||
m->Model.TranspSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader)); | m->Model.TranspSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader)); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
m->Model.VertexGPUSkinningShader.reset(); | m->Model.VertexGPUSkinningShader.reset(); | ||||
m->Model.NormalSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexRendererShader)); | m->Model.NormalSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexRendererShader)); | ||||
m->Model.TranspSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexRendererShader)); | m->Model.TranspSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexRendererShader)); | ||||
} | } | ||||
// Use instancing renderers in shader mode | // Use instancing renderers in shader mode | ||||
if (GetRenderPath() == RP_SHADER) | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
{ | { | ||||
m->Model.NormalUnskinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexInstancingShader)); | m->Model.NormalUnskinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexInstancingShader)); | ||||
m->Model.TranspUnskinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexInstancingShader)); | m->Model.TranspUnskinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexInstancingShader)); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
m->Model.NormalUnskinned = m->Model.NormalSkinned; | m->Model.NormalUnskinned = m->Model.NormalSkinned; | ||||
m->Model.TranspUnskinned = m->Model.TranspSkinned; | m->Model.TranspUnskinned = m->Model.TranspSkinned; | ||||
Show All 29 Lines | bool CRenderer::Open(int width, int height) | ||||
glGetIntegerv(GL_DEPTH_BITS,&bits); | glGetIntegerv(GL_DEPTH_BITS,&bits); | ||||
LOGMESSAGE("CRenderer::Open: depth bits %d",bits); | LOGMESSAGE("CRenderer::Open: depth bits %d",bits); | ||||
glGetIntegerv(GL_STENCIL_BITS,&bits); | glGetIntegerv(GL_STENCIL_BITS,&bits); | ||||
LOGMESSAGE("CRenderer::Open: stencil bits %d",bits); | LOGMESSAGE("CRenderer::Open: stencil bits %d",bits); | ||||
glGetIntegerv(GL_ALPHA_BITS,&bits); | glGetIntegerv(GL_ALPHA_BITS,&bits); | ||||
LOGMESSAGE("CRenderer::Open: alpha bits %d",bits); | LOGMESSAGE("CRenderer::Open: alpha bits %d",bits); | ||||
// Validate the currently selected render path | // Validate the currently selected render path | ||||
SetRenderPath(m_Options.m_RenderPath); | SetRenderPath(g_RenderingOptions.GetRenderPath()); | ||||
RecomputeSystemShaderDefines(); | RecomputeSystemShaderDefines(); | ||||
// Let component renderers perform one-time initialization after graphics capabilities and | // Let component renderers perform one-time initialization after graphics capabilities and | ||||
// the shader path have been determined. | // the shader path have been determined. | ||||
m->overlayRenderer.Initialize(); | m->overlayRenderer.Initialize(); | ||||
if (m_Options.m_Postproc) | if (g_RenderingOptions.GetPostProc()) | ||||
m->postprocManager.Initialize(); | m->postprocManager.Initialize(); | ||||
return true; | return true; | ||||
} | } | ||||
// resize renderer view | // resize renderer view | ||||
void CRenderer::Resize(int width, int height) | void CRenderer::Resize(int width, int height) | ||||
{ | { | ||||
// need to recreate the shadow map object to resize the shadow texture | // need to recreate the shadow map object to resize the shadow texture | ||||
m->shadow.RecreateTexture(); | m->shadow.RecreateTexture(); | ||||
m_Width = width; | m_Width = width; | ||||
m_Height = height; | m_Height = height; | ||||
m->postprocManager.Resize(); | m->postprocManager.Resize(); | ||||
m_WaterManager->Resize(); | m_WaterManager->Resize(); | ||||
} | } | ||||
////////////////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////////////////// | ||||
// SetOptionBool: set boolean renderer option | |||||
void CRenderer::SetOptionBool(enum Option opt,bool value) | |||||
{ | |||||
// Don't do anything if the option didn't change from its previous value. | |||||
if (value == GetOptionBool(opt)) | |||||
return; | |||||
switch (opt) { | |||||
case OPT_NOVBO: | |||||
m_Options.m_NoVBO = value; | |||||
break; | |||||
case OPT_SHADOWS: | |||||
m_Options.m_Shadows = value; | |||||
MakeShadersDirty(); | |||||
break; | |||||
case OPT_WATEREFFECTS: | |||||
m_Options.m_WaterEffects = value; | |||||
break; | |||||
case OPT_WATERFANCYEFFECTS: | |||||
m_Options.m_WaterFancyEffects = value; | |||||
break; | |||||
case OPT_WATERREALDEPTH: | |||||
m_Options.m_WaterRealDepth = value; | |||||
break; | |||||
case OPT_WATERREFLECTION: | |||||
m_Options.m_WaterReflection = value; | |||||
break; | |||||
case OPT_WATERREFRACTION: | |||||
m_Options.m_WaterRefraction = value; | |||||
break; | |||||
case OPT_SHADOWSONWATER: | |||||
m_Options.m_WaterShadows = value; | |||||
break; | |||||
case OPT_SHADOWPCF: | |||||
m_Options.m_ShadowPCF = value; | |||||
MakeShadersDirty(); | |||||
break; | |||||
case OPT_PARTICLES: | |||||
m_Options.m_Particles = value; | |||||
break; | |||||
case OPT_PREFERGLSL: | |||||
m_Options.m_PreferGLSL = value; | |||||
MakeShadersDirty(); | |||||
RecomputeSystemShaderDefines(); | |||||
break; | |||||
case OPT_FOG: | |||||
m_Options.m_Fog = value; | |||||
MakeShadersDirty(); | |||||
break; | |||||
case OPT_SILHOUETTES: | |||||
m_Options.m_Silhouettes = value; | |||||
break; | |||||
case OPT_SHOWSKY: | |||||
m_Options.m_ShowSky = value; | |||||
break; | |||||
case OPT_SMOOTHLOS: | |||||
m_Options.m_SmoothLOS = value; | |||||
break; | |||||
case OPT_POSTPROC: | |||||
m_Options.m_Postproc = value; | |||||
break; | |||||
case OPT_DISPLAYFRUSTUM: | |||||
m_Options.m_DisplayFrustum = value; | |||||
break; | |||||
default: | |||||
debug_warn(L"CRenderer::SetOptionBool: unknown option"); | |||||
break; | |||||
} | |||||
} | |||||
////////////////////////////////////////////////////////////////////////////////////////// | |||||
// GetOptionBool: get boolean renderer option | |||||
bool CRenderer::GetOptionBool(enum Option opt) const | |||||
{ | |||||
switch (opt) { | |||||
case OPT_NOVBO: | |||||
return m_Options.m_NoVBO; | |||||
case OPT_SHADOWS: | |||||
return m_Options.m_Shadows; | |||||
case OPT_WATEREFFECTS: | |||||
return m_Options.m_WaterEffects; | |||||
case OPT_WATERFANCYEFFECTS: | |||||
return m_Options.m_WaterFancyEffects; | |||||
case OPT_WATERREALDEPTH: | |||||
return m_Options.m_WaterRealDepth; | |||||
case OPT_WATERREFLECTION: | |||||
return m_Options.m_WaterReflection; | |||||
case OPT_WATERREFRACTION: | |||||
return m_Options.m_WaterRefraction; | |||||
case OPT_SHADOWSONWATER: | |||||
return m_Options.m_WaterShadows; | |||||
case OPT_SHADOWPCF: | |||||
return m_Options.m_ShadowPCF; | |||||
case OPT_PARTICLES: | |||||
return m_Options.m_Particles; | |||||
case OPT_PREFERGLSL: | |||||
return m_Options.m_PreferGLSL; | |||||
case OPT_FOG: | |||||
return m_Options.m_Fog; | |||||
case OPT_SILHOUETTES: | |||||
return m_Options.m_Silhouettes; | |||||
case OPT_SHOWSKY: | |||||
return m_Options.m_ShowSky; | |||||
case OPT_SMOOTHLOS: | |||||
return m_Options.m_SmoothLOS; | |||||
case OPT_POSTPROC: | |||||
return m_Options.m_Postproc; | |||||
case OPT_DISPLAYFRUSTUM: | |||||
return m_Options.m_DisplayFrustum; | |||||
default: | |||||
debug_warn(L"CRenderer::GetOptionBool: unknown option"); | |||||
break; | |||||
} | |||||
return false; | |||||
} | |||||
////////////////////////////////////////////////////////////////////////////////////////// | |||||
// SetRenderPath: Select the preferred render path. | // SetRenderPath: Select the preferred render path. | ||||
// This may only be called before Open(), because the layout of vertex arrays and other | // This may only be called before Open(), because the layout of vertex arrays and other | ||||
// data may depend on the chosen render path. | // data may depend on the chosen render path. | ||||
void CRenderer::SetRenderPath(RenderPath rp) | void CRenderer::SetRenderPath(RenderPath rp) | ||||
{ | { | ||||
if (!m->IsOpen) | if (!m->IsOpen) | ||||
{ | { | ||||
// Delay until Open() is called. | // Delay until Open() is called. | ||||
m_Options.m_RenderPath = rp; | |||||
return; | return; | ||||
} | } | ||||
// Renderer has been opened, so validate the selected renderpath | // Renderer has been opened, so validate the selected renderpath | ||||
if (rp == RP_DEFAULT) | if (rp == RenderPath::DEFAULT) | ||||
{ | { | ||||
if (m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && m_Options.m_PreferGLSL)) | if (m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_RenderingOptions.GetPreferGLSL())) | ||||
rp = RP_SHADER; | rp = RenderPath::SHADER; | ||||
else | else | ||||
rp = RP_FIXED; | rp = RenderPath::FIXED; | ||||
} | } | ||||
if (rp == RP_SHADER) | if (rp == RenderPath::SHADER) | ||||
{ | { | ||||
if (!(m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && m_Options.m_PreferGLSL))) | if (!(m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_RenderingOptions.GetPreferGLSL()))) | ||||
{ | { | ||||
LOGWARNING("Falling back to fixed function\n"); | LOGWARNING("Falling back to fixed function\n"); | ||||
rp = RP_FIXED; | rp = RenderPath::FIXED; | ||||
} | } | ||||
} | } | ||||
m_Options.m_RenderPath = rp; | // TODO: remove this once capabilities have been properly extracted and the above checks have been moved elsewhere. | ||||
g_RenderingOptions.m_RenderPath = rp; | |||||
MakeShadersDirty(); | MakeShadersDirty(); | ||||
RecomputeSystemShaderDefines(); | RecomputeSystemShaderDefines(); | ||||
// We might need to regenerate some render data after changing path | // We might need to regenerate some render data after changing path | ||||
if (g_Game) | if (g_Game) | ||||
g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_COLOR); | g_Game->GetWorld()->GetTerrain()->MakeDirty(RENDERDATA_UPDATE_COLOR); | ||||
} | } | ||||
CStr CRenderer::GetRenderPathName(RenderPath rp) | |||||
{ | |||||
switch(rp) { | |||||
case RP_DEFAULT: return "default"; | |||||
case RP_FIXED: return "fixed"; | |||||
case RP_SHADER: return "shader"; | |||||
default: return "(invalid)"; | |||||
} | |||||
} | |||||
CRenderer::RenderPath CRenderer::GetRenderPathByName(const CStr& name) | |||||
{ | |||||
if (name == "fixed") | |||||
return RP_FIXED; | |||||
if (name == "shader") | |||||
return RP_SHADER; | |||||
if (name == "default") | |||||
return RP_DEFAULT; | |||||
LOGWARNING("Unknown render path name '%s', assuming 'default'", name.c_str()); | |||||
return RP_DEFAULT; | |||||
} | |||||
////////////////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////////////////// | ||||
// BeginFrame: signal frame start | // BeginFrame: signal frame start | ||||
void CRenderer::BeginFrame() | void CRenderer::BeginFrame() | ||||
{ | { | ||||
PROFILE("begin frame"); | PROFILE("begin frame"); | ||||
// zero out all the per-frame stats | // zero out all the per-frame stats | ||||
m_Stats.Reset(); | m_Stats.Reset(); | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | #else | ||||
// switch on wireframe if we need it | // switch on wireframe if we need it | ||||
if (m_TerrainRenderMode == WIREFRAME) | if (m_TerrainRenderMode == WIREFRAME) | ||||
{ | { | ||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
} | } | ||||
#endif | #endif | ||||
// render all the patches, including blend pass | // render all the patches, including blend pass | ||||
if (GetRenderPath() == RP_SHADER) | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
m->terrainRenderer.RenderTerrainShader(context, cullGroup, (m_Caps.m_Shadows && m_Options.m_Shadows) ? &m->shadow : 0); | m->terrainRenderer.RenderTerrainShader(context, cullGroup, (m_Caps.m_Shadows && g_RenderingOptions.GetShadows()) ? &m->shadow : 0); | ||||
else | else | ||||
m->terrainRenderer.RenderTerrain(cullGroup); | m->terrainRenderer.RenderTerrain(cullGroup); | ||||
#if !CONFIG2_GLES | #if !CONFIG2_GLES | ||||
if (m_TerrainRenderMode == WIREFRAME) | if (m_TerrainRenderMode == WIREFRAME) | ||||
{ | { | ||||
// switch wireframe off again | // switch wireframe off again | ||||
▲ Show 20 Lines • Show All 265 Lines • ▼ Show 20 Lines | void CRenderer::RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor) | ||||
// try binding the framebuffer | // try binding the framebuffer | ||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_ReflectionFbo); | pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wm.m_ReflectionFbo); | ||||
glClearColor(0.5f,0.5f,1.0f,0.0f); | glClearColor(0.5f,0.5f,1.0f,0.0f); | ||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
glFrontFace(GL_CW); | glFrontFace(GL_CW); | ||||
if (!m_Options.m_WaterReflection) | if (!g_RenderingOptions.GetWaterReflection()) | ||||
{ | { | ||||
m->skyManager.RenderSky(); | m->skyManager.RenderSky(); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
// Render terrain and models | // Render terrain and models | ||||
RenderPatches(context, CULL_REFLECTIONS); | RenderPatches(context, CULL_REFLECTIONS); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
RenderModels(context, CULL_REFLECTIONS); | RenderModels(context, CULL_REFLECTIONS); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
RenderTransparentModels(context, CULL_REFLECTIONS, TRANSPARENT, true); | RenderTransparentModels(context, CULL_REFLECTIONS, TRANSPARENT, true); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
glFrontFace(GL_CCW); | glFrontFace(GL_CCW); | ||||
// Particles are always oriented to face the camera in the vertex shader, | // Particles are always oriented to face the camera in the vertex shader, | ||||
// so they don't need the inverted glFrontFace | // so they don't need the inverted glFrontFace | ||||
if (m_Options.m_Particles) | if (g_RenderingOptions.GetParticles()) | ||||
{ | { | ||||
RenderParticles(CULL_REFLECTIONS); | RenderParticles(CULL_REFLECTIONS); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
// Reset old camera | // Reset old camera | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | else | ||||
pglBlendColorEXT(0, 0, 0, 0); | pglBlendColorEXT(0, 0, 0, 0); | ||||
glDisable(GL_STENCIL_TEST); | glDisable(GL_STENCIL_TEST); | ||||
} | } | ||||
} | } | ||||
void CRenderer::RenderParticles(int cullGroup) | void CRenderer::RenderParticles(int cullGroup) | ||||
{ | { | ||||
// Only supported in shader modes | // Only supported in shader modes | ||||
if (GetRenderPath() != RP_SHADER) | if (g_RenderingOptions.GetRenderPath() != RenderPath::SHADER) | ||||
return; | return; | ||||
PROFILE3_GPU("particles"); | PROFILE3_GPU("particles"); | ||||
m->particleRenderer.RenderParticles(cullGroup); | m->particleRenderer.RenderParticles(cullGroup); | ||||
#if !CONFIG2_GLES | #if !CONFIG2_GLES | ||||
if (m_ModelRenderMode == EDGED_FACES) | if (m_ModelRenderMode == EDGED_FACES) | ||||
Show All 23 Lines | |||||
/////////////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
// RenderSubmissions: force rendering of any batched objects | // RenderSubmissions: force rendering of any batched objects | ||||
void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor) | void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor) | ||||
{ | { | ||||
PROFILE3("render submissions"); | PROFILE3("render submissions"); | ||||
GetScene().GetLOSTexture().InterpolateLOS(); | GetScene().GetLOSTexture().InterpolateLOS(); | ||||
if (m_Options.m_Postproc) | if (g_RenderingOptions.GetPostProc()) | ||||
{ | { | ||||
m->postprocManager.Initialize(); | m->postprocManager.Initialize(); | ||||
m->postprocManager.CaptureRenderOutput(); | m->postprocManager.CaptureRenderOutput(); | ||||
} | } | ||||
CShaderDefines context = m->globalContext; | CShaderDefines context = m->globalContext; | ||||
int cullGroup = CULL_DEFAULT; | int cullGroup = CULL_DEFAULT; | ||||
Show All 15 Lines | void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor) | ||||
} | } | ||||
m->terrainRenderer.PrepareForRendering(); | m->terrainRenderer.PrepareForRendering(); | ||||
m->overlayRenderer.PrepareForRendering(); | m->overlayRenderer.PrepareForRendering(); | ||||
m->particleRenderer.PrepareForRendering(context); | m->particleRenderer.PrepareForRendering(context); | ||||
if (m_Caps.m_Shadows && m_Options.m_Shadows && GetRenderPath() == RP_SHADER) | if (m_Caps.m_Shadows && g_RenderingOptions.GetShadows() && g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
{ | { | ||||
RenderShadowMap(context); | RenderShadowMap(context); | ||||
} | } | ||||
{ | { | ||||
PROFILE3_GPU("clear buffers"); | PROFILE3_GPU("clear buffers"); | ||||
glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]); | glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]); | ||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||||
} | } | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
if (m_WaterManager->m_RenderWater) | if (m_WaterManager->m_RenderWater) | ||||
{ | { | ||||
if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater()) | if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater()) | ||||
{ | { | ||||
PROFILE3_GPU("water scissor"); | PROFILE3_GPU("water scissor"); | ||||
RenderReflections(context, waterScissor); | RenderReflections(context, waterScissor); | ||||
if (m_Options.m_WaterRefraction) | if (g_RenderingOptions.GetWaterRefraction()) | ||||
RenderRefractions(context, waterScissor); | RenderRefractions(context, waterScissor); | ||||
} | } | ||||
} | } | ||||
if (m_Options.m_ShowSky) | if (g_RenderingOptions.GetShowSky()) | ||||
{ | { | ||||
m->skyManager.RenderSky(); | m->skyManager.RenderSky(); | ||||
} | } | ||||
// render submitted patches and models | // render submitted patches and models | ||||
RenderPatches(context, cullGroup); | RenderPatches(context, cullGroup); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
Show All 33 Lines | void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor) | ||||
ITerrainOverlay::RenderOverlaysAfterWater(cullGroup); | ITerrainOverlay::RenderOverlaysAfterWater(cullGroup); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
// render some other overlays after water (so they can be displayed on top of water) | // render some other overlays after water (so they can be displayed on top of water) | ||||
m->overlayRenderer.RenderOverlaysAfterWater(); | m->overlayRenderer.RenderOverlaysAfterWater(); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
// particles are transparent so render after water | // particles are transparent so render after water | ||||
if (m_Options.m_Particles) | if (g_RenderingOptions.GetParticles()) | ||||
{ | { | ||||
RenderParticles(cullGroup); | RenderParticles(cullGroup); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
if (m_Options.m_Postproc) | if (g_RenderingOptions.GetPostProc()) | ||||
{ | { | ||||
m->postprocManager.ApplyPostproc(); | m->postprocManager.ApplyPostproc(); | ||||
m->postprocManager.ReleaseRenderOutput(); | m->postprocManager.ReleaseRenderOutput(); | ||||
} | } | ||||
if (m_Options.m_Silhouettes) | if (g_RenderingOptions.GetSilhouettes()) | ||||
{ | { | ||||
RenderSilhouettes(context); | RenderSilhouettes(context); | ||||
} | } | ||||
#if !CONFIG2_GLES | #if !CONFIG2_GLES | ||||
// Clean up texture blend mode so particles and other things render OK | // Clean up texture blend mode so particles and other things render OK | ||||
// (really this should be cleaned up by whoever set it) | // (really this should be cleaned up by whoever set it) | ||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||||
#endif | #endif | ||||
// render debug lines | // render debug lines | ||||
if (m_Options.m_DisplayFrustum) | if (g_RenderingOptions.GetDisplayFrustum()) | ||||
{ | { | ||||
DisplayFrustum(); | DisplayFrustum(); | ||||
m->shadow.RenderDebugBounds(); | m->shadow.RenderDebugBounds(); | ||||
m->shadow.RenderDebugTexture(); | m->shadow.RenderDebugTexture(); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
m->silhouetteRenderer.RenderDebugOverlays(m_ViewCamera); | m->silhouetteRenderer.RenderDebugOverlays(m_ViewCamera); | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
// SetSceneCamera: setup projection and transform of camera and adjust viewport to current view | // SetSceneCamera: setup projection and transform of camera and adjust viewport to current view | ||||
// The camera always represents the actual camera used to render a scene, not any virtual camera | // The camera always represents the actual camera used to render a scene, not any virtual camera | ||||
// used for shadow rendering or reflections. | // used for shadow rendering or reflections. | ||||
void CRenderer::SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera) | void CRenderer::SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera) | ||||
{ | { | ||||
m_ViewCamera = viewCamera; | m_ViewCamera = viewCamera; | ||||
m_CullCamera = cullCamera; | m_CullCamera = cullCamera; | ||||
if (m_Caps.m_Shadows && m_Options.m_Shadows && GetRenderPath() == RP_SHADER) | if (m_Caps.m_Shadows && g_RenderingOptions.GetShadows() && g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
m->shadow.SetupFrame(m_CullCamera, m_LightEnv->GetSunDir()); | m->shadow.SetupFrame(m_CullCamera, m_LightEnv->GetSunDir()); | ||||
} | } | ||||
void CRenderer::SetViewport(const SViewPort &vp) | void CRenderer::SetViewport(const SViewPort &vp) | ||||
{ | { | ||||
m_Viewport = vp; | m_Viewport = vp; | ||||
glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height); | glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height); | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | void CRenderer::RenderScene(Scene& scene) | ||||
CFrustum frustum = m_CullCamera.GetFrustum(); | CFrustum frustum = m_CullCamera.GetFrustum(); | ||||
m_CurrentCullGroup = CULL_DEFAULT; | m_CurrentCullGroup = CULL_DEFAULT; | ||||
scene.EnumerateObjects(frustum, this); | scene.EnumerateObjects(frustum, this); | ||||
m->particleManager.RenderSubmit(*this, frustum); | m->particleManager.RenderSubmit(*this, frustum); | ||||
if (m_Options.m_Silhouettes) | if (g_RenderingOptions.GetSilhouettes()) | ||||
{ | { | ||||
m->silhouetteRenderer.ComputeSubmissions(m_ViewCamera); | m->silhouetteRenderer.ComputeSubmissions(m_ViewCamera); | ||||
m_CurrentCullGroup = CULL_DEFAULT; | m_CurrentCullGroup = CULL_DEFAULT; | ||||
m->silhouetteRenderer.RenderSubmitOverlays(*this); | m->silhouetteRenderer.RenderSubmitOverlays(*this); | ||||
m_CurrentCullGroup = CULL_SILHOUETTE_OCCLUDER; | m_CurrentCullGroup = CULL_SILHOUETTE_OCCLUDER; | ||||
m->silhouetteRenderer.RenderSubmitOccluders(*this); | m->silhouetteRenderer.RenderSubmitOccluders(*this); | ||||
m_CurrentCullGroup = CULL_SILHOUETTE_CASTER; | m_CurrentCullGroup = CULL_SILHOUETTE_CASTER; | ||||
m->silhouetteRenderer.RenderSubmitCasters(*this); | m->silhouetteRenderer.RenderSubmitCasters(*this); | ||||
} | } | ||||
if (m_Caps.m_Shadows && m_Options.m_Shadows && GetRenderPath() == RP_SHADER) | if (m_Caps.m_Shadows && g_RenderingOptions.GetShadows() && g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
{ | { | ||||
m_CurrentCullGroup = CULL_SHADOWS; | m_CurrentCullGroup = CULL_SHADOWS; | ||||
CFrustum shadowFrustum = m->shadow.GetShadowCasterCullFrustum(); | CFrustum shadowFrustum = m->shadow.GetShadowCasterCullFrustum(); | ||||
scene.EnumerateObjects(shadowFrustum, this); | scene.EnumerateObjects(shadowFrustum, this); | ||||
} | } | ||||
CBoundingBoxAligned waterScissor; | CBoundingBoxAligned waterScissor; | ||||
if (m_WaterManager->m_RenderWater) | if (m_WaterManager->m_RenderWater) | ||||
{ | { | ||||
waterScissor = m->terrainRenderer.ScissorWater(CULL_DEFAULT, m_ViewCamera.GetViewProjection()); | waterScissor = m->terrainRenderer.ScissorWater(CULL_DEFAULT, m_ViewCamera.GetViewProjection()); | ||||
if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater()) | if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater()) | ||||
{ | { | ||||
if (m_Options.m_WaterReflection) | if (g_RenderingOptions.GetWaterReflection()) | ||||
{ | { | ||||
m_CurrentCullGroup = CULL_REFLECTIONS; | m_CurrentCullGroup = CULL_REFLECTIONS; | ||||
CCamera reflectionCamera; | CCamera reflectionCamera; | ||||
ComputeReflectionCamera(reflectionCamera, waterScissor); | ComputeReflectionCamera(reflectionCamera, waterScissor); | ||||
scene.EnumerateObjects(reflectionCamera.GetFrustum(), this); | scene.EnumerateObjects(reflectionCamera.GetFrustum(), this); | ||||
} | } | ||||
if (m_Options.m_WaterRefraction) | if (g_RenderingOptions.GetWaterRefraction()) | ||||
{ | { | ||||
m_CurrentCullGroup = CULL_REFRACTIONS; | m_CurrentCullGroup = CULL_REFRACTIONS; | ||||
CCamera refractionCamera; | CCamera refractionCamera; | ||||
ComputeRefractionCamera(refractionCamera, waterScissor); | ComputeRefractionCamera(refractionCamera, waterScissor); | ||||
scene.EnumerateObjects(refractionCamera.GetFrustum(), this); | scene.EnumerateObjects(refractionCamera.GetFrustum(), this); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator