Moved AssignTextureUnit to new Shader base class.

This commit is contained in:
hiker 2015-04-25 00:57:53 +10:00
parent 118233fb24
commit 45d6c863b3
6 changed files with 157 additions and 193 deletions

View File

@ -28,6 +28,91 @@
#include "../../lib/irrlicht/source/Irrlicht/os.h"
#define COMPONENTCOUNT 8
// ============================================================================
/** Transform feedback shader that simulates the particles on GPU.
*/
class PointEmitterShader : public Shader
< PointEmitterShader, core::matrix4, int, int, float >
{
public:
PointEmitterShader()
{
const char *varyings[] = { "new_particle_position", "new_lifetime",
"new_particle_velocity", "new_size" };
loadTFBProgram("pointemitter.vert", varyings, 4);
assignUniforms("sourcematrix", "dt", "level", "size_increase_factor");
} // PointEmitterShader
}; // PointEmitterShader
// ============================================================================
/** A Shader to render particles.
*/
class SimpleParticleRender : public Shader<SimpleParticleRender, video::SColorf,
video::SColorf>,
public TextureRead<Trilinear_Anisotropic_Filtered,
Nearest_Filtered>
{
public:
SimpleParticleRender()
{
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "particle.vert",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "particle.frag");
assignUniforms("color_from", "color_to");
AssignSamplerNames(m_program, 0, "tex", 1, "dtex");
} // SimpleParticleRender
}; // SimpleParticleRender
// ============================================================================
class FlipParticleRender : public Shader<FlipParticleRender>,
public TextureRead < Trilinear_Anisotropic_Filtered,
Nearest_Filtered >
{
public:
FlipParticleRender()
{
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "flipparticle.vert",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "particle.frag");
assignUniforms();
AssignSamplerNames(m_program, 0, "tex", 1, "dtex");
}
}; // FlipParticleShader
// ============================================================================
/** */
class HeightmapSimulationShader : public Shader <HeightmapSimulationShader,
core::matrix4, int, int,
float,float,float,float,float>
{
public:
GLuint m_TU_heightmap;
HeightmapSimulationShader()
{
const char *varyings[] = {"new_particle_position", "new_lifetime",
"new_particle_velocity", "new_size" };
loadTFBProgram("particlesimheightmap.vert", varyings, 4);
assignUniforms("sourcematrix", "dt", "level", "size_increase_factor",
"track_x", "track_x_len", "track_z", "track_z_len");
m_TU_heightmap = 2;
assignTextureUnit(TexUnit(m_TU_heightmap, "heightmap"));
}
};
// ============================================================================
scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode(
bool withDefaultEmitter, bool randomize_initial_y, ISceneNode* parent, s32 id,
const core::vector3df& position,
@ -388,7 +473,7 @@ void ParticleSystemProxy::simulate()
if (has_height_map)
{
HeightmapSimulationShader::getInstance()->use();
glActiveTexture(GL_TEXTURE0 + HeightmapSimulationShader::getInstance()->TU_heightmap);
glActiveTexture(GL_TEXTURE0 + HeightmapSimulationShader::getInstance()->m_TU_heightmap);
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
HeightmapSimulationShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor, track_x, track_x_len, track_z, track_z_len);
}
@ -535,101 +620,3 @@ void ParticleSystemProxy::render() {
simulate();
draw();
}
// ============================================================================
PointEmitterShader::PointEmitterShader()
{
const char *varyings[] = {
"new_particle_position",
"new_lifetime",
"new_particle_velocity",
"new_size",
};
loadTFBProgram("pointemitter.vert", varyings, 4);
assignUniforms("sourcematrix", "dt", "level", "size_increase_factor");
} // PointEmitterShader
// ============================================================================
SimpleParticleRender::SimpleParticleRender()
{
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "particle.vert",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "particle.frag");
assignUniforms("color_from", "color_to");
AssignSamplerNames(m_program, 0, "tex", 1, "dtex");
} // SimpleParticleRender
// ============================================================================
struct TexUnit
{
GLuint m_index;
const char* m_uniform;
TexUnit(GLuint index, const char* uniform)
{
m_index = index;
m_uniform = uniform;
}
};
static void
AssignTextureUnit(GLuint Program, TexUnit texUnit)
{
glUseProgram(Program);
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
glUseProgram(0);
}
template<typename... T>
static void AssignTextureUnit(GLuint Program, TexUnit texUnit, T... rest)
{
glUseProgram(Program);
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
AssignTextureUnit_Sub(Program, rest...);
glUseProgram(0);
}
static void AssignTextureUnit_Sub(GLuint Program) {}
template<typename... T>
static void AssignTextureUnit_Sub(GLuint Program, TexUnit texUnit, T... rest)
{
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
AssignTextureUnit_Sub(Program, rest...);
}
HeightmapSimulationShader::HeightmapSimulationShader()
{
const char *varyings[] = {
"new_particle_position",
"new_lifetime",
"new_particle_velocity",
"new_size",
};
loadTFBProgram("particlesimheightmap.vert", varyings, 4);
TU_heightmap = 2;
AssignTextureUnit(m_program, TexUnit(TU_heightmap, "heightmap"));
assignUniforms("sourcematrix", "dt", "level", "size_increase_factor", "track_x", "track_x_len", "track_z", "track_z_len");
}
FlipParticleRender::FlipParticleRender()
{
loadProgram(PARTICLES_RENDERING,
GL_VERTEX_SHADER, "flipparticle.vert",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "particle.frag");
assignUniforms();
AssignSamplerNames(m_program, 0, "tex", 1, "dtex");
}

