Turn Pass 1 shader to singleton, and factorize the setUniforms.

This commit is contained in:
vlj 2014-07-13 00:19:45 +02:00
parent ef1bca5424
commit 22be386247
5 changed files with 78 additions and 75 deletions

View File

@ -529,10 +529,36 @@ void IrrDriver::computeSunVisibility()
} }
} }
template<typename Shader, enum E_VERTEX_TYPE VertexType, typename... TupleType> template<unsigned N>
void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes) struct unroll_args_instance
{ {
glUseProgram(Shader::Program); template<typename T, typename ...TupleTypes, typename ...Args>
static void exec(const T *Shader, const std::tuple<TupleTypes...> &t, Args... args)
{
unroll_args_instance<N - 1>::template exec<T>(Shader, t, std::get<N - 1>(t), args...);
}
};
template<>
struct unroll_args_instance<0>
{
template<typename T, typename ...TupleTypes, typename ...Args>
static void exec(const T *Shader, const std::tuple<TupleTypes...> &t, Args... args)
{
draw<T>(Shader, args...);
}
};
template<typename T, typename... TupleType>
void apply_instance(const T *Shader, const std::tuple<TupleType...> &arg)
{
unroll_args_instance<std::tuple_size<std::tuple<TupleType...> >::value >::template exec<T>(Shader, arg);
}
template<typename T, enum E_VERTEX_TYPE VertexType, typename... TupleType>
void renderMeshes1stPass(const T *Shader, const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes)
{
glUseProgram(Shader->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(getVAO(VertexType));
for (unsigned i = 0; i < meshes.size(); i++) for (unsigned i = 0; i < meshes.size(); i++)
{ {
@ -551,7 +577,7 @@ void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::t
#endif #endif
continue; continue;
} }
apply<Shader>(meshes[i]); apply_instance(Shader, meshes[i]);
} }
} }
@ -579,10 +605,10 @@ void IrrDriver::renderSolidFirstPass()
{ {
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1)); ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD>({ MeshShader::ObjectPass1Shader::TU_tex }, ListDefaultStandardG::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD>(MeshShader::ObjectPass1ShaderInstance, { MeshShader::ObjectPass1ShaderInstance->TU_tex }, ListDefaultStandardG::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS>({ MeshShader::ObjectPass1Shader::TU_tex }, ListDefault2TCoordG::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS>(MeshShader::ObjectPass1ShaderInstance, { MeshShader::ObjectPass1ShaderInstance->TU_tex }, ListDefault2TCoordG::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD>({ MeshShader::ObjectRefPass1Shader::TU_tex }, ListAlphaRefG::Arguments); renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD>(MeshShader::ObjectRefPass1ShaderInstance, { MeshShader::ObjectRefPass1ShaderInstance->TU_tex }, ListAlphaRefG::Arguments);
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS>({ MeshShader::NormalMapShader::TU_glossy, MeshShader::NormalMapShader::TU_normalmap }, ListNormalG::Arguments); renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS>(MeshShader::NormalMapShaderInstance, { MeshShader::NormalMapShaderInstance->TU_glossy, MeshShader::NormalMapShaderInstance->TU_normalmap }, ListNormalG::Arguments);
} }
} }

View File

@ -325,9 +325,9 @@ void Shaders::loadShaders()
FullScreenShader::MLAABlendWeightSHader::init(); FullScreenShader::MLAABlendWeightSHader::init();
FullScreenShader::MLAAGatherSHader::init(); FullScreenShader::MLAAGatherSHader::init();
MeshShader::ColorizeShader::init(); MeshShader::ColorizeShader::init();
MeshShader::NormalMapShader::init(); MeshShader::NormalMapShaderInstance = new MeshShader::NormalMapShader();
MeshShader::ObjectPass1Shader::init(); MeshShader::ObjectPass1ShaderInstance = new MeshShader::ObjectPass1Shader();
MeshShader::ObjectRefPass1Shader::init(); MeshShader::ObjectRefPass1ShaderInstance = new MeshShader::ObjectRefPass1Shader();
MeshShader::InstancedObjectPass1Shader::init(); MeshShader::InstancedObjectPass1Shader::init();
MeshShader::InstancedObjectRefPass1Shader::init(); MeshShader::InstancedObjectRefPass1Shader::init();
MeshShader::InstancedGrassPass1Shader::init(); MeshShader::InstancedGrassPass1Shader::init();
@ -468,10 +468,7 @@ namespace MeshShader
{ {
// Solid Normal and depth pass shaders // Solid Normal and depth pass shaders
GLuint ObjectPass1Shader::Program; ObjectPass1Shader::ObjectPass1Shader()
GLuint ObjectPass1Shader::TU_tex;
void ObjectPass1Shader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
@ -486,22 +483,15 @@ namespace MeshShader
TU_tex = 0; TU_tex = 0;
AssignTextureUnit(Program, { { TU_tex, "tex" } }); AssignTextureUnit(Program, { { TU_tex, "tex" } });
} }
ObjectPass1Shader *ObjectPass1ShaderInstance;
GLuint ObjectRefPass1Shader::Program; ObjectRefPass1Shader::ObjectRefPass1Shader()
GLuint ObjectRefPass1Shader::uniform_MM;
GLuint ObjectRefPass1Shader::uniform_IMM;
GLuint ObjectRefPass1Shader::uniform_TM;
GLuint ObjectRefPass1Shader::TU_tex;
void ObjectRefPass1Shader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); AssignUniforms(Program, uniforms, { "ModelMatrix", "InverseModelMatrix", "TextureMatrix" });
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -510,13 +500,7 @@ namespace MeshShader
TU_tex = 0; TU_tex = 0;
AssignTextureUnit(Program, { { TU_tex, "tex" } }); AssignTextureUnit(Program, { { TU_tex, "tex" } });
} }
ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
void ObjectRefPass1Shader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const core::matrix4 &TextureMatrix)
{
if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program);
setUniformsHelper({ uniform_MM, uniform_TM, uniform_IMM }, ModelMatrix, InverseModelMatrix, TextureMatrix);
}
GLuint GrassPass1Shader::Program; GLuint GrassPass1Shader::Program;
GLuint GrassPass1Shader::uniform_MVP; GLuint GrassPass1Shader::uniform_MVP;
@ -544,20 +528,13 @@ namespace MeshShader
glUniform1i(uniform_tex, TU_tex); glUniform1i(uniform_tex, TU_tex);
} }
GLuint NormalMapShader::Program; NormalMapShader::NormalMapShader()
GLuint NormalMapShader::uniform_MM;
GLuint NormalMapShader::uniform_IMM;
GLuint NormalMapShader::TU_normalmap;
GLuint NormalMapShader::TU_glossy;
void NormalMapShader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/normalmap.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/normalmap.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/normalmap.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/normalmap.frag").c_str());
uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); AssignUniforms(Program, uniforms, {"ModelMatrix", "InverseModelMatrix"});
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
if (!UserConfigParams::m_ubo_disabled) if (!UserConfigParams::m_ubo_disabled)
{ {
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -567,14 +544,7 @@ namespace MeshShader
TU_glossy = 0; TU_glossy = 0;
AssignTextureUnit(Program, { { TU_normalmap, "normalMap" }, { TU_glossy, "DiffuseForAlpha" } }); AssignTextureUnit(Program, { { TU_normalmap, "normalMap" }, { TU_glossy, "DiffuseForAlpha" } });
} }
NormalMapShader *NormalMapShaderInstance;
void NormalMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix)
{
if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniformMatrix4fv(uniform_IMM, 1, GL_FALSE, InverseModelMatrix.pointer());
}
GLuint InstancedObjectPass1Shader::Program; GLuint InstancedObjectPass1Shader::Program;
GLuint InstancedObjectPass1Shader::uniform_tex; GLuint InstancedObjectPass1Shader::uniform_tex;

