Moved more drawing functions from GeometryPasses to drawing policies classes.
This commit is contained in:
@@ -49,7 +49,7 @@ void fillOriginOrientationScale(scene::ISceneNode *node, InstanceData &instance)
|
||||
instance.Orientation.Z = Orientation.Z;
|
||||
instance.Scale.X = Scale.X;
|
||||
instance.Scale.Y = Scale.Y;
|
||||
instance.Scale.Z = Scale.Z;
|
||||
instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
template<typename InstanceData>
|
||||
|
||||
286
src/graphics/draw_policies.cpp
Normal file
286
src/graphics/draw_policies.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/draw_policies.hpp"
|
||||
#include "graphics/draw_tools.hpp"
|
||||
#include "graphics/materials.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int ...List>
|
||||
void renderMeshes1stPass(const DrawCalls& draw_calls)
|
||||
{
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
T::FirstPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh.vao);
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 1 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::FirstPassShader>::template expand(mesh.TextureHandles, T::FirstPassTextures);
|
||||
else
|
||||
TexExpander<typename T::FirstPassShader>::template expandTex(mesh, T::FirstPassTextures);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::FirstPassShader>(meshes.at(i));
|
||||
}
|
||||
} // renderMeshes1stPass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int...List>
|
||||
void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
||||
const std::vector<GLuint> &Prefilled_Tex)
|
||||
{
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
T::SecondPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh.vao);
|
||||
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 2 "
|
||||
"(hint texture : %s)",
|
||||
mesh.textures[0]->getName().getPath().c_str());
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::SecondPassShader>::template
|
||||
expand(mesh.TextureHandles, T::SecondPassTextures,
|
||||
Prefilled_Handle[0], Prefilled_Handle[1],
|
||||
Prefilled_Handle[2]);
|
||||
else
|
||||
TexExpander<typename T::SecondPassShader>::template
|
||||
expandTex(mesh, T::SecondPassTextures, Prefilled_Tex[0],
|
||||
Prefilled_Tex[1], Prefilled_Tex[2]);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::SecondPassShader>(meshes.at(i));
|
||||
}
|
||||
} // renderMeshes2ndPass
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GL3DrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const
|
||||
{
|
||||
renderMeshes2ndPass<DefaultMaterial, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<AlphaRef, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<UnlitMat, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<SphereMap, 2, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<DetailMat, 1 > (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<GrassMat, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<NormalMat, 3, 1> (handles, prefilled_tex);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
||||
{
|
||||
//TODO: find a way to add TextureMarix in instanced shaders,
|
||||
//and remove these four lines
|
||||
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);
|
||||
|
||||
draw_calls.drawIndirectSolidFirstPass();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IndirectDrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const
|
||||
{
|
||||
//TODO: find a way to add TextureMarix in instanced shaders,
|
||||
//and remove these four lines
|
||||
renderMeshes2ndPass<DefaultMaterial, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<AlphaRef, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<UnlitMat, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
||||
|
||||
draw_calls.drawIndirectSolidSecondPass(prefilled_tex);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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: write instanced splatting RSM shader and remove this line
|
||||
draw_calls.drawIndirectReflectiveShadowMaps(rsm_matrix);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MultidrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
||||
{
|
||||
//TODO: find a way to add TextureMarix in instanced shaders,
|
||||
//and remove these four lines
|
||||
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);
|
||||
|
||||
draw_calls.multidrawSolidFirstPass();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void MultidrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const
|
||||
{
|
||||
//TODO: find a way to add TextureMarix in instanced shaders,
|
||||
//and remove these four lines
|
||||
renderMeshes2ndPass<DefaultMaterial, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<AlphaRef, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<UnlitMat, 3, 1> (handles, prefilled_tex);
|
||||
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
||||
|
||||
draw_calls.multidrawSolidSecondPass(handles);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
86
src/graphics/draw_policies.hpp
Normal file
86
src/graphics/draw_policies.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program 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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_DRAW_POLICIES_HPP
|
||||
#define HEADER_DRAW_POLICIES_HPP
|
||||
|
||||
#include "graphics/draw_calls.hpp"
|
||||
|
||||
|
||||
/** Rendering methods in this class only require
|
||||
* OpenGL3.2 functions */
|
||||
class GL3DrawPolicy
|
||||
{
|
||||
public:
|
||||
void drawSolidFirstPass (const DrawCalls& draw_calls ) const;
|
||||
|
||||
void drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const;
|
||||
|
||||
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 OpenGL 4.0 (or higher)
|
||||
* or GL_ARB_base_instance and GL_ARB_draw_indirect extensions)*/
|
||||
class IndirectDrawPolicy
|
||||
{
|
||||
public:
|
||||
void drawSolidFirstPass (const DrawCalls& draw_calls ) const;
|
||||
|
||||
void drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const;
|
||||
|
||||
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 drawSolidFirstPass (const DrawCalls& draw_calls ) const;
|
||||
|
||||
void drawSolidSecondPass (const DrawCalls& draw_calls,
|
||||
const std::vector<uint64_t>& handles,
|
||||
const std::vector<GLuint>& prefilled_tex) const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
#endif //HEADER_DRAW_POLICIES_HPP
|
||||
@@ -133,188 +133,6 @@ namespace RenderGeometry
|
||||
using namespace RenderGeometry;
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int ...List>
|
||||
void renderMeshes1stPass(const DrawCalls& draw_calls)
|
||||
{
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
T::FirstPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh.vao);
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 1 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::FirstPassShader>::template expand(mesh.TextureHandles, T::FirstPassTextures);
|
||||
else
|
||||
TexExpander<typename T::FirstPassShader>::template expandTex(mesh, T::FirstPassTextures);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::FirstPassShader>(meshes.at(i));
|
||||
}
|
||||
} // renderMeshes1stPass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T, int...List>
|
||||
void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
||||
const std::vector<GLuint> &Prefilled_Tex)
|
||||
{
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
T::SecondPassShader::getInstance()->use();
|
||||
if (CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i)));
|
||||
if (!CVS->isARBBaseInstanceUsable())
|
||||
glBindVertexArray(mesh.vao);
|
||||
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 2 "
|
||||
"(hint texture : %s)",
|
||||
mesh.textures[0]->getName().getPath().c_str());
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
HandleExpander<typename T::SecondPassShader>::template
|
||||
expand(mesh.TextureHandles, T::SecondPassTextures,
|
||||
Prefilled_Handle[0], Prefilled_Handle[1],
|
||||
Prefilled_Handle[2]);
|
||||
else
|
||||
TexExpander<typename T::SecondPassShader>::template
|
||||
expandTex(mesh, T::SecondPassTextures, Prefilled_Tex[0],
|
||||
Prefilled_Tex[1], Prefilled_Tex[2]);
|
||||
CustomUnrollArgs<List...>::template drawMesh<typename T::SecondPassShader>(meshes.at(i));
|
||||
}
|
||||
} // renderMeshes2ndPass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
@@ -363,124 +181,30 @@ void AbstractGeometryPasses::shadowPostProcessing(const ShadowMatrices& shadow_m
|
||||
|
||||
AbstractGeometryPasses::AbstractGeometryPasses()
|
||||
{
|
||||
m_displace_tex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
|
||||
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)
|
||||
{
|
||||
irr_driver->setPhase(SOLID_LIT_PASS);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
uint64_t DiffuseHandle = 0, SpecularHandle = 0, SSAOHandle = 0, DepthHandle = 0;
|
||||
void AbstractGeometryPasses::setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures)
|
||||
{
|
||||
m_prefilled_textures = prefilled_textures;
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
DiffuseHandle = glGetTextureSamplerHandleARB(render_target_diffuse,
|
||||
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[0]);
|
||||
if (!glIsTextureHandleResidentARB(DiffuseHandle))
|
||||
glMakeTextureHandleResidentARB(DiffuseHandle);
|
||||
|
||||
SpecularHandle = glGetTextureSamplerHandleARB(render_target_specular,
|
||||
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[1]);
|
||||
if (!glIsTextureHandleResidentARB(SpecularHandle))
|
||||
glMakeTextureHandleResidentARB(SpecularHandle);
|
||||
|
||||
SSAOHandle = glGetTextureSamplerHandleARB(render_target_half_red,
|
||||
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[2]);
|
||||
if (!glIsTextureHandleResidentARB(SSAOHandle))
|
||||
glMakeTextureHandleResidentARB(SSAOHandle);
|
||||
|
||||
DepthHandle = glGetTextureSamplerHandleARB(irr_driver->getDepthStencilTexture(),
|
||||
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[3]);
|
||||
if (!glIsTextureHandleResidentARB(DepthHandle))
|
||||
glMakeTextureHandleResidentARB(DepthHandle);
|
||||
}
|
||||
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS2));
|
||||
|
||||
irr_driver->setPhase(SOLID_LIT_PASS);
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
|
||||
std::vector<GLuint> DiffSpecSSAOTex =
|
||||
createVector<GLuint>(render_target_diffuse,
|
||||
render_target_specular,
|
||||
render_target_half_red);
|
||||
|
||||
//TODO: is it useful when AZDO enabled?
|
||||
renderMeshes2ndPass<DefaultMaterial, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<AlphaRef, 3, 1 >(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<UnlitMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<SplattingMat, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<SphereMap, 2, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<DetailMat, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<GrassMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<NormalMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
for(size_t i=0;i<m_prefilled_textures.size();i++)
|
||||
{
|
||||
std::vector<uint64_t> handles =
|
||||
createVector<uint64_t>(DiffuseHandle,
|
||||
SpecularHandle,
|
||||
SSAOHandle,
|
||||
DepthHandle);
|
||||
|
||||
draw_calls.multidrawSolidSecondPass(handles);
|
||||
uint64_t handle = 0;
|
||||
handle = glGetTextureSamplerHandleARB(m_prefilled_textures[i],
|
||||
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[i]);
|
||||
if (!glIsTextureHandleResidentARB(handle))
|
||||
glMakeTextureHandleResidentARB(handle);
|
||||
m_textures_handles.push_back(handle);
|
||||
}
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
{
|
||||
std::vector<GLuint> prefilled_tex =
|
||||
createVector<GLuint>(render_target_diffuse,
|
||||
render_target_specular,
|
||||
render_target_half_red,
|
||||
irr_driver->getDepthStencilTexture());
|
||||
draw_calls.drawIndirectSolidSecondPass(prefilled_tex);
|
||||
}
|
||||
}
|
||||
} // renderSolidSecondPass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void AbstractGeometryPasses::renderGlow(const DrawCalls& draw_calls, const std::vector<GlowData>& glows)
|
||||
{
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(scene::ESNRP_SOLID);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SuperTuxéKart - a fun racing game with go-kart
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@@ -25,55 +25,19 @@
|
||||
#include <ITexture.h>
|
||||
|
||||
|
||||
/** Rendering methods in this class only require
|
||||
* OpenGL3.2 functions */
|
||||
class GL3DrawPolicy
|
||||
{
|
||||
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::core::vector3df m_wind_dir; //TODO
|
||||
irr::video::ITexture *m_displace_tex;
|
||||
|
||||
std::vector<GLuint> m_prefilled_textures;
|
||||
std::vector<uint64_t> m_textures_handles;
|
||||
|
||||
|
||||
void prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const;
|
||||
void shadowPostProcessing(const ShadowMatrices& shadow_matrices,
|
||||
const FrameBuffer& shadow_framebuffer) const;
|
||||
@@ -82,11 +46,11 @@ public:
|
||||
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 setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures);
|
||||
|
||||
virtual void renderSolidFirstPass(const DrawCalls& draw_calls) const = 0;
|
||||
|
||||
virtual void renderSolidSecondPass( const DrawCalls& draw_calls) const = 0;
|
||||
|
||||
virtual void renderNormalsVisualisation(const DrawCalls& draw_calls) const = 0;
|
||||
|
||||
@@ -111,6 +75,29 @@ template<typename DrawPolicy>
|
||||
class GeometryPasses: public AbstractGeometryPasses, public DrawPolicy
|
||||
{
|
||||
public:
|
||||
void renderSolidFirstPass(const DrawCalls& draw_calls) const
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS1));
|
||||
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
DrawPolicy::drawSolidFirstPass(draw_calls);
|
||||
|
||||
} // renderSolidFirstPass
|
||||
|
||||
void renderSolidSecondPass( const DrawCalls& draw_calls) const
|
||||
{
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS2));
|
||||
irr_driver->setPhase(SOLID_LIT_PASS);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
DrawPolicy::drawSolidSecondPass(draw_calls,
|
||||
m_textures_handles,
|
||||
m_prefilled_textures);
|
||||
}
|
||||
|
||||
|
||||
void renderNormalsVisualisation(const DrawCalls& draw_calls) const
|
||||
{
|
||||
|
||||
@@ -281,10 +281,16 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
m_geometry_passes->renderSolidSecondPass(m_draw_calls,
|
||||
rtts->getRenderTarget(RTT_DIFFUSE),
|
||||
rtts->getRenderTarget(RTT_SPECULAR),
|
||||
rtts->getRenderTarget(RTT_HALF1_R));
|
||||
|
||||
std::vector<GLuint> prefilled_textures =
|
||||
createVector<GLuint>(rtts->getRenderTarget(RTT_DIFFUSE),
|
||||
rtts->getRenderTarget(RTT_SPECULAR),
|
||||
rtts->getRenderTarget(RTT_HALF1_R),
|
||||
irr_driver->getDepthStencilTexture());
|
||||
m_geometry_passes->setFirstPassRenderTargets(prefilled_textures);
|
||||
//TODO: no need to update it every frame
|
||||
|
||||
m_geometry_passes->renderSolidSecondPass(m_draw_calls);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
if (irr_driver->getNormals())
|
||||
@@ -491,7 +497,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
|
||||
|
||||
|
||||
ShaderBasedRenderer::ShaderBasedRenderer()
|
||||
{
|
||||
{
|
||||
if (CVS->isAZDOEnabled())
|
||||
m_geometry_passes = new GeometryPasses<MultidrawPolicy>();
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "graphics/abstract_renderer.hpp"
|
||||
#include "graphics/draw_calls.hpp"
|
||||
#include "graphics/draw_policies.hpp"
|
||||
#include "graphics/geometry_passes.hpp"
|
||||
#include "graphics/lighting_passes.hpp"
|
||||
#include "graphics/shadow_matrices.hpp"
|
||||
|
||||
Reference in New Issue
Block a user