This commit is contained in:
samuncle 2014-08-13 21:32:12 +02:00
commit a91bcfa746
7 changed files with 97 additions and 191 deletions

View File

@ -1,11 +1,12 @@
in vec2 quadcorner;
in vec2 texcoord;
in vec3 position;
in float lifetime;
in float size;
layout(location=0) in vec3 Position;
layout(location = 1) in float lifetime;
layout(location = 2) in float size;
in vec3 rotationvec;
in float anglespeed;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 quadcorner;
layout(location = 5) in vec3 rotationvec;
layout(location = 6) in float anglespeed;
out float lf;
out vec2 tc;
@ -13,9 +14,9 @@ out vec3 pc;
void main(void)
{
tc = texcoord;
tc = Texcoord;
lf = lifetime;
vec3 newposition = position;
vec3 newposition = Position;
// from http://jeux.developpez.com/faq/math
float angle = lf * anglespeed;

View File

@ -7,17 +7,16 @@ in vec2 tc;
in vec3 pc;
out vec4 FragColor;
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main(void)
{
vec2 xy = gl_FragCoord.xy / screen;
float FragZ = gl_FragCoord.z;
float EnvZ = texture(dtex, xy).x;
vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.);
FragmentPos /= FragmentPos.w;
vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.);
EnvPos /= EnvPos.w;
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
vec2 xy = gl_FragCoord.xy / screen;
float FragZ = gl_FragCoord.z;
vec4 FragmentPos = getPosFromUVDepth(vec3(xy, FragZ), InverseProjectionMatrix);
float EnvZ = texture(dtex, xy).x;
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), InverseProjectionMatrix);
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
vec4 color = texture(tex, tc) * vec4(pc, 1.0);
FragColor = color * alpha * smoothstep(1., 0.8, lf);
}

View File

@ -1,11 +1,12 @@
uniform vec3 color_from;
uniform vec3 color_to;
in vec2 quadcorner;
in vec2 texcoord;
in vec3 position;
in float lifetime;
in float size;
layout(location=0) in vec3 Position;
layout(location = 1) in float lifetime;
layout(location = 2) in float size;
layout(location=3) in vec2 Texcoord;
layout(location = 4) in vec2 quadcorner;
out float lf;
out vec2 tc;
@ -13,12 +14,12 @@ out vec3 pc;
void main(void)
{
tc = texcoord;
lf = lifetime;
tc = Texcoord;
lf = lifetime;
pc = color_from + (color_to - color_from) * lifetime;
vec3 newposition = position;
vec3 newposition = Position;
vec4 viewpos = ViewMatrix * vec4(newposition, 1.0);
viewpos += size * vec4(quadcorner, 0., 0.);
gl_Position = ProjectionMatrix * viewpos;
viewpos += size * vec4(quadcorner, 0., 0.);
gl_Position = ProjectionMatrix * viewpos;
}

View File

