Started refactoring of shaders to follow our coding style.
One transform feedback buffer shader in particles is done.
This commit is contained in:
parent
959c86d816
commit
262fc0c373
@ -17,6 +17,7 @@
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/shaders_util.hpp"
|
||||
#include "gpuparticles.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
@ -386,15 +387,15 @@ void ParticleSystemProxy::simulate()
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
if (has_height_map)
|
||||
{
|
||||
glUseProgram(ParticleShader::HeightmapSimulationShader::getInstance()->Program);
|
||||
glActiveTexture(GL_TEXTURE0 + ParticleShader::HeightmapSimulationShader::getInstance()->TU_heightmap);
|
||||
glUseProgram(HeightmapSimulationShader::getInstance()->Program);
|
||||
glActiveTexture(GL_TEXTURE0 + HeightmapSimulationShader::getInstance()->TU_heightmap);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture);
|
||||
ParticleShader::HeightmapSimulationShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor, track_x, track_x_len, track_z, track_z_len);
|
||||
HeightmapSimulationShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor, track_x, track_x_len, track_z, track_z_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUseProgram(ParticleShader::SimpleSimulationShader::getInstance()->Program);
|
||||
ParticleShader::SimpleSimulationShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor);
|
||||
PointEmitterShader::getInstance()->use();
|
||||
PointEmitterShader::getInstance()->setUniforms(matrix, timediff, active_count, size_increase_factor);
|
||||
}
|
||||
|
||||
glBindVertexArray(current_simulation_vao);
|
||||
@ -432,10 +433,10 @@ void ParticleSystemProxy::simulate()
|
||||
void ParticleSystemProxy::drawFlip()
|
||||
{
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glUseProgram(ParticleShader::FlipParticleRender::getInstance()->Program);
|
||||
glUseProgram(FlipParticleRender::getInstance()->Program);
|
||||
|
||||
ParticleShader::FlipParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture());
|
||||
ParticleShader::FlipParticleRender::getInstance()->setUniforms();
|
||||
FlipParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture());
|
||||
FlipParticleRender::getInstance()->setUniforms();
|
||||
|
||||
glBindVertexArray(current_rendering_vao);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, m_count);
|
||||
@ -447,13 +448,13 @@ void ParticleSystemProxy::drawNotFlip()
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
else
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(ParticleShader::SimpleParticleRender::getInstance()->Program);
|
||||
glUseProgram(SimpleParticleRender::getInstance()->Program);
|
||||
|
||||
ParticleShader::SimpleParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture());
|
||||
SimpleParticleRender::getInstance()->SetTextureUnits(texture, irr_driver->getDepthStencilTexture());
|
||||
video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]);
|
||||
video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]);
|
||||
|
||||
ParticleShader::SimpleParticleRender::getInstance()->setUniforms(ColorFrom, ColorTo);
|
||||
SimpleParticleRender::getInstance()->setUniforms(ColorFrom, ColorTo);
|
||||
|
||||
glBindVertexArray(current_rendering_vao);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, m_count);
|
||||
@ -534,3 +535,97 @@ 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");
|
||||
}
|
||||
|
||||
|
||||
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",
|
||||
};
|
||||
Program = LoadTFBProgram(file_manager->getAsset("shaders/particlesimheightmap.vert").c_str(), varyings, 4);
|
||||
TU_heightmap = 2;
|
||||
AssignTextureUnit(Program, TexUnit(TU_heightmap, "heightmap"));
|
||||
AssignUniforms("sourcematrix", "dt", "level", "size_increase_factor", "track_x", "track_x_len", "track_z", "track_z_len");
|
||||
}
|
||||
|
||||
SimpleParticleRender::SimpleParticleRender()
|
||||
{
|
||||
Program = LoadProgram(PARTICLES_RENDERING,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/particle.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/particle.frag").c_str());
|
||||
AssignUniforms("color_from", "color_to");
|
||||
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "dtex");
|
||||
}
|
||||
|
||||
FlipParticleRender::FlipParticleRender()
|
||||
{
|
||||
Program = LoadProgram(PARTICLES_RENDERING,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/flipparticle.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/particle.frag").c_str());
|
||||
AssignUniforms();
|
||||
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "dtex");
|
||||
}
|
||||
|
@ -15,13 +15,45 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef GPUPARTICLES_H
|
||||
#define GPUPARTICLES_H
|
||||
#ifndef HEADER_GPU_PARTICLES_HPP
|
||||
#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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class HeightmapSimulationShader : public ShaderHelperSingleton<HeightmapSimulationShader, core::matrix4, int, int, float, float, float, float, float>
|
||||
{
|
||||
public:
|
||||
GLuint TU_heightmap;
|
||||
|
||||
HeightmapSimulationShader();
|
||||
};
|
||||
|
||||
class SimpleParticleRender : public ShaderHelperSingleton<SimpleParticleRender, video::SColorf, video::SColorf>, public TextureRead<Trilinear_Anisotropic_Filtered, Nearest_Filtered>
|
||||
{
|
||||
public:
|
||||
SimpleParticleRender();
|
||||
};
|
||||
|
||||
class FlipParticleRender : public ShaderHelperSingleton<FlipParticleRender>, public TextureRead<Trilinear_Anisotropic_Filtered, Nearest_Filtered>
|
||||
{
|
||||
public:
|
||||
FlipParticleRender();
|
||||
};
|
||||
|
||||
|
||||
namespace irr { namespace video{ class ITexture; } }
|
||||
|
||||
class ParticleSystemProxy : public scene::CParticleSystemSceneNode
|
||||
|
200
src/graphics/shader.cpp
Normal file
200
src/graphics/shader.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2014-2015 SuperTuxKart-Team
|
||||
// (C) 2015 Joerg Henrichs
|
||||
//
|
||||
// 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/shader.hpp"
|
||||
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
std::string ShaderBase::m_shader_header = "";
|
||||
std::vector<ShaderBase *> ShaderBase::m_all_shaders;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a string with the content of header.txt (which contains basic
|
||||
* shader defines).
|
||||
*/
|
||||
const std::string& ShaderBase::getHeader()
|
||||
{
|
||||
// Only read file first time
|
||||
if (m_shader_header.empty())
|
||||
{
|
||||
std::ifstream stream(file_manager->getShader("header.txt"), std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string line = "";
|
||||
while (getline(stream, line))
|
||||
m_shader_header += "\n" + line;
|
||||
stream.close();
|
||||
}
|
||||
} // if m_shader_header.empty()
|
||||
|
||||
return m_shader_header;
|
||||
} // getHeader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a single shader.
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
|
||||
{
|
||||
GLuint id = glCreateShader(type);
|
||||
|
||||
std::ostringstream code;
|
||||
code << "#version " << CVS->getGLSLVersion()<<"\n";
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
code << "#extension GL_ARB_bindless_texture : enable\n";
|
||||
code << "#define Use_Bindless_Texture\n";
|
||||
}
|
||||
code << "//" + std::string(file) + "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#define VSLayer\n";
|
||||
if (CVS->needsRGBBindlessWorkaround())
|
||||
code << "#define SRGBBindlessFix\n";
|
||||
code << getHeader();
|
||||
|
||||
std::ifstream stream(file, std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(stream, Line))
|
||||
code << "\n" + Line;
|
||||
stream.close();
|
||||
}
|
||||
else
|
||||
Log::error("shader", "Can not open '%s'.", file.c_str());
|
||||
|
||||
Log::info("shader", "Compiling shader : %s", file);
|
||||
const std::string &source = code.str();
|
||||
char const *source_pointer = source.c_str();
|
||||
int len = source.size();
|
||||
glShaderSource(id, 1, &source_pointer, &len);
|
||||
glCompileShader(id);
|
||||
|
||||
GLint result = GL_FALSE;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
int info_length;
|
||||
Log::error("GLWrap", "Error in shader %s", file);
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_length);
|
||||
if (info_length<0)
|
||||
info_length = 1024;
|
||||
char *error_message = new char[info_length];
|
||||
error_message[0] = 0;
|
||||
glGetShaderInfoLog(id, info_length, NULL, error_message);
|
||||
Log::error("GLWrap", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return id;
|
||||
} // loadShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a transform feedback buffer shader with a given number of varying
|
||||
* parameters.
|
||||
*/
|
||||
int ShaderBase::loadTFBProgram(const std::string &shader_name,
|
||||
const char **varyings,
|
||||
unsigned varying_count)
|
||||
{
|
||||
std::string full_path = file_manager->getShader(shader_name);
|
||||
m_program = glCreateProgram();
|
||||
loadAndAttachShader(GL_VERTEX_SHADER, full_path);
|
||||
if (CVS->getGLSLVersion() < 330)
|
||||
setAttribute(PARTICLES_SIM);
|
||||
|
||||
glTransformFeedbackVaryings(m_program, varying_count, varyings,
|
||||
GL_INTERLEAVED_ATTRIBS);
|
||||
glLinkProgram(m_program);
|
||||
|
||||
GLint result = GL_FALSE;
|
||||
glGetProgramiv(m_program, GL_LINK_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
int info_log_length;
|
||||
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
char *error_message = new char[info_log_length];
|
||||
glGetProgramInfoLog(m_program, info_log_length, NULL, error_message);
|
||||
Log::error("GLWrap", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return m_program;
|
||||
} // loadTFBProgram
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
ShaderBase::ShaderBase()
|
||||
{
|
||||
m_all_shaders.push_back(this);
|
||||
} // ShaderBase
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ShaderBase::setAttribute(AttributeType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OBJECT:
|
||||
glBindAttribLocation(m_program, 0, "Position");
|
||||
glBindAttribLocation(m_program, 1, "Normal");
|
||||
glBindAttribLocation(m_program, 2, "Color");
|
||||
glBindAttribLocation(m_program, 3, "Texcoord");
|
||||
glBindAttribLocation(m_program, 4, "SecondTexcoord");
|
||||
glBindAttribLocation(m_program, 5, "Tangent");
|
||||
glBindAttribLocation(m_program, 6, "Bitangent");
|
||||
glBindAttribLocation(m_program, 7, "Origin");
|
||||
glBindAttribLocation(m_program, 8, "Orientation");
|
||||
glBindAttribLocation(m_program, 9, "Scale");
|
||||
break;
|
||||
case PARTICLES_SIM:
|
||||
glBindAttribLocation(m_program, 0, "particle_position");
|
||||
glBindAttribLocation(m_program, 1, "lifetime");
|
||||
glBindAttribLocation(m_program, 2, "particle_velocity");
|
||||
glBindAttribLocation(m_program, 3, "size");
|
||||
glBindAttribLocation(m_program, 4, "particle_position_initial");
|
||||
glBindAttribLocation(m_program, 5, "lifetime_initial");
|
||||
glBindAttribLocation(m_program, 6, "particle_velocity_initial");
|
||||
glBindAttribLocation(m_program, 7, "size_initial");
|
||||
break;
|
||||
case PARTICLES_RENDERING:
|
||||
glBindAttribLocation(m_program, 1, "lifetime");
|
||||
glBindAttribLocation(m_program, 2, "size");
|
||||
glBindAttribLocation(m_program, 4, "quadcorner");
|
||||
glBindAttribLocation(m_program, 5, "rotationvec");
|
||||
glBindAttribLocation(m_program, 6, "anglespeed");
|
||||
break;
|
||||
}
|
||||
} // setAttribute
|
||||
|
||||
// ============================================================================
|
228
src/graphics/shader.hpp
Normal file
228
src/graphics/shader.hpp
Normal file
@ -0,0 +1,228 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2014-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_SHADER_HPP
|
||||
#define HEADER_SHADER_HPP
|
||||
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
#include <matrix4.h>
|
||||
#include <SColor.h>
|
||||
#include <vector3d.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ShaderBase
|
||||
{
|
||||
private:
|
||||
// Static members
|
||||
/** Stores the context of header.txt, to avoid reading
|
||||
* this file repeatedly. */
|
||||
static std::string m_shader_header;
|
||||
|
||||
/** Maintains a list of all shaders. */
|
||||
static std::vector<ShaderBase *> m_all_shaders;
|
||||
|
||||
enum AttributeType
|
||||
{
|
||||
OBJECT,
|
||||
PARTICLES_SIM,
|
||||
PARTICLES_RENDERING,
|
||||
};
|
||||
|
||||
protected:
|
||||
/** OpenGL's program id. */
|
||||
GLuint m_program;
|
||||
|
||||
private:
|
||||
// ------------------------------------------------------------------------
|
||||
// Ends vararg template
|
||||
template<typename ... Types>
|
||||
void loadAndAttachShader(GLint ProgramID)
|
||||
{
|
||||
return;
|
||||
} // loadAndAttachShader
|
||||
// ------------------------------------------------------------------------
|
||||
template<typename ... Types>
|
||||
void loadAndAttachShader(GLint shader_type, const std::string &name,
|
||||
Types ... args)
|
||||
{
|
||||
GLint shader_id = loadShader(name, shader_type);
|
||||
glAttachShader(m_program, shader_id);
|
||||
glDeleteShader(shader_id);
|
||||
loadAndAttachShader(shader_type, args...);
|
||||
} // loadAndAttachShader
|
||||
|
||||
const std::string& getHeader();
|
||||
|
||||
GLuint loadShader(const std::string &file, unsigned type);
|
||||
void setAttribute(AttributeType type);
|
||||
|
||||
public:
|
||||
ShaderBase();
|
||||
int loadTFBProgram(const std::string &vertex_file_path,
|
||||
const char **varyings,
|
||||
unsigned varyingscount);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Activates the shader calling glUseProgram. */
|
||||
void use() { glUseProgram(m_program); }
|
||||
}; // ShaderBase
|
||||
|
||||
// ============================================================================
|
||||
template<typename T, typename... Args>
|
||||
class Shader : public ShaderBase, public Singleton<T>
|
||||
{
|
||||
private:
|
||||
std::vector<GLuint> m_uniforms;
|
||||
|
||||
/** Finds the specified uniform block and assigns a binding point to it. */
|
||||
void bindPoint(const char *name, int index)
|
||||
{
|
||||
GLuint block_index = glGetUniformBlockIndex(m_program, name);
|
||||
if (block_index != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(m_program, block_index, index);
|
||||
} // bindPoint
|
||||
// ------------------------------------------------------------------------
|
||||
/** End of recursive implementation of assignUniforms. */
|
||||
void assignUniformsImpl()
|
||||
{
|
||||
bindPoint("MatrixData", 0);
|
||||
bindPoint("LightingData", 1);
|
||||
} // assignUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Recursive implementation of assignniforms. It collects the unfirom
|
||||
* locations in m_uniform, then recursing.
|
||||
* \param name Name of the uniform.
|
||||
*/
|
||||
template<typename... U>
|
||||
void assignUniformsImpl(const char* name, U... rest)
|
||||
{
|
||||
m_uniforms.push_back(glGetUniformLocation(m_program, name));
|
||||
assignUniformsImpl(rest...);
|
||||
} // assignUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** End of recursion for setUniforms implementation.
|
||||
*/
|
||||
template<unsigned N = 0>
|
||||
void setUniformsImpl() const
|
||||
{
|
||||
} // setUniformImpl
|
||||
// ------------------------------------------------------------------------
|
||||
/** Implementation for setUniforms for a matrix uniform. */
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::core::matrix4 &mat, Args... arg) const
|
||||
{
|
||||
glUniformMatrix4fv(m_uniforms[N], 1, GL_FALSE, mat.pointer());
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::video::SColorf &col, Args... arg) const
|
||||
{
|
||||
glUniform3f(m_uniforms[N], col.r, col.g, col.b);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::video::SColor &col, Args... arg) const
|
||||
{
|
||||
glUniform4i(m_uniforms[N], col.getRed(), c ol.getGreen(),
|
||||
col.getBlue(), col.getAlpha());
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::core::vector3df &v, Args... arg) const
|
||||
{
|
||||
glUniform3f(m_uniforms[N], v.X, v.Y, v.Z);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::core::vector2df &v, Args... arg) const
|
||||
{
|
||||
glUniform2f(m_uniforms[N], v.X, v.Y);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const irr::core::dimension2df &v, Args... arg) const
|
||||
{
|
||||
glUniform2f(m_uniforms[N], v.Width, v.Height);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(float f, Args... arg) const
|
||||
{
|
||||
glUniform1f(m_uniforms[N], f);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(int f, Args... arg) const
|
||||
{
|
||||
glUniform1i(m_uniforms[N], f);
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<unsigned N = 0, typename... Args>
|
||||
void setUniformsImpl(const std::vector<float> &v, Args... arg) const
|
||||
{
|
||||
glUniform1fv(m_uniforms[N], (int)v.size(), v.data());
|
||||
setUniformsImpl<N + 1>(arg...);
|
||||
} // setUniformsImpl
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** This variadic template collects all names of uniforms in
|
||||
* a std::vector. */
|
||||
template<typename... U>
|
||||
void assignUniforms(U... rest)
|
||||
{
|
||||
static_assert(sizeof...(rest) == sizeof...(Args),
|
||||
"Count of Uniform's name mismatch");
|
||||
assignUniformsImpl(rest...);
|
||||
} // assignUniforms
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setUniforms(const Args & ... args) const
|
||||
{
|
||||
if (needsUBO())
|
||||
bypassUBO(m_program);
|
||||
setUniformsImpl(args...);
|
||||
}
|
||||
|
||||
|
||||
}; // Shader
|
||||
|
||||
// ============================================================================
|
||||
#endif
|
@ -1491,56 +1491,6 @@ namespace LightShader
|
||||
}
|
||||
|
||||
|
||||
namespace ParticleShader
|
||||
{
|
||||
SimpleSimulationShader::SimpleSimulationShader()
|
||||
{
|
||||
const char *varyings[] = {
|
||||
"new_particle_position",
|
||||
"new_lifetime",
|
||||
"new_particle_velocity",
|
||||
"new_size",
|
||||
};
|
||||
Program = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 4);
|
||||
AssignUniforms("sourcematrix", "dt", "level", "size_increase_factor");
|
||||
}
|
||||
|
||||
HeightmapSimulationShader::HeightmapSimulationShader()
|
||||
{
|
||||
const char *varyings[] = {
|
||||
"new_particle_position",
|
||||
"new_lifetime",
|
||||
"new_particle_velocity",
|
||||
"new_size",
|
||||
};
|
||||
Program = LoadTFBProgram(file_manager->getAsset("shaders/particlesimheightmap.vert").c_str(), varyings, 4);
|
||||
TU_heightmap = 2;
|
||||
AssignTextureUnit(Program, TexUnit(TU_heightmap, "heightmap"));
|
||||
AssignUniforms("sourcematrix", "dt", "level", "size_increase_factor", "track_x", "track_x_len", "track_z", "track_z_len");
|
||||
}
|
||||
|
||||
SimpleParticleRender::SimpleParticleRender()
|
||||
{
|
||||
Program = LoadProgram(PARTICLES_RENDERING,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/particle.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/particle.frag").c_str());
|
||||
AssignUniforms("color_from", "color_to");
|
||||
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "dtex");
|
||||
}
|
||||
|
||||
FlipParticleRender::FlipParticleRender()
|
||||
{
|
||||
Program = LoadProgram(PARTICLES_RENDERING,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/flipparticle.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/particle.frag").c_str());
|
||||
AssignUniforms();
|
||||
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "dtex");
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint createVAO(GLuint Program)
|
||||
{
|
||||
|
@ -339,37 +339,6 @@ namespace LightShader
|
||||
};
|
||||
}
|
||||
|
||||
namespace ParticleShader
|
||||
{
|
||||
|
||||
class SimpleSimulationShader : public ShaderHelperSingleton<SimpleSimulationShader, core::matrix4, int, int, float>
|
||||
{
|
||||
public:
|
||||
SimpleSimulationShader();
|
||||
};
|
||||
|
||||
|
||||
|
||||
class HeightmapSimulationShader : public ShaderHelperSingleton<HeightmapSimulationShader, core::matrix4, int, int, float, float, float, float, float>
|
||||
{
|
||||
public:
|
||||
GLuint TU_heightmap;
|
||||
|
||||
HeightmapSimulationShader();
|
||||
};
|
||||
|
||||
class SimpleParticleRender : public ShaderHelperSingleton<SimpleParticleRender, video::SColorf, video::SColorf>, public TextureRead<Trilinear_Anisotropic_Filtered, Nearest_Filtered>
|
||||
{
|
||||
public:
|
||||
SimpleParticleRender();
|
||||
};
|
||||
|
||||
class FlipParticleRender : public ShaderHelperSingleton<FlipParticleRender>, public TextureRead<Trilinear_Anisotropic_Filtered, Nearest_Filtered>
|
||||
{
|
||||
public:
|
||||
FlipParticleRender();
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void DrawFullScreenEffect(Args...args)
|
||||
|
@ -158,7 +158,16 @@ public:
|
||||
{
|
||||
m_music_search_path.push_back(path);
|
||||
} // pushMusicSearchPath
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the full path to a shader (this function could be modified
|
||||
* later to allow track-specific shaders).
|
||||
* \param name Name of the shader.
|
||||
*/
|
||||
std::string getShader(const std::string &name) const
|
||||
{
|
||||
return getAsset(SHADER, name);
|
||||
|
||||
} // getShader
|
||||
}; // FileManager
|
||||
|
||||
extern FileManager* file_manager;
|
||||
|
Loading…
Reference in New Issue
Block a user