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>
void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes)
template<unsigned N>
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));
for (unsigned i = 0; i < meshes.size(); i++)
{
@ -551,7 +577,7 @@ void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::t
#endif
continue;
}
apply<Shader>(meshes[i]);
apply_instance(Shader, meshes[i]);
}
}
@ -579,10 +605,10 @@ void IrrDriver::renderSolidFirstPass()
{
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD>({ MeshShader::ObjectPass1Shader::TU_tex }, ListDefaultStandardG::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS>({ MeshShader::ObjectPass1Shader::TU_tex }, ListDefault2TCoordG::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD>({ MeshShader::ObjectRefPass1Shader::TU_tex }, ListAlphaRefG::Arguments);
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS>({ MeshShader::NormalMapShader::TU_glossy, MeshShader::NormalMapShader::TU_normalmap }, ListNormalG::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD>(MeshShader::ObjectPass1ShaderInstance, { MeshShader::ObjectPass1ShaderInstance->TU_tex }, ListDefaultStandardG::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS>(MeshShader::ObjectPass1ShaderInstance, { MeshShader::ObjectPass1ShaderInstance->TU_tex }, ListDefault2TCoordG::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD>(MeshShader::ObjectRefPass1ShaderInstance, { MeshShader::ObjectRefPass1ShaderInstance->TU_tex }, ListAlphaRefG::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::MLAAGatherSHader::init();
MeshShader::ColorizeShader::init();
MeshShader::NormalMapShader::init();
MeshShader::ObjectPass1Shader::init();
MeshShader::ObjectRefPass1Shader::init();
MeshShader::NormalMapShaderInstance = new MeshShader::NormalMapShader();
MeshShader::ObjectPass1ShaderInstance = new MeshShader::ObjectPass1Shader();
MeshShader::ObjectRefPass1ShaderInstance = new MeshShader::ObjectRefPass1Shader();
MeshShader::InstancedObjectPass1Shader::init();
MeshShader::InstancedObjectRefPass1Shader::init();
MeshShader::InstancedGrassPass1Shader::init();
@ -468,10 +468,7 @@ namespace MeshShader
{
// Solid Normal and depth pass shaders
GLuint ObjectPass1Shader::Program;
GLuint ObjectPass1Shader::TU_tex;
void ObjectPass1Shader::init()
ObjectPass1Shader::ObjectPass1Shader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
@ -486,22 +483,15 @@ namespace MeshShader
TU_tex = 0;
AssignTextureUnit(Program, { { TU_tex, "tex" } });
}
ObjectPass1Shader *ObjectPass1ShaderInstance;
GLuint ObjectRefPass1Shader::Program;
GLuint ObjectRefPass1Shader::uniform_MM;
GLuint ObjectRefPass1Shader::uniform_IMM;
GLuint ObjectRefPass1Shader::uniform_TM;
GLuint ObjectRefPass1Shader::TU_tex;
void ObjectRefPass1Shader::init()
ObjectRefPass1Shader::ObjectRefPass1Shader()
{
Program = LoadProgram(
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/objectref_pass1.frag").c_str());
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
AssignUniforms(Program, uniforms, { "ModelMatrix", "InverseModelMatrix", "TextureMatrix" });
if (!UserConfigParams::m_ubo_disabled)
{
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -510,13 +500,7 @@ namespace MeshShader
TU_tex = 0;
AssignTextureUnit(Program, { { TU_tex, "tex" } });
}
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);
}
ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
GLuint GrassPass1Shader::Program;
GLuint GrassPass1Shader::uniform_MVP;
@ -544,20 +528,13 @@ namespace MeshShader
glUniform1i(uniform_tex, TU_tex);
}
GLuint NormalMapShader::Program;
GLuint NormalMapShader::uniform_MM;
GLuint NormalMapShader::uniform_IMM;
GLuint NormalMapShader::TU_normalmap;
GLuint NormalMapShader::TU_glossy;
void NormalMapShader::init()
NormalMapShader::NormalMapShader()
{
Program = LoadProgram(
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/normalmap.frag").c_str());
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
AssignUniforms(Program, uniforms, {"ModelMatrix", "InverseModelMatrix"});
if (!UserConfigParams::m_ubo_disabled)
{
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
@ -567,14 +544,7 @@ namespace MeshShader
TU_glossy = 0;
AssignTextureUnit(Program, { { TU_normalmap, "normalMap" }, { TU_glossy, "DiffuseForAlpha" } });
}
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());
}
NormalMapShader *NormalMapShaderInstance;
GLuint InstancedObjectPass1Shader::Program;
GLuint InstancedObjectPass1Shader::uniform_tex;

View File

@ -68,10 +68,11 @@ template<typename... Args>
class ShaderHelper
{
protected:
static std::vector<GLuint> uniforms;
static GLuint Program;
std::vector<GLuint> uniforms;
public:
static void setUniforms(const Args & ... args)
GLuint Program;
void setUniforms(const Args & ... args) const
{
if (UserConfigParams::m_ubo_disabled)
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
{
class ObjectPass1Shader : public ShaderHelper<core::matrix4, core::matrix4>
{
public:
static GLuint Program;
static GLuint TU_tex;
static void init();
GLuint TU_tex;
ObjectPass1Shader();
};
class ObjectRefPass1Shader
extern ObjectPass1Shader *ObjectPass1ShaderInstance;
class ObjectRefPass1Shader : public ShaderHelper<core::matrix4, core::matrix4, core::matrix4>
{
public:
static GLuint Program;
static GLuint uniform_MM, uniform_TM, uniform_IMM;
static GLuint TU_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const core::matrix4 &TextureMatrix);
GLuint TU_tex;
ObjectRefPass1Shader();
};
extern ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
class GrassPass1Shader
{
public:
@ -114,17 +111,15 @@ public:
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:
static GLuint Program;
static GLuint uniform_MM, uniform_IMM;
static GLuint TU_normalmap, TU_glossy;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix);
GLuint TU_normalmap, TU_glossy;
NormalMapShader();
};
extern NormalMapShader *NormalMapShaderInstance;
class InstancedObjectPass1Shader
{
public:

View File

@ -131,6 +131,18 @@ void draw(const GLMesh *mesh, uniforms... Args)
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);
// Pass 2 shader (ie shaders that outputs final color)

View File

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