View File

@ -19,48 +19,16 @@
#define HEADER_GPU_PARTICLES_HPP
#include "graphics/shader.hpp"
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
#include <ISceneManager.h>
#include <IParticleSystemSceneNode.h>
class PointEmitterShader : public Shader
< PointEmitterShader, core::matrix4, int, int, float >
{
public:
PointEmitterShader();
}; // PointEmitterShader
// ============================================================================
class SimpleParticleRender : public Shader<SimpleParticleRender, video::SColorf,
video::SColorf>,
public TextureRead<Trilinear_Anisotropic_Filtered,
Nearest_Filtered>
{
public:
SimpleParticleRender();
}; // SimpleParticleRender
// ============================================================================
class HeightmapSimulationShader : public Shader<HeightmapSimulationShader, core::matrix4, int, int, float, float, float, float, float>
{
public:
GLuint TU_heightmap;
HeightmapSimulationShader();
};
class FlipParticleRender : public Shader<FlipParticleRender>, public TextureRead<Trilinear_Anisotropic_Filtered, Nearest_Filtered>
{
public:
FlipParticleRender();
};
namespace irr { namespace video{ class ITexture; } }
class ParticleSystemProxy : public scene::CParticleSystemSceneNode
{
protected:

View File

@ -754,7 +754,7 @@ void IrrDriver::renderNormalsVisualisation()
}
template<typename Shader, enum video::E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
void renderTransparenPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
{
Shader::getInstance()->use();
if (CVS->isARBBaseInstanceUsable())
@ -802,19 +802,19 @@ void IrrDriver::renderTransparent()
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderTransparenPass<MeshShader::TransparentFogShader, video::EVT_STANDARD, 8, 7, 6, 5, 4, 3, 2, 1>(TexUnits(
TexUnit(0, true)), ListBlendTransparentFog::getInstance());
RenderGeometry::TexUnit(0, true)), ListBlendTransparentFog::getInstance());
glBlendFunc(GL_ONE, GL_ONE);
renderTransparenPass<MeshShader::TransparentFogShader, video::EVT_STANDARD, 8, 7, 6, 5, 4, 3, 2, 1>(TexUnits(
TexUnit(0, true)), ListAdditiveTransparentFog::getInstance());
RenderGeometry::TexUnit(0, true)), ListAdditiveTransparentFog::getInstance());
}
else
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderTransparenPass<MeshShader::TransparentShader, video::EVT_STANDARD, 2, 1>(TexUnits(
TexUnit(0, true)), ListBlendTransparent::getInstance());
RenderGeometry::TexUnit(0, true)), ListBlendTransparent::getInstance());
glBlendFunc(GL_ONE, GL_ONE);
renderTransparenPass<MeshShader::TransparentShader, video::EVT_STANDARD, 2, 1>(TexUnits(
TexUnit(0, true)), ListAdditiveTransparent::getInstance());
RenderGeometry::TexUnit(0, true)), ListAdditiveTransparent::getInstance());
}
for (unsigned i = 0; i < BillBoardList::getInstance()->size(); i++)