@ -24,8 +24,6 @@ scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode(
return node;
}
GLuint ParticleSystemProxy::quad_vertex_buffer = 0;
ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
const core::vector3df& position,
@ -54,19 +52,6 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
track_x_len = 0;
track_z_len = 0;
texture = 0;
if (quad_vertex_buffer)
return;
static const GLfloat quad_vertex[] = {
-.5, -.5, 0., 0.,
.5, -.5, 1., 0.,
-.5, .5, 0., 1.,
.5, .5, 1., 1.,
};
glGenBuffers(1, &quad_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex), quad_vertex, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
ParticleSystemProxy::~ParticleSystemProxy()
@ -261,44 +246,38 @@ static bool isGPUParticleType(scene::E_PARTICLE_EMITTER_TYPE type)
}
}
template<typename T>
void setPositionQuadAttributes(GLuint quad_vbo, GLuint position_vbo)
void ParticleSystemProxy::SimpleParticleVAOBind(GLuint PositionBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
glEnableVertexAttribArray(T::attrib_quadcorner);
glVertexAttribPointer(T::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glEnableVertexAttribArray(T::attrib_texcoord);
glVertexAttribPointer(T::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, SharedObject::ParticleQuadVBO);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, position_vbo);
glEnableVertexAttribArray(T::attrib_pos);
glVertexAttribPointer(T::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
glVertexAttribDivisor(T::attrib_pos, 1);
glEnableVertexAttribArray(T::attrib_lf);
glVertexAttribPointer(T::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
glVertexAttribDivisor(T::attrib_lf, 1);
glEnableVertexAttribArray(T::attrib_sz);
glVertexAttribPointer(T::attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float)));
glVertexAttribDivisor(T::attrib_sz, 1);
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
glVertexAttribDivisor(0, 1);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
glVertexAttribDivisor(1, 1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float)));
glVertexAttribDivisor(2, 1);
}
void ParticleSystemProxy::FlipParticleVAOBind(GLuint PositionBuffer, GLuint QuaternionBuffer)
{
setPositionQuadAttributes<ParticleShader::FlipParticleRender>(quad_vertex_buffer, PositionBuffer);
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_rotationvec);
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_anglespeed);
SimpleParticleVAOBind(PositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, QuaternionBuffer);
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_rotationvec, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_anglespeed, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float)));
glEnableVertexAttribArray(5);
glVertexAttribDivisor(ParticleShader::FlipParticleRender::attrib_rotationvec, 1);
glVertexAttribDivisor(ParticleShader::FlipParticleRender::attrib_anglespeed, 1);
}
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glVertexAttribDivisor(5, 1);
void ParticleSystemProxy::SimpleParticleVAOBind(GLuint PositionBuffer)
{
setPositionQuadAttributes<ParticleShader::SimpleParticleRender>(quad_vertex_buffer, PositionBuffer);
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float)));
glVertexAttribDivisor(6, 1);
}
template<typename T>
@ -442,17 +421,12 @@ void ParticleSystemProxy::simulate()
void ParticleSystemProxy::drawFlip()
{
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(ParticleShader::FlipParticleRender::Program);
glUseProgram(ParticleShader::FlipParticleRender::getInstance()->Program);
float screen[2] = {
(float)UserConfigParams::m_width,
(float)UserConfigParams::m_height
};
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(ParticleShader::FlipParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::FlipParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1);
ParticleShader::FlipParticleRender::getInstance()->setUniforms();
glBindVertexArray(current_rendering_vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
@ -464,18 +438,14 @@ void ParticleSystemProxy::drawNotFlip()
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(ParticleShader::SimpleParticleRender::Program);
glUseProgram(ParticleShader::SimpleParticleRender::getInstance()->Program);
float screen[2] = {
(float)UserConfigParams::m_width,
(float)UserConfigParams::m_height
};
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_tex, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(ParticleShader::SimpleParticleRender::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]);
video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]);
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::SimpleParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(),
irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1, this);
ParticleShader::SimpleParticleRender::getInstance()->setUniforms(ColorFrom, ColorTo);
glBindVertexArray(current_rendering_vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);

View File

@ -20,8 +20,6 @@ protected:
float m_color_from[3];
float m_color_to[3];
static GLuint quad_vertex_buffer;
GLuint texture;
unsigned count;
static void SimpleParticleVAOBind(GLuint PositionBuffer);

View File