View File

@ -68,10 +68,11 @@ template<typename... Args>
class ShaderHelper class ShaderHelper
{ {
protected: protected:
static std::vector<GLuint> uniforms; std::vector<GLuint> uniforms;
static GLuint Program;
public: public:
static void setUniforms(const Args & ... args) GLuint Program;
void setUniforms(const Args & ... args) const
{ {
if (UserConfigParams::m_ubo_disabled) if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program); bypassUBO(Program);
@ -79,31 +80,27 @@ public:
} }
}; };
template<typename... Args> std::vector<GLuint> ShaderHelper<Args...>::uniforms;
template<typename... Args> GLuint ShaderHelper<Args...>::Program;
namespace MeshShader namespace MeshShader
{ {
class ObjectPass1Shader : public ShaderHelper<core::matrix4, core::matrix4> class ObjectPass1Shader : public ShaderHelper<core::matrix4, core::matrix4>
{ {
public: public:
static GLuint Program; GLuint TU_tex;
static GLuint TU_tex; ObjectPass1Shader();
static void init();
}; };
class ObjectRefPass1Shader extern ObjectPass1Shader *ObjectPass1ShaderInstance;
class ObjectRefPass1Shader : public ShaderHelper<core::matrix4, core::matrix4, core::matrix4>
{ {
public: public:
static GLuint Program; GLuint TU_tex;
static GLuint uniform_MM, uniform_TM, uniform_IMM; ObjectRefPass1Shader();
static GLuint TU_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const core::matrix4 &TextureMatrix);
}; };
extern ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
class GrassPass1Shader class GrassPass1Shader
{ {
public: public:
@ -114,17 +111,15 @@ public:
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex); static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex);
}; };
class NormalMapShader class NormalMapShader : public ShaderHelper<core::matrix4, core::matrix4>
{ {
public: public:
static GLuint Program; GLuint TU_normalmap, TU_glossy;
static GLuint uniform_MM, uniform_IMM; NormalMapShader();
static GLuint TU_normalmap, TU_glossy;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix);
}; };
extern NormalMapShader *NormalMapShaderInstance;
class InstancedObjectPass1Shader class InstancedObjectPass1Shader
{ {
public: public:

View File

@ -131,6 +131,18 @@ void draw(const GLMesh *mesh, uniforms... Args)
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex); glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
} }
template<typename T, typename...uniforms>
void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh->PrimitiveType;
GLenum itype = mesh->IndexType;
size_t count = mesh->IndexCount;
Shader->setUniforms(Args...);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir); void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir);
// Pass 2 shader (ie shaders that outputs final color) // Pass 2 shader (ie shaders that outputs final color)

View File

@ -260,7 +260,7 @@ void STKMeshSceneNode::render()
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
if (update_each_frame) if (update_each_frame)
updatevbo(); updatevbo();
glUseProgram(MeshShader::ObjectPass1Shader::Program); glUseProgram(MeshShader::ObjectPass1ShaderInstance->Program);
// Only untextured // Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++) for (unsigned i = 0; i < GLmeshes.size(); i++)
{ {
@ -270,7 +270,7 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
MeshShader::ObjectPass1Shader::setUniforms(AbsoluteTransformation, invmodel); MeshShader::ObjectPass1ShaderInstance->setUniforms(AbsoluteTransformation, invmodel);
assert(mesh.vao); assert(mesh.vao);
glBindVertexArray(mesh.vao); glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0); glDrawElements(ptype, count, itype, 0);