View File

@ -238,6 +238,52 @@ private:
Log::error("shader", filepath);
printFileList(args...);
} // printFileList
protected:
/** Stores texture index and uniform. */
class TexUnit
{
public:
GLuint m_index;
const char* m_uniform;
TexUnit(GLuint index, const char* uniform)
{
m_index = index;
m_uniform = uniform;
} // TexUnit
}; // class TexUnit
// ========================================================================
void assignTextureUnit(TexUnit tex_unit)
{
glUseProgram(m_program);
GLuint uniform = glGetUniformLocation(m_program, tex_unit.m_uniform);
glUniform1i(uniform, tex_unit.m_index);
glUseProgram(0);
} // assignTextureUnit
// ------------------------------------------------------------------------
template<typename... T>
void assignTextureUnit(TexUnit tex_unit, T... rest)
{
glUseProgram(m_program);
GLuint uniform = glGetUniformLocation(m_program, tex_unit.m_uniform);
glUniform1i(uniform, tex_unit.m_index);
assignTextureUnitNoUse(rest...);
glUseProgram(0);
} // assignTextureUnit
// ------------------------------------------------------------------------
void assignTextureUnitNoUse() {}
// ------------------------------------------------------------------------
template<typename... T>
void assignTextureUnitNoUse(TexUnit tex_unit, T... rest)
{
GLuint uniform = glGetUniformLocation(m_program, tex_unit.m_uniform);
glUniform1i(uniform, tex_unit.m_index);
assignTextureUnitNoUse(rest...);
}
public:

View File

