Allow auto-add usable uniforms to shader
This commit is contained in:
parent
9e2d649b55
commit
97fd634ed8
@ -100,18 +100,11 @@
|
||||
<shadow-pass use-function="" unuse-function=""
|
||||
vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<!--
|
||||
uniforms: Define the uniforms in shader with the name of the
|
||||
type (int, float, mat4, vec4, vec3, vec2).
|
||||
-->
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<!--
|
||||
uniform-assigners: List of uniform assigners functions to be auto-run
|
||||
when "use" the shader which set the above uniforms,
|
||||
currently there are:
|
||||
when "use" the shader which set the uniform
|
||||
variables in shader, currently there are:
|
||||
|
||||
shadowCascadeUniformAssigner will set the current shadow
|
||||
cascade being drawn.
|
||||
@ -127,6 +120,9 @@
|
||||
|
||||
You have to specify the uniform name in shader together with the
|
||||
bundled uniform-assigners.
|
||||
|
||||
Currently you can automatically assign to uniform type int, float,
|
||||
mat4, vec4, vec3 and vec2 only.
|
||||
-->
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -7,9 +7,6 @@
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -7,9 +7,6 @@
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -5,9 +5,6 @@
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -2,16 +2,9 @@
|
||||
<shader-info name="grass" use-alpha-channel="Y"/>
|
||||
<first-pass vertex-shader="sp_grass_pass.vert"
|
||||
fragment-shader="sp_grass.frag">
|
||||
<uniforms>
|
||||
<uniform name="wind_direction" type="vec3"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_grass_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag">
|
||||
<uniforms>
|
||||
<uniform name="wind_direction" type="vec3"/>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -6,9 +6,6 @@
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
|
@ -3,10 +3,6 @@
|
||||
<first-pass use-function="alphaBlendUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_transparent.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="fog_enabled" type="int"/>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="fog_enabled"
|
||||
|
@ -3,10 +3,6 @@
|
||||
<first-pass use-function="additiveUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_transparent.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="fog_enabled" type="int"/>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="fog_enabled"
|
||||
|
@ -3,9 +3,6 @@
|
||||
<first-pass use-function="ghostUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_ghost.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="custom_alpha"
|
||||
|
@ -1134,7 +1134,8 @@ void PostProcessing::renderGodRays(scene::ICameraSceneNode * const camnode,
|
||||
SP::SPUniformAssigner* glow_color_assigner = glow_shader
|
||||
->getUniformAssigner("col");
|
||||
assert(glow_color_assigner != NULL);
|
||||
glow_color_assigner->setValue(video::SColorf(track->getGodRaysColor()));
|
||||
video::SColorf cf(track->getGodRaysColor());
|
||||
glow_color_assigner->setValue(core::vector3df(cf.r, cf.g, cf.b));
|
||||
sun->draw();
|
||||
glow_shader->unuse();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
@ -83,7 +83,7 @@ std::vector<std::pair<SPShader*, std::vector<std::pair<std::array<GLuint, 6>,
|
||||
std::vector<std::pair<SPMeshBuffer*, int/*material_id*/> > > > > >
|
||||
g_final_draw_calls[DCT_FOR_VAO];
|
||||
// ----------------------------------------------------------------------------
|
||||
std::unordered_map<unsigned, std::pair<video::SColorf,
|
||||
std::unordered_map<unsigned, std::pair<core::vector3df,
|
||||
std::unordered_set<SPMeshBuffer*> > > g_glow_meshes;
|
||||
// ----------------------------------------------------------------------------
|
||||
std::unordered_set<SPMeshBuffer*> g_instances;
|
||||
@ -186,7 +186,7 @@ void displaceShaderInit(SPShader* shader)
|
||||
shader->linkShaderFiles(RP_RESERVED);
|
||||
shader->use(RP_RESERVED);
|
||||
shader->addBasicUniforms(RP_RESERVED);
|
||||
shader->addUniform("direction", typeid(std::array<float, 4>), RP_RESERVED);
|
||||
shader->addAllUniforms(RP_RESERVED);
|
||||
shader->setUseFunction([]()->void
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -357,7 +357,7 @@ void loadShaders()
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("col", typeid(irr::video::SColorf), RP_1ST);
|
||||
shader->addAllUniforms(RP_1ST);
|
||||
});
|
||||
SPShaderManager::get()->addSPShader(sps->getName(), sps);
|
||||
g_glow_shader = sps.get();
|
||||
@ -928,7 +928,8 @@ void addObject(SPMeshNode* node)
|
||||
auto ret = g_glow_meshes.find(key);
|
||||
if (ret == g_glow_meshes.end())
|
||||
{
|
||||
g_glow_meshes[key] = std::make_pair(gc,
|
||||
g_glow_meshes[key] = std::make_pair(
|
||||
core::vector3df(gc.r, gc.g, gc.b),
|
||||
std::unordered_set<SPMeshBuffer*>());
|
||||
}
|
||||
g_glow_meshes.at(key).second.insert(mb);
|
||||
|
@ -24,9 +24,11 @@
|
||||
#include "guiengine/message_queue.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace SP
|
||||
{
|
||||
std::unordered_map<std::string, std::pair<unsigned, SamplerType> >
|
||||
const std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
g_prefilled_names =
|
||||
{
|
||||
#ifdef USE_GLES2
|
||||
@ -203,20 +205,49 @@ void SPShader::bindTextures(const std::array<GLuint, 6>& tex,
|
||||
} // bindTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::addUniform(const std::string& name, const std::type_index& ti,
|
||||
RenderPass rp)
|
||||
void SPShader::addAllUniforms(RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
const char* s = name.c_str();
|
||||
GLuint location = glGetUniformLocation(m_program[rp], s);
|
||||
if (location == GL_INVALID_INDEX)
|
||||
GLint total_uniforms;
|
||||
glGetProgramiv(m_program[rp], GL_ACTIVE_UNIFORMS, &total_uniforms);
|
||||
static const std::map<GLenum, std::type_index> supported_types =
|
||||
{
|
||||
{ GL_INT, std::type_index(typeid(int)) },
|
||||
{ GL_FLOAT, std::type_index(typeid(float)) },
|
||||
{ GL_FLOAT_MAT4, std::type_index(typeid(irr::core::matrix4)) },
|
||||
{ GL_FLOAT_VEC4, std::type_index(typeid(std::array<float, 4>)) },
|
||||
{ GL_FLOAT_VEC3, std::type_index(typeid(irr::core::vector3df)) },
|
||||
{ GL_FLOAT_VEC2, std::type_index(typeid(irr::core::vector2df)) }
|
||||
};
|
||||
|
||||
for (int i = 0; i < total_uniforms; i++)
|
||||
{
|
||||
Log::warn("SPShader", "Missing uniform %s in shader files.", s);
|
||||
return;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
char name[100] = {};
|
||||
glGetActiveUniform(m_program[rp], i, 99, NULL, &size, &type, name);
|
||||
if (size != 1)
|
||||
{
|
||||
Log::debug("SPShader", "Array of uniforms is not supported in"
|
||||
" shader %s for %s.", m_name.c_str(), name);
|
||||
continue;
|
||||
}
|
||||
auto ret = supported_types.find(type);
|
||||
if (ret == supported_types.end())
|
||||
{
|
||||
Log::debug("SPShader", "%d type not supported", (unsigned)type);
|
||||
continue;
|
||||
}
|
||||
GLuint location = glGetUniformLocation(m_program[rp], name);
|
||||
if (location == GL_INVALID_INDEX)
|
||||
{
|
||||
Log::debug("SPShader", "%s uniform not found", name);
|
||||
continue;
|
||||
}
|
||||
m_uniforms[rp][name] = new SPUniformAssigner(ret->second, location);
|
||||
}
|
||||
m_uniforms[rp][name] = new SPUniformAssigner(ti, location);
|
||||
#endif
|
||||
} // addUniform
|
||||
} // addAllUniforms
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::setUniformsPerObject(SPPerObjectUniform* sppou,
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void addAllTextures(RenderPass rp = RP_1ST);
|
||||
// ------------------------------------------------------------------------
|
||||
void addAllUniforms(RenderPass rp = RP_1ST);
|
||||
// ------------------------------------------------------------------------
|
||||
void addCustomPrefilledTextures(SamplerType st, GLuint texture_type,
|
||||
const std::string& name,
|
||||
std::function<GLuint()> func,
|
||||
@ -190,9 +192,6 @@ public:
|
||||
SPUniformAssigner* getUniformAssigner(const std::string& name,
|
||||
RenderPass rp = RP_1ST) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void addUniform(const std::string& name, const std::type_index& ti,
|
||||
RenderPass rp = RP_1ST);
|
||||
// ------------------------------------------------------------------------
|
||||
void setUniformsPerObject(SPPerObjectUniform* sppou,
|
||||
std::vector<SPUniformAssigner*>* ua_used,
|
||||
RenderPass rp = RP_1ST);
|
||||
|
@ -37,16 +37,6 @@ SPShaderManager* SPShaderManager::m_spsm = NULL;
|
||||
SPShaderManager::SPShaderManager()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_official_types =
|
||||
{
|
||||
{ "int", std::type_index(typeid(int)) },
|
||||
{ "float", std::type_index(typeid(float)) },
|
||||
{ "mat4", std::type_index(typeid(irr::core::matrix4)) },
|
||||
{ "vec4", std::type_index(typeid(std::array<float, 4>)) },
|
||||
{ "vec3", std::type_index(typeid(irr::core::vector3df)) },
|
||||
{ "vec2", std::type_index(typeid(irr::core::vector2df)) }
|
||||
};
|
||||
|
||||
m_official_sampler_types =
|
||||
{
|
||||
{ "nearest", ST_NEAREST },
|
||||
@ -313,32 +303,6 @@ void SPShaderManager::loadPassInfo(const XMLNode* pass, PassInfo& pi)
|
||||
pass->get("skinned-mesh-shader", &pi.m_skinned_mesh_shader);
|
||||
pi.m_skinned_mesh_shader = getShaderFullPath(pi.m_skinned_mesh_shader);
|
||||
|
||||
const XMLNode* uniforms = pass->getNode("uniforms");
|
||||
if (uniforms)
|
||||
{
|
||||
for (unsigned i = 0; i < uniforms->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* uniform = uniforms->getNode(i);
|
||||
if (uniform->getName() == "uniform")
|
||||
{
|
||||
std::string name, type;
|
||||
uniform->get("name", &name);
|
||||
uniform->get("type", &type);
|
||||
if (!name.empty() && !type.empty() &&
|
||||
m_official_types.find(type) != m_official_types.end())
|
||||
{
|
||||
pi.m_uniforms.emplace_back(name,
|
||||
m_official_types.at(type));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid uniform type %s",
|
||||
type.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const XMLNode* prefilled_textures = pass->getNode("prefilled-textures");
|
||||
if (prefilled_textures)
|
||||
{
|
||||
@ -431,7 +395,7 @@ std::shared_ptr<SPShader> SPShaderManager::buildSPShader(const ShaderInfo& si,
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
addUniformsToShader(shader, pi[0].m_uniforms, RP_1ST);
|
||||
shader->addAllUniforms(RP_1ST);
|
||||
if (pi[0].m_use_function)
|
||||
{
|
||||
shader->setUseFunction(pi[0].m_use_function, RP_1ST);
|
||||
@ -466,7 +430,7 @@ std::shared_ptr<SPShader> SPShaderManager::buildSPShader(const ShaderInfo& si,
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
addUniformsToShader(shader, pi[1].m_uniforms, RP_SHADOW);
|
||||
shader->addAllUniforms(RP_SHADOW);
|
||||
if (pi[1].m_use_function)
|
||||
{
|
||||
shader->setUseFunction(pi[1].m_use_function, RP_SHADOW);
|
||||
@ -484,17 +448,6 @@ std::shared_ptr<SPShader> SPShaderManager::buildSPShader(const ShaderInfo& si,
|
||||
return sps;
|
||||
} // buildSPShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::addUniformsToShader(SPShader* s,
|
||||
const std::vector<std::pair<std::string, std::type_index> >& u,
|
||||
RenderPass rp)
|
||||
{
|
||||
for (auto& p : u)
|
||||
{
|
||||
s->addUniform(p.first, p.second, rp);
|
||||
}
|
||||
} // addUniformsToShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::addPrefilledTexturesToShader(SPShader* s,
|
||||
const std::vector<std::tuple<std::string, std::string, bool, SamplerType> >
|
||||
|
@ -41,7 +41,6 @@ enum RenderPass: unsigned int;
|
||||
class SPShaderManager : public NoCopy
|
||||
{
|
||||
public:
|
||||
|
||||
struct PassInfo
|
||||
{
|
||||
std::function<void()> m_use_function;
|
||||
@ -54,8 +53,6 @@ public:
|
||||
|
||||
std::string m_skinned_mesh_shader;
|
||||
|
||||
std::vector<std::pair<std::string, std::type_index> > m_uniforms;
|
||||
|
||||
std::vector<std::tuple<std::string, std::string, bool, SamplerType> >
|
||||
m_prefilled_textures;
|
||||
};
|
||||
@ -87,8 +84,6 @@ private:
|
||||
|
||||
std::vector<std::shared_ptr<SPShader> > m_official_shaders;
|
||||
|
||||
std::unordered_map<std::string, std::type_index> m_official_types;
|
||||
|
||||
std::unordered_map<std::string, SamplerType> m_official_sampler_types;
|
||||
|
||||
std::unordered_map<std::string, std::function<void(SPUniformAssigner*)> >
|
||||
@ -114,10 +109,6 @@ private:
|
||||
const UniformAssigners& ua,
|
||||
bool skinned);
|
||||
// ------------------------------------------------------------------------
|
||||
static void addUniformsToShader(SPShader* s,
|
||||
const std::vector<std::pair<std::string, std::type_index> >& u,
|
||||
RenderPass rp);
|
||||
// ------------------------------------------------------------------------
|
||||
static void addPrefilledTexturesToShader(SPShader* s,
|
||||
const std::vector<std::tuple<std::string, std::string, bool,
|
||||
SamplerType> >& t, RenderPass rp);
|
||||
|
@ -84,17 +84,6 @@ public:
|
||||
#ifndef SERVER_ONLY
|
||||
glUniform4f(m_location, v[0], v[1], v[2], v[3]);
|
||||
m_assigned = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setValue(const irr::video::SColorf& col) const
|
||||
{
|
||||
if (rumtimeChecking(typeid(col)))
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
glUniform3f(m_location, col.r, col.g, col.b);
|
||||
m_assigned = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -117,17 +106,6 @@ public:
|
||||
#ifndef SERVER_ONLY
|
||||
glUniform2f(m_location, v.X, v.Y);
|
||||
m_assigned = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setValue(const irr::core::dimension2df& v) const
|
||||
{
|
||||
if (rumtimeChecking(typeid(v)))
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
glUniform2f(m_location, v.Width, v.Height);
|
||||
m_assigned = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -160,37 +138,31 @@ public:
|
||||
{
|
||||
m_assigned = false;
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_type == typeid(irr::core::matrix4))
|
||||
if (m_type == typeid(int))
|
||||
{
|
||||
static const char zeroes[64] = {};
|
||||
glUniformMatrix4fv(m_location, 1, GL_FALSE, (float*)zeroes);
|
||||
}
|
||||
else if (m_type == typeid(irr::video::SColor))
|
||||
{
|
||||
glUniform4i(m_location, 0, 0, 0, 0);
|
||||
}
|
||||
else if (m_type == typeid(irr::video::SColorf) ||
|
||||
m_type == typeid(irr::core::vector3df))
|
||||
{
|
||||
glUniform3f(m_location, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
else if (m_type == typeid(irr::core::vector2df) ||
|
||||
m_type == typeid(irr::core::dimension2df))
|
||||
{
|
||||
glUniform2f(m_location, 0.0f, 0.0f);
|
||||
glUniform1i(m_location, 0);
|
||||
}
|
||||
else if (m_type == typeid(float))
|
||||
{
|
||||
glUniform1f(m_location, 0.0f);
|
||||
}
|
||||
else if (m_type == typeid(int))
|
||||
else if (m_type == typeid(irr::core::matrix4))
|
||||
{
|
||||
glUniform1i(m_location, 0);
|
||||
static const char zeroes[64] = {};
|
||||
glUniformMatrix4fv(m_location, 1, GL_FALSE, (float*)zeroes);
|
||||
}
|
||||
else if (m_type == typeid(std::array<float, 4>))
|
||||
{
|
||||
glUniform4f(m_location, 0.0f, 0.0f, 0.0f,0.0f);
|
||||
}
|
||||
else if (m_type == typeid(irr::core::vector3df))
|
||||
{
|
||||
glUniform3f(m_location, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
else if (m_type == typeid(irr::core::vector2df))
|
||||
{
|
||||
glUniform2f(m_location, 0.0f, 0.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user