From dc02eec7b6e83a1eb84020b81856b4d184586683 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 13 Aug 2014 21:04:03 +0200 Subject: [PATCH] Port particle rendering shaders too. --- data/shaders/flipparticle.vert | 19 +++---- data/shaders/particle.frag | 15 +++--- data/shaders/particle.vert | 21 ++++---- src/graphics/gpuparticles.cpp | 81 ++++++++++++---------------- src/graphics/shaders.cpp | 96 +++++----------------------------- src/graphics/shaders.hpp | 20 +++---- 6 files changed, 79 insertions(+), 173 deletions(-) diff --git a/data/shaders/flipparticle.vert b/data/shaders/flipparticle.vert index 4ef8cc68d..591d121af 100644 --- a/data/shaders/flipparticle.vert +++ b/data/shaders/flipparticle.vert @@ -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; diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index 54fca2871..dfe447838 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -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); } diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index dd8efbac2..99d38137c 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -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; } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 49a0494f6..c2c85e54b 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -261,44 +261,38 @@ static bool isGPUParticleType(scene::E_PARTICLE_EMITTER_TYPE type) } } -template -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, quad_vertex_buffer); + 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(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(quad_vertex_buffer, PositionBuffer); + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float))); + glVertexAttribDivisor(6, 1); } template @@ -442,17 +436,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 +453,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); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 321abf523..7c477bcf0 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -397,9 +397,7 @@ void Shaders::loadShaders() 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 +1449,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")); } } diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 639b13617..e6dda115b 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -509,28 +509,20 @@ public: static void init(); }; -class SimpleParticleRender +class SimpleParticleRender : public ShaderHelperSingleton { 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 { 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(); }; }