@ -298,6 +298,22 @@ static void initShadowVPMUBO()
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
GLuint SharedObject::ParticleQuadVBO = 0;
static void initParticleQuadVBO()
{
static const GLfloat quad_vertex[] = {
-.5, -.5, 0., 0.,
.5, -.5, 1., 0.,
-.5, .5, 0., 1.,
.5, .5, 1., 1.,
};
glGenBuffers(1, &SharedObject::ParticleQuadVBO);
glBindBuffer(GL_ARRAY_BUFFER, SharedObject::ParticleQuadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex), quad_vertex, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Shaders::loadShaders()
{
const std::string &dir = file_manager->getAsset(FileManager::SHADER, "");
@ -392,14 +408,13 @@ void Shaders::loadShaders()
initCubeVBO();
initFrustrumVBO();
initShadowVPMUBO();
initParticleQuadVBO();
FullScreenShader::DiffuseEnvMapShader::init();
MeshShader::BubbleShader::init();
LightShader::PointLightShader::init();
MeshShader::SkyboxShader::init();
MeshShader::ViewFrustrumShader::init();
ParticleShader::FlipParticleRender::init();
ParticleShader::HeightmapSimulationShader::init();
ParticleShader::SimpleParticleRender::init();
ParticleShader::SimpleSimulationShader::init();
UtilShader::ColoredLine::init();
}
@ -1451,100 +1466,30 @@ namespace ParticleShader
uniform_track_z_len = glGetUniformLocation(Program, "track_z_len");
}
GLuint SimpleParticleRender::Program;
GLuint SimpleParticleRender::attrib_pos;
GLuint SimpleParticleRender::attrib_lf;
GLuint SimpleParticleRender::attrib_quadcorner;
GLuint SimpleParticleRender::attrib_texcoord;
GLuint SimpleParticleRender::attrib_sz;
GLuint SimpleParticleRender::uniform_matrix;
GLuint SimpleParticleRender::uniform_viewmatrix;
GLuint SimpleParticleRender::uniform_tex;
GLuint SimpleParticleRender::uniform_dtex;
GLuint SimpleParticleRender::uniform_invproj;
GLuint SimpleParticleRender::uniform_color_from;
GLuint SimpleParticleRender::uniform_color_to;
void SimpleParticleRender::init()
SimpleParticleRender::SimpleParticleRender()
{
Program = LoadProgram(
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());
attrib_pos = glGetAttribLocation(Program, "position");
attrib_sz = glGetAttribLocation(Program, "size");
attrib_lf = glGetAttribLocation(Program, "lifetime");
attrib_quadcorner = glGetAttribLocation(Program, "quadcorner");
attrib_texcoord = glGetAttribLocation(Program, "texcoord");
AssignUniforms("color_from", "color_to");
uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix");
uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_invproj = glGetUniformLocation(Program, "invproj");
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_color_from = glGetUniformLocation(Program, "color_from");
assert(uniform_color_from != -1);
uniform_color_to = glGetUniformLocation(Program, "color_to");
assert(uniform_color_to != -1);
TU_tex = 0;
TU_dtex = 1;
AssignTextureUnit(Program, TexUnit(TU_tex, "tex"), TexUnit(TU_dtex, "dtex"));
}
void SimpleParticleRender::setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix,
const core::matrix4 InvProjMatrix, float width, float height, unsigned TU_tex, unsigned TU_dtex,
const ParticleSystemProxy* particle_system)
{
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProjMatrix.pointer());
glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer());
glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());
glUniform1i(uniform_tex, TU_tex);
glUniform1i(uniform_dtex, TU_dtex);
const float* color_from = particle_system->getColorFrom();
const float* color_to = particle_system->getColorTo();
glUniform3f(uniform_color_from, color_from[0], color_from[1], color_from[2]);
glUniform3f(uniform_color_to, color_to[0], color_to[1], color_to[2]);
}
GLuint FlipParticleRender::Program;
GLuint FlipParticleRender::attrib_pos;
GLuint FlipParticleRender::attrib_lf;
GLuint FlipParticleRender::attrib_quadcorner;
GLuint FlipParticleRender::attrib_texcoord;
GLuint FlipParticleRender::attrib_sz;
GLuint FlipParticleRender::attrib_rotationvec;
GLuint FlipParticleRender::attrib_anglespeed;
GLuint FlipParticleRender::uniform_matrix;
GLuint FlipParticleRender::uniform_viewmatrix;
GLuint FlipParticleRender::uniform_tex;
GLuint FlipParticleRender::uniform_dtex;
GLuint FlipParticleRender::uniform_invproj;
void FlipParticleRender::init()
FlipParticleRender::FlipParticleRender()
{
Program = LoadProgram(
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());
attrib_pos = glGetAttribLocation(Program, "position");
attrib_sz = glGetAttribLocation(Program, "size");
attrib_lf = glGetAttribLocation(Program, "lifetime");
attrib_quadcorner = glGetAttribLocation(Program, "quadcorner");
attrib_texcoord = glGetAttribLocation(Program, "texcoord");
attrib_anglespeed = glGetAttribLocation(Program, "anglespeed");
attrib_rotationvec = glGetAttribLocation(Program, "rotationvec");
AssignUniforms();
uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix");
uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_invproj = glGetUniformLocation(Program, "invproj");
uniform_dtex = glGetUniformLocation(Program, "dtex");
}
void FlipParticleRender::setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix, const core::matrix4 InvProjMatrix, float width, float height, unsigned TU_tex, unsigned TU_dtex)
{
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProjMatrix.pointer());
glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer());
glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());
glUniform1i(uniform_tex, TU_tex);
glUniform1i(uniform_dtex, TU_dtex);
TU_tex = 0;
TU_dtex = 1;
AssignTextureUnit(Program, TexUnit(TU_tex, "tex"), TexUnit(TU_dtex, "dtex"));
}
}

View File

@ -31,7 +31,7 @@ class SharedObject
{
public:
static GLuint billboardvbo;
static GLuint cubevbo, cubeindexes, frustrumvbo, frustrumindexes;
static GLuint cubevbo, cubeindexes, frustrumvbo, frustrumindexes, ParticleQuadVBO;
static GLuint ViewProjectionMatrixesUBO;
static GLuint FullScreenQuadVAO;
static GLuint UIVAO;
@ -509,28 +509,20 @@ public:
static void init();
};
class SimpleParticleRender
class SimpleParticleRender : public ShaderHelperSingleton<SimpleParticleRender, video::SColorf, video::SColorf>
{
public:
static GLuint Program;
static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz;
static GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_dtex, uniform_invproj, uniform_color_from, uniform_color_to;
GLuint TU_tex, TU_dtex;
static void init();
static void setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix,
const core::matrix4 InvProjMatrix, float width, float height, unsigned TU_tex,
unsigned TU_normal_and_depth, const ParticleSystemProxy* particle_system);
SimpleParticleRender();
};
class FlipParticleRender
class FlipParticleRender : public ShaderHelperSingleton<FlipParticleRender>
{
public:
static GLuint Program;
static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz, attrib_rotationvec, attrib_anglespeed;
static GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_dtex, uniform_invproj;
GLuint TU_tex, TU_dtex;
static void init();
static void setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix, const core::matrix4 InvProjMatrix, float width, float height, unsigned TU_tex, unsigned TU_normal_and_depth);
FlipParticleRender();
};
}