Adding policies for each way to rendering meshes (depending on available OpenGL extensions)
This commit is contained in:
@@ -622,6 +622,7 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const
|
||||
m_shadow_cmd_buffer.drawIndirect<GrassMat,irr::core::vector3df>(windDir, cascade);
|
||||
m_shadow_cmd_buffer.drawIndirect<NormalMat>(cascade);
|
||||
m_shadow_cmd_buffer.drawIndirect<SplattingMat>(cascade);
|
||||
m_shadow_cmd_buffer.drawIndirect<SphereMap>(cascade);
|
||||
}
|
||||
|
||||
void DrawCalls::multidrawShadows(unsigned cascade) const
|
||||
@@ -632,7 +633,9 @@ void DrawCalls::multidrawShadows(unsigned cascade) const
|
||||
m_shadow_cmd_buffer.multidrawShadow<NormalMat>(cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<AlphaRef>(cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<UnlitMat>(cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<GrassMat,irr::core::vector3df>(windDir, cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<GrassMat,irr::core::vector3df>(windDir, cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<SplattingMat>(cascade);
|
||||
m_shadow_cmd_buffer.multidrawShadow<SphereMap>(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -34,7 +34,6 @@ class DrawCalls
|
||||
public:
|
||||
|
||||
|
||||
|
||||
GLsync m_sync = 0; //TODO: make it private. Should it be in shader_based_renderer?
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stk_scene_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/tuple.hpp"
|
||||
#include <SColor.h>
|
||||
#include <S3DVertex.h>
|
||||
@@ -165,45 +164,6 @@ void renderMeshes1stPass(const DrawCalls& draw_calls)
|
||||
}
|
||||
} // renderMeshes1stPass
|
||||
|
||||
|
||||
GeometryPasses::GeometryPasses()
|
||||
{
|
||||
m_displace_tex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderSolidFirstPass(const DrawCalls& draw_calls)
|
||||
{
|
||||
m_wind_dir = getWindDir(); //TODO: why this function instead of Wind::getWind()?
|
||||
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS1));
|
||||
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
|
||||
//TODO: is it useful if AZDO enabled?
|
||||
renderMeshes1stPass<DefaultMaterial, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<SplattingMat, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<UnlitMat, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<AlphaRef, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<GrassMat, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<NormalMat, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<SphereMap, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<DetailMat, 2, 1>(draw_calls);
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
draw_calls.multidrawSolidFirstPass();
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
draw_calls.drawIndirectSolidFirstPass();
|
||||
}
|
||||
}
|
||||
} // renderSolidFirstPass
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int...List>
|
||||
void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
||||
@@ -243,7 +203,205 @@ void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
||||
} // renderMeshes2ndPass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls,
|
||||
template<typename T, int...List>
|
||||
void renderShadow(unsigned cascade)
|
||||
{
|
||||
auto &t = T::List::getInstance()->Shadows[cascade];
|
||||
T::ShadowPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < t.size(); i++)
|
||||
{
|
||||
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh->vao);
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::ShadowPassShader>::template expand(mesh->TextureHandles, T::ShadowTextures);
|
||||
else
|
||||
TexExpander<typename T::ShadowPassShader>::template expandTex(*mesh, T::ShadowTextures);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::ShadowPassShader>(t.at(i), cascade);
|
||||
} // for i
|
||||
} // renderShadow
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int... Selector>
|
||||
void drawRSM(const core::matrix4 & rsm_matrix)
|
||||
{
|
||||
T::RSMShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
auto t = T::List::getInstance()->RSM;
|
||||
for (unsigned i = 0; i < t.size(); i++)
|
||||
{
|
||||
std::vector<GLuint> Textures;
|
||||
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh->vao);
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::RSMShader>::template expand(mesh->TextureHandles, T::RSMTextures);
|
||||
else
|
||||
TexExpander<typename T::RSMShader>::template expandTex(*mesh, T::RSMTextures);
|
||||
CustomUnrollArgs<Selector...>::template drawMesh<typename T::RSMShader>(t.at(i), rsm_matrix);
|
||||
}
|
||||
} // drawRSM
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GL3DrawPolicy::drawShadows(const DrawCalls& draw_calls, unsigned cascade) const
|
||||
{
|
||||
renderShadow<DefaultMaterial, 1>(cascade);
|
||||
renderShadow<SphereMap, 1>(cascade);
|
||||
renderShadow<DetailMat, 1>(cascade);
|
||||
renderShadow<SplattingMat, 1>(cascade);
|
||||
renderShadow<NormalMat, 1>(cascade);
|
||||
renderShadow<AlphaRef, 1>(cascade);
|
||||
renderShadow<UnlitMat, 1>(cascade);
|
||||
renderShadow<GrassMat, 3, 1>(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GL3DrawPolicy::drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const
|
||||
{
|
||||
drawRSM<DefaultMaterial, 3, 1>(rsm_matrix);
|
||||
drawRSM<AlphaRef, 3, 1>(rsm_matrix);
|
||||
drawRSM<NormalMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<UnlitMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<DetailMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<SplattingMat, 1>(rsm_matrix);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IndirectDrawPolicy::drawNormals(const DrawCalls& draw_calls) const
|
||||
{
|
||||
draw_calls.drawIndirectNormals();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IndirectDrawPolicy::drawShadows(const DrawCalls& draw_calls, unsigned cascade) const
|
||||
{
|
||||
draw_calls.drawIndirectShadows(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IndirectDrawPolicy::drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const
|
||||
{
|
||||
drawRSM<SplattingMat, 1>(rsm_matrix); //TODO: add instanced splatting RSM shader
|
||||
draw_calls.drawIndirectReflectiveShadowMaps(rsm_matrix);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MultidrawPolicy::drawNormals(const DrawCalls& draw_calls) const
|
||||
{
|
||||
draw_calls.multidrawNormals();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MultidrawPolicy::drawShadows(const DrawCalls& draw_calls, unsigned cascade) const
|
||||
{
|
||||
draw_calls.multidrawShadows(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MultidrawPolicy::drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const
|
||||
{
|
||||
drawRSM<SplattingMat, 1>(rsm_matrix); //TODO: add instanced splatting RSM shader
|
||||
draw_calls.multidrawReflectiveShadowMaps(rsm_matrix);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AbstractGeometryPasses::prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const
|
||||
{
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
shadow_framebuffer.bind();
|
||||
if (!CVS->isESMEnabled())
|
||||
{
|
||||
glDrawBuffer(GL_NONE);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.5, 50.);
|
||||
}
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0., 0., 0., 0.);
|
||||
}
|
||||
|
||||
void AbstractGeometryPasses::shadowPostProcessing(const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer) const
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOW_POSTPROCESS));
|
||||
|
||||
if (CVS->isARBTextureViewUsable())
|
||||
{
|
||||
const std::pair<float, float>* shadow_scales
|
||||
= shadow_matrices.getShadowScales();
|
||||
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
{
|
||||
irr_driver->getPostProcessing()->renderGaussian6BlurLayer(
|
||||
shadow_framebuffer, i,
|
||||
2.f * shadow_scales[0].first / shadow_scales[i].first,
|
||||
2.f * shadow_scales[0].second / shadow_scales[i].second);
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadow_framebuffer.getRTT()[0]);
|
||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
AbstractGeometryPasses::AbstractGeometryPasses()
|
||||
{
|
||||
m_displace_tex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AbstractGeometryPasses::renderSolidFirstPass(const DrawCalls& draw_calls)
|
||||
{
|
||||
m_wind_dir = getWindDir(); //TODO: why this function instead of Wind::getWind()?
|
||||
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS1));
|
||||
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
|
||||
//TODO: is it useful if AZDO enabled?
|
||||
renderMeshes1stPass<DefaultMaterial, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<SplattingMat, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<UnlitMat, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<AlphaRef, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<GrassMat, 3, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<NormalMat, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<SphereMap, 2, 1>(draw_calls);
|
||||
renderMeshes1stPass<DetailMat, 2, 1>(draw_calls);
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
draw_calls.multidrawSolidFirstPass();
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
draw_calls.drawIndirectSolidFirstPass();
|
||||
}
|
||||
}
|
||||
} // renderSolidFirstPass
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AbstractGeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls,
|
||||
unsigned render_target_diffuse,
|
||||
unsigned render_target_specular,
|
||||
unsigned render_target_half_red)
|
||||
@@ -321,24 +479,9 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls,
|
||||
}
|
||||
} // renderSolidSecondPass
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderNormalsVisualisation(const DrawCalls& draw_calls)
|
||||
{
|
||||
if (CVS->isAZDOEnabled()) {
|
||||
draw_calls.multidrawNormals();
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
draw_calls.drawIndirectNormals();
|
||||
}
|
||||
} // renderNormalsVisualisation
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void GeometryPasses::renderGlow(const DrawCalls& draw_calls, const std::vector<GlowData>& glows)
|
||||
void AbstractGeometryPasses::renderGlow(const DrawCalls& draw_calls, const std::vector<GlowData>& glows)
|
||||
{
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(scene::ESNRP_SOLID);
|
||||
irr_driver->getRTT()->getFBO(FBO_TMP1_WITH_DS).bind();
|
||||
@@ -437,7 +580,7 @@ void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits,
|
||||
} // renderTransparenPass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsigned render_target)
|
||||
void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsigned render_target)
|
||||
{
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@@ -572,145 +715,5 @@ void GeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsigned ren
|
||||
|
||||
} // renderTransparent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int...List>
|
||||
void renderShadow(unsigned cascade)
|
||||
{
|
||||
auto &t = T::List::getInstance()->Shadows[cascade];
|
||||
T::ShadowPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < t.size(); i++)
|
||||
{
|
||||
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh->vao);
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::ShadowPassShader>::template expand(mesh->TextureHandles, T::ShadowTextures);
|
||||
else
|
||||
TexExpander<typename T::ShadowPassShader>::template expandTex(*mesh, T::ShadowTextures);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::ShadowPassShader>(t.at(i), cascade);
|
||||
} // for i
|
||||
} // renderShadow
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderShadows(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer)
|
||||
{
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
shadow_framebuffer.bind();
|
||||
if (!CVS->isESMEnabled())
|
||||
{
|
||||
glDrawBuffer(GL_NONE);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.5, 50.);
|
||||
}
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0., 0., 0., 0.);
|
||||
|
||||
for (unsigned cascade = 0; cascade < 4; cascade++)
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOWS_CASCADE0 + cascade));
|
||||
|
||||
//TODO: useless if indirect instancing rendering or AZDO
|
||||
renderShadow<DefaultMaterial, 1>(cascade);
|
||||
renderShadow<SphereMap, 1>(cascade);
|
||||
renderShadow<DetailMat, 1>(cascade);
|
||||
//renderShadow<SplattingMat, 1>(cascade);
|
||||
renderShadow<NormalMat, 1>(cascade);
|
||||
renderShadow<AlphaRef, 1>(cascade);
|
||||
renderShadow<UnlitMat, 1>(cascade);
|
||||
renderShadow<GrassMat, 3, 1>(cascade);
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
draw_calls.multidrawShadows(cascade);
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
draw_calls.drawIndirectShadows(cascade);
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (CVS->isESMEnabled())
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOW_POSTPROCESS));
|
||||
|
||||
if (CVS->isARBTextureViewUsable())
|
||||
{
|
||||
const std::pair<float, float>* shadow_scales
|
||||
= shadow_matrices.getShadowScales();
|
||||
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
{
|
||||
irr_driver->getPostProcessing()->renderGaussian6BlurLayer(
|
||||
shadow_framebuffer, i,
|
||||
2.f * shadow_scales[0].first / shadow_scales[i].first,
|
||||
2.f * shadow_scales[0].second / shadow_scales[i].second);
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadow_framebuffer.getRTT()[0]);
|
||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||
}
|
||||
} // renderShadows
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int... Selector>
|
||||
void drawRSM(const core::matrix4 & rsm_matrix)
|
||||
{
|
||||
T::RSMShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
auto t = T::List::getInstance()->RSM;
|
||||
for (unsigned i = 0; i < t.size(); i++)
|
||||
{
|
||||
std::vector<GLuint> Textures;
|
||||
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh->vao);
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::RSMShader>::template expand(mesh->TextureHandles, T::RSMTextures);
|
||||
else
|
||||
TexExpander<typename T::RSMShader>::template expandTex(*mesh, T::RSMTextures);
|
||||
CustomUnrollArgs<Selector...>::template drawMesh<typename T::RSMShader>(t.at(i), rsm_matrix);
|
||||
}
|
||||
} // drawRSM
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GeometryPasses::renderReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& reflective_shadow_map_framebuffer)
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_RSM));
|
||||
reflective_shadow_map_framebuffer.bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
const core::matrix4 &rsm_matrix = shadow_matrices.getRSMMatrix();
|
||||
drawRSM<DefaultMaterial, 3, 1>(rsm_matrix);
|
||||
drawRSM<AlphaRef, 3, 1>(rsm_matrix);
|
||||
drawRSM<NormalMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<UnlitMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<DetailMat, 3, 1>(rsm_matrix);
|
||||
drawRSM<SplattingMat, 1>(rsm_matrix);
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
draw_calls.multidrawReflectiveShadowMaps(rsm_matrix);
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
draw_calls.drawIndirectReflectiveShadowMaps(rsm_matrix);
|
||||
}
|
||||
} // renderRSM
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// SuperTuxéKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@@ -11,7 +11,7 @@
|
||||
// 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
|
||||
// You should have received a copy éof the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
@@ -21,38 +21,133 @@
|
||||
#include "graphics/draw_calls.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/shadow_matrices.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include <ITexture.h>
|
||||
|
||||
class GeometryPasses
|
||||
|
||||
/** Rendering methods in this class only require
|
||||
* OpenGL3.2 functions */
|
||||
class GL3DrawPolicy
|
||||
{
|
||||
private:
|
||||
public:
|
||||
|
||||
void drawNormals(const DrawCalls& draw_calls) const {}
|
||||
|
||||
void drawShadows(const DrawCalls& draw_calls, unsigned cascade) const;
|
||||
void drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const;
|
||||
};
|
||||
|
||||
/** Faster than GL3GeometryPasses.
|
||||
* Require at least OpenGL 4.0
|
||||
* or GL_ARB_base_instance and GL_ARB_draw_indirect extensions)*/
|
||||
class IndirectDrawPolicy
|
||||
{
|
||||
public:
|
||||
|
||||
void drawNormals(const DrawCalls& draw_calls) const;
|
||||
|
||||
void drawShadows(const DrawCalls& draw_calls, unsigned cascade) const;
|
||||
void drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const;
|
||||
};
|
||||
|
||||
/** Faster than IndirectGeometryPasses.
|
||||
* Require OpenGL AZDO extensions */
|
||||
class MultidrawPolicy
|
||||
{
|
||||
public:
|
||||
|
||||
void drawNormals(const DrawCalls& draw_calls) const;
|
||||
|
||||
void drawShadows(const DrawCalls& draw_calls, unsigned cascade) const;
|
||||
void drawReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const core::matrix4 &rsm_matrix) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class AbstractGeometryPasses
|
||||
{
|
||||
protected:
|
||||
|
||||
irr::core::vector3df m_wind_dir;
|
||||
irr::video::ITexture *m_displace_tex;
|
||||
|
||||
void prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const;
|
||||
void shadowPostProcessing(const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer) const;
|
||||
|
||||
public:
|
||||
GeometryPasses();
|
||||
AbstractGeometryPasses();
|
||||
virtual ~AbstractGeometryPasses(){}
|
||||
|
||||
void renderSolidFirstPass(const DrawCalls& draw_calls);
|
||||
void renderSolidSecondPass( const DrawCalls& draw_calls,
|
||||
unsigned render_target_diffuse,
|
||||
unsigned render_target_specular,
|
||||
unsigned render_target_half_red);
|
||||
void renderNormalsVisualisation(const DrawCalls& draw_calls);
|
||||
|
||||
virtual void renderNormalsVisualisation(const DrawCalls& draw_calls) const = 0;
|
||||
|
||||
void renderGlow(const DrawCalls& draw_calls, std::vector<GlowData>& glows);
|
||||
void renderGlow(const DrawCalls& draw_calls, const std::vector<GlowData>& glows);
|
||||
|
||||
void renderTransparent(const DrawCalls& draw_calls,
|
||||
unsigned render_target);
|
||||
void renderShadows(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer);
|
||||
void renderReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& reflective_shadow_map_framebuffer);
|
||||
|
||||
virtual void renderShadows(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer) const = 0;
|
||||
|
||||
|
||||
virtual void renderReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& reflective_shadow_map_framebuffer) const = 0 ;
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename DrawPolicy>
|
||||
class GeometryPasses: public AbstractGeometryPasses, public DrawPolicy
|
||||
{
|
||||
public:
|
||||
|
||||
void renderNormalsVisualisation(const DrawCalls& draw_calls) const
|
||||
{
|
||||
DrawPolicy::drawNormals(draw_calls);
|
||||
}
|
||||
|
||||
|
||||
void renderShadows(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer) const
|
||||
{
|
||||
prepareShadowRendering(shadow_framebuffer);
|
||||
|
||||
for (unsigned cascade = 0; cascade < 4; cascade++)
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOWS_CASCADE0 + cascade));
|
||||
DrawPolicy::drawShadows(draw_calls, cascade);
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (CVS->isESMEnabled())
|
||||
shadowPostProcessing(shadow_matrices, shadow_framebuffer);
|
||||
}
|
||||
|
||||
|
||||
void renderReflectiveShadowMap(const DrawCalls& draw_calls,
|
||||
const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& reflective_shadow_map_framebuffer) const
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_RSM));
|
||||
reflective_shadow_map_framebuffer.bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
DrawPolicy::drawReflectiveShadowMap(draw_calls, shadow_matrices.getRSMMatrix());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //HEADER_GEOMETRY_PASSES_HPP
|
||||
|
||||
@@ -23,34 +23,6 @@
|
||||
#include "graphics/stk_mesh.hpp"
|
||||
#include "graphics/vao_manager.hpp"
|
||||
|
||||
/*class InstancedObjectPass1Shader;
|
||||
class InstancedObjectPass2Shader;
|
||||
class InstancedShadowShader;
|
||||
class CInstancedRSMShader;
|
||||
class ShadowShader;
|
||||
class CRSMShader;
|
||||
class InstancedObjectRefPass1Shader;
|
||||
class InstancedObjectRefPass2Shader;
|
||||
class InstancedRefShadowShader;
|
||||
class ObjectRefPass1Shader;
|
||||
class ObjectRefPass2Shader;
|
||||
class RefShadowShader;
|
||||
class InstancedSphereMapShader;
|
||||
class SphereMapShader;
|
||||
class InstancedObjectUnlitShader;
|
||||
class ObjectUnlitShader;
|
||||
class InstancedGrassPass1Shader;
|
||||
class InstancedGrassPass2Shader;
|
||||
class InstancedGrassShadowShader;
|
||||
class GrassPass1Shader;
|
||||
class GrassPass2Shader;
|
||||
class GrassShadowShader;
|
||||
class InstancedNormalMapShader;
|
||||
class NormalMapShader;
|
||||
class InstancedDetailedObjectPass2Shader;
|
||||
class DetailedObjectPass2Shader;
|
||||
class SplattingShader;
|
||||
class SplattingRSMShader;*/
|
||||
|
||||
// ============================================================================
|
||||
class InstancedObjectPass1Shader : public TextureShader<InstancedObjectPass1Shader, 1>
|
||||
@@ -246,7 +218,6 @@ public:
|
||||
} // CInstancedRSMShader
|
||||
}; // CInstancedRSMShader
|
||||
|
||||
|
||||
// ============================================================================
|
||||
class SphereMapShader : public TextureShader<SphereMapShader, 4, core::matrix4,
|
||||
core::matrix4>
|
||||
@@ -822,8 +793,8 @@ struct SplattingMat
|
||||
typedef InstancedObjectPass1Shader InstancedFirstPassShader;
|
||||
//TODO: InstancedSecondPassShader
|
||||
typedef InstancedShadowShader InstancedShadowPassShader;
|
||||
//TODO: InstancedRSMShader
|
||||
|
||||
//TODO InstancedRSMShader
|
||||
|
||||
typedef Shaders::ObjectPass1Shader FirstPassShader;
|
||||
typedef SplattingShader SecondPassShader;
|
||||
typedef ShadowShader ShadowPassShader;
|
||||
|
||||
@@ -183,18 +183,18 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
CVS->isShadowEnabled() && hasShadow)
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||
m_geometry_passes.renderShadows(m_draw_calls,
|
||||
m_shadow_matrices,
|
||||
irr_driver->getRTT()->getShadowFrameBuffer());
|
||||
m_geometry_passes->renderShadows(m_draw_calls,
|
||||
m_shadow_matrices,
|
||||
irr_driver->getRTT()->getShadowFrameBuffer());
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
if (CVS->isGlobalIlluminationEnabled())
|
||||
{
|
||||
if (!m_shadow_matrices.isRSMMapAvail())
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF);
|
||||
m_geometry_passes.renderReflectiveShadowMap(m_draw_calls,
|
||||
m_shadow_matrices,
|
||||
irr_driver->getRTT()->getReflectiveShadowMapFrameBuffer()); //TODO: move somewhere else as RSM are computed only once per track
|
||||
m_geometry_passes->renderReflectiveShadowMap(m_draw_calls,
|
||||
m_shadow_matrices,
|
||||
irr_driver->getRTT()->getReflectiveShadowMapFrameBuffer()); //TODO: move somewhere else as RSM are computed only once per track
|
||||
m_shadow_matrices.setRSMMapAvail(true);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
@@ -217,7 +217,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
rtts->getFBO(FBO_NORMAL_AND_DEPTHS).bind();
|
||||
glClearColor(0., 0., 0., 0.);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
m_geometry_passes.renderSolidFirstPass(m_draw_calls);
|
||||
m_geometry_passes->renderSolidFirstPass(m_draw_calls);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -281,7 +281,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
m_geometry_passes.renderSolidSecondPass( m_draw_calls,
|
||||
m_geometry_passes->renderSolidSecondPass(m_draw_calls,
|
||||
rtts->getRenderTarget(RTT_DIFFUSE),
|
||||
rtts->getRenderTarget(RTT_SPECULAR),
|
||||
rtts->getRenderTarget(RTT_HALF1_R));
|
||||
@@ -290,7 +290,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
if (irr_driver->getNormals())
|
||||
{
|
||||
rtts->getFBO(FBO_NORMAL_AND_DEPTHS).bind();
|
||||
m_geometry_passes.renderNormalsVisualisation(m_draw_calls);
|
||||
m_geometry_passes->renderNormalsVisualisation(m_draw_calls);
|
||||
rtts->getFBO(FBO_COLORS).bind();
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GLOW));
|
||||
irr_driver->setPhase(GLOW_PASS);
|
||||
m_geometry_passes.renderGlow(m_draw_calls, glows);
|
||||
m_geometry_passes->renderGlow(m_draw_calls, glows);
|
||||
} // end glow
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
@@ -355,8 +355,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT));
|
||||
m_geometry_passes.renderTransparent(m_draw_calls,
|
||||
irr_driver->getRTT()->getRenderTarget(RTT_DISPLACE));
|
||||
m_geometry_passes->renderTransparent(m_draw_calls,
|
||||
irr_driver->getRTT()->getRenderTarget(RTT_DISPLACE));
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
@@ -492,10 +492,17 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
|
||||
|
||||
ShaderBasedRenderer::ShaderBasedRenderer()
|
||||
{
|
||||
if (CVS->isAZDOEnabled())
|
||||
m_geometry_passes = new GeometryPasses<MultidrawPolicy>();
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
m_geometry_passes = new GeometryPasses<IndirectDrawPolicy>();
|
||||
else
|
||||
m_geometry_passes = new GeometryPasses<GL3DrawPolicy>();
|
||||
}
|
||||
|
||||
ShaderBasedRenderer::~ShaderBasedRenderer()
|
||||
{
|
||||
delete m_geometry_passes;
|
||||
}
|
||||
|
||||
void ShaderBasedRenderer::addSunLight(const core::vector3df &pos) {
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
|
||||
//GLsync m_sync; //TODO
|
||||
DrawCalls m_draw_calls;
|
||||
GeometryPasses m_geometry_passes;
|
||||
AbstractGeometryPasses *m_geometry_passes;
|
||||
LightingPasses m_lighting_passes;
|
||||
ShadowMatrices m_shadow_matrices;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user