@ -57,7 +57,7 @@
\subsection shader_declaration_bind_texture_unit Bind texture unit and name
Texture are optional but if you have one, you must give them determined texture unit (up to 32).
You can do this using the AssignTextureUnit function that takes pair of texture unit and sampler name
You can do this using the assignTextureUnit function that takes pair of texture unit and sampler name
as argument.
\section shader_usage
@ -97,6 +97,7 @@
#include "graphics/irr_driver.hpp"
#include "graphics/gpuparticles.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shaders_util.hpp"
#include "io/file_manager.hpp"
#include "utils/log.hpp"
#include "graphics/glwrap.hpp"
@ -515,20 +516,9 @@ namespace UtilShader
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
struct TexUnit
{
GLuint m_index;
const char* m_uniform;
TexUnit(GLuint index, const char* uniform)
{
m_index = index;
m_uniform = uniform;
}
};
template <typename T>
std::vector<TexUnit> TexUnits(T curr) // required on older clang versions
std::vector<Shader::TexUnit> TexUnits(T curr) // required on older clang versions
{
std::vector<TexUnit> v;
v.push_back(curr);
@ -536,7 +526,7 @@ namespace UtilShader
}
template <typename T, typename... R>
std::vector<TexUnit> TexUnits(T curr, R... rest) // required on older clang versions
std::vector<Shader::TexUnit> TexUnits(T curr, R... rest) // required on older clang versions
{
std::vector<TexUnit> v;
v.push_back(curr);
@ -545,46 +535,18 @@ namespace UtilShader
}
template <typename T, typename... R>
void VTexUnits(std::vector<TexUnit>& v, T curr, R... rest) // required on older clang versions
void VTexUnits(std::vector<Shader::TexUnit>& v, T curr, R... rest) // required on older clang versions
{
v.push_back(curr);
VTexUnits(v, rest...);
}
template <typename T>
void VTexUnits(std::vector<TexUnit>& v, T curr)
void VTexUnits(std::vector<Shader::TexUnit>& v, T curr)
{
v.push_back(curr);
}
static void
AssignTextureUnit(GLuint Program, TexUnit texUnit)
{
glUseProgram(Program);
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
glUseProgram(0);
}
template<typename... T>
static void AssignTextureUnit(GLuint Program, TexUnit texUnit, T... rest)
{
glUseProgram(Program);
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
AssignTextureUnit_Sub(Program, rest...);
glUseProgram(0);
}
static void AssignTextureUnit_Sub(GLuint Program) {}
template<typename... T>
static void AssignTextureUnit_Sub(GLuint Program, TexUnit texUnit, T... rest)
{
GLuint uniform = glGetUniformLocation(Program, texUnit.m_uniform);
glUniform1i(uniform, texUnit.m_index);
AssignTextureUnit_Sub(Program, rest...);
}
}
using namespace UtilShader;
@ -829,7 +791,7 @@ namespace UtilShader
assignUniforms("PermutationMatrix", "ViewportSize");
TU_Samples = 1;
AssignSamplerNames(m_program, 0, "tex");
AssignTextureUnit(m_program, TexUnit(TU_Samples, "samples"));
assignTextureUnit(TexUnit(TU_Samples, "samples"));
}
}
@ -1614,7 +1576,7 @@ namespace FullScreenShader
TU_SHR = 0;
TU_SHG = 1;
TU_SHB = 2;
AssignTextureUnit(m_program, TexUnit(TU_SHR, "SHR"), TexUnit(TU_SHG, "SHG"), TexUnit(TU_SHB, "SHB"));
assignTextureUnit(TexUnit(TU_SHR, "SHR"), TexUnit(TU_SHG, "SHG"), TexUnit(TU_SHB, "SHB"));
}
GlobalIlluminationReconstructionShader::GlobalIlluminationReconstructionShader()
@ -1644,7 +1606,7 @@ namespace FullScreenShader
TU_dest = 2;
assignUniforms("pixel");
AssignSamplerNames(m_program, 0, "source", 1, "depth");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
ComputeGaussian6HBlurShader::ComputeGaussian6HBlurShader()
@ -1654,7 +1616,7 @@ namespace FullScreenShader
TU_dest = 1;
assignUniforms("pixel", "weights");
AssignSamplerNames(m_program, 0, "source");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
ComputeShadowBlurHShader::ComputeShadowBlurHShader()
@ -1664,7 +1626,7 @@ namespace FullScreenShader
TU_dest = 1;
assignUniforms("pixel", "weights");
AssignSamplerNames(m_program, 0, "source");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
Gaussian6HBlurShader::Gaussian6HBlurShader()
@ -1714,7 +1676,7 @@ namespace FullScreenShader
TU_dest = 2;
assignUniforms("pixel");
AssignSamplerNames(m_program, 0, "source", 1, "depth");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
ComputeGaussian6VBlurShader::ComputeGaussian6VBlurShader()
@ -1724,7 +1686,7 @@ namespace FullScreenShader
TU_dest = 1;
assignUniforms("pixel", "weights");
AssignSamplerNames(m_program, 0, "source");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
ComputeShadowBlurVShader::ComputeShadowBlurVShader()
@ -1734,7 +1696,7 @@ namespace FullScreenShader
TU_dest = 1;
assignUniforms("pixel", "weights");
AssignSamplerNames(m_program, 0, "source");
AssignTextureUnit(m_program, TexUnit(TU_dest, "dest"));
assignTextureUnit(TexUnit(TU_dest, "dest"));
}
Gaussian6VBlurShader::Gaussian6VBlurShader()
@ -1774,7 +1736,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, "layertexturequad.frag");
TU_texture = 0;
assignUniforms("layer");
AssignTextureUnit(m_program, TexUnit(TU_texture, "tex"));
assignTextureUnit(TexUnit(TU_texture, "tex"));
vao = createVAO(m_program);
}

View File

@ -369,6 +369,7 @@ protected:
std::vector<GLuint> TextureUnits;
std::vector<GLenum> TextureType;
std::vector<GLenum> TextureLocation;
public:
template<typename...Args>
void AssignSamplerNames(GLuint Program, Args...args)
{