Implement color variation in particle system
This commit is contained in:
parent
de820054b6
commit
0425cf2ef4
@ -5,6 +5,7 @@ uniform vec2 screen;
|
|||||||
|
|
||||||
in float lf;
|
in float lf;
|
||||||
in vec2 tc;
|
in vec2 tc;
|
||||||
|
in vec3 pc;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
|
||||||
@ -18,6 +19,6 @@ void main(void)
|
|||||||
vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.);
|
vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.);
|
||||||
EnvPos /= EnvPos.w;
|
EnvPos /= EnvPos.w;
|
||||||
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
||||||
color = texture(tex, tc);
|
color = texture(tex, tc) * vec4(pc, 1.0);
|
||||||
color.a *= alpha * smoothstep(1., 0.8, lf);
|
color.a *= alpha * smoothstep(1., 0.8, lf);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
uniform mat4 ProjectionMatrix;
|
uniform mat4 ProjectionMatrix;
|
||||||
uniform mat4 ViewMatrix;
|
uniform mat4 ViewMatrix;
|
||||||
|
uniform vec3 color_from;
|
||||||
|
uniform vec3 color_to;
|
||||||
|
|
||||||
in vec2 quadcorner;
|
in vec2 quadcorner;
|
||||||
in vec2 texcoord;
|
in vec2 texcoord;
|
||||||
@ -9,11 +11,13 @@ in float size;
|
|||||||
|
|
||||||
out float lf;
|
out float lf;
|
||||||
out vec2 tc;
|
out vec2 tc;
|
||||||
|
out vec3 pc;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
tc = texcoord;
|
tc = texcoord;
|
||||||
lf = lifetime;
|
lf = lifetime;
|
||||||
|
pc = color_from + (color_to - color_from) * lifetime;
|
||||||
vec3 newposition = position;
|
vec3 newposition = position;
|
||||||
|
|
||||||
vec4 viewpos = ViewMatrix * vec4(newposition, 1.0);
|
vec4 viewpos = ViewMatrix * vec4(newposition, 1.0);
|
||||||
|
@ -197,8 +197,8 @@ void initGL()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mostly from shader tutorial
|
// Mostly from shader tutorial
|
||||||
static
|
static GLuint LoadShader(const char * file, unsigned type)
|
||||||
GLuint LoadShader(const char * file, unsigned type) {
|
{
|
||||||
GLuint Id = glCreateShader(type);
|
GLuint Id = glCreateShader(type);
|
||||||
std::string Code = "#version 330\n";
|
std::string Code = "#version 330\n";
|
||||||
std::ifstream Stream(file, std::ios::in);
|
std::ifstream Stream(file, std::ios::in);
|
||||||
@ -218,7 +218,8 @@ GLuint LoadShader(const char * file, unsigned type) {
|
|||||||
glCompileShader(Id);
|
glCompileShader(Id);
|
||||||
|
|
||||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||||
if (Result == GL_FALSE) {
|
if (Result == GL_FALSE)
|
||||||
|
{
|
||||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||||
char *ErrorMessage = new char[InfoLogLength];
|
char *ErrorMessage = new char[InfoLogLength];
|
||||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||||
@ -229,7 +230,8 @@ GLuint LoadShader(const char * file, unsigned type) {
|
|||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) {
|
GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path)
|
||||||
|
{
|
||||||
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||||
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
@ -255,7 +257,8 @@ GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_pat
|
|||||||
return ProgramID;
|
return ProgramID;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint LoadProgram(const char * vertex_file_path, const char * geometry_file_path, const char * fragment_file_path) {
|
GLuint LoadProgram(const char * vertex_file_path, const char * geometry_file_path, const char * fragment_file_path)
|
||||||
|
{
|
||||||
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||||
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER);
|
||||||
GLuint GeometryShaderID = LoadShader(geometry_file_path, GL_GEOMETRY_SHADER);
|
GLuint GeometryShaderID = LoadShader(geometry_file_path, GL_GEOMETRY_SHADER);
|
||||||
@ -284,7 +287,8 @@ GLuint LoadProgram(const char * vertex_file_path, const char * geometry_file_pat
|
|||||||
return ProgramID;
|
return ProgramID;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) {
|
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount)
|
||||||
|
{
|
||||||
GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER);
|
||||||
GLuint Program = glCreateProgram();
|
GLuint Program = glCreateProgram();
|
||||||
glAttachShader(Program, Shader);
|
glAttachShader(Program, Shader);
|
||||||
@ -294,7 +298,8 @@ GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsi
|
|||||||
GLint Result = GL_FALSE;
|
GLint Result = GL_FALSE;
|
||||||
int InfoLogLength;
|
int InfoLogLength;
|
||||||
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
glGetProgramiv(Program, GL_LINK_STATUS, &Result);
|
||||||
if (Result == GL_FALSE) {
|
if (Result == GL_FALSE)
|
||||||
|
{
|
||||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||||
char *ErrorMessage = new char[InfoLogLength];
|
char *ErrorMessage = new char[InfoLogLength];
|
||||||
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage);
|
||||||
@ -305,11 +310,13 @@ GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsi
|
|||||||
return Program;
|
return Program;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint getTextureGLuint(irr::video::ITexture *tex) {
|
GLuint getTextureGLuint(irr::video::ITexture *tex)
|
||||||
|
{
|
||||||
return static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
return static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint getDepthTexture(irr::video::ITexture *tex) {
|
GLuint getDepthTexture(irr::video::ITexture *tex)
|
||||||
|
{
|
||||||
assert(tex->isRenderTarget());
|
assert(tex->isRenderTarget());
|
||||||
return static_cast<irr::video::COpenGLFBOTexture*>(tex)->DepthBufferTexture;
|
return static_cast<irr::video::COpenGLFBOTexture*>(tex)->DepthBufferTexture;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
|
|||||||
glGenVertexArrays(1, &non_current_rendering_vao);
|
glGenVertexArrays(1, &non_current_rendering_vao);
|
||||||
size_increase_factor = 0.;
|
size_increase_factor = 0.;
|
||||||
|
|
||||||
|
m_color_from[0] = m_color_from[1] = m_color_from[2] = 1.0;
|
||||||
|
m_color_to[0] = m_color_to[1] = m_color_to[2] = 1.0;
|
||||||
|
|
||||||
|
|
||||||
// We set these later but avoid coverity report them
|
// We set these later but avoid coverity report them
|
||||||
heighmapbuffer = 0;
|
heighmapbuffer = 0;
|
||||||
heightmaptexture = 0;
|
heightmaptexture = 0;
|
||||||
@ -82,11 +86,8 @@ ParticleSystemProxy::~ParticleSystemProxy()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; }
|
void ParticleSystemProxy::setFlip()
|
||||||
|
{
|
||||||
void ParticleSystemProxy::setIncreaseFactor(float val) { size_increase_factor = val; }
|
|
||||||
|
|
||||||
void ParticleSystemProxy::setFlip() {
|
|
||||||
flip = true;
|
flip = true;
|
||||||
float *quaternions = new float[4 * count];
|
float *quaternions = new float[4 * count];
|
||||||
for (unsigned i = 0; i < count; i++)
|
for (unsigned i = 0; i < count; i++)
|
||||||
@ -114,7 +115,8 @@ void ParticleSystemProxy::setFlip() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystemProxy::setHeightmap(const std::vector<std::vector<float> > &hm,
|
void ParticleSystemProxy::setHeightmap(const std::vector<std::vector<float> > &hm,
|
||||||
float f1, float f2, float f3, float f4) {
|
float f1, float f2, float f3, float f4)
|
||||||
|
{
|
||||||
track_x = f1, track_z = f2, track_x_len = f3, track_z_len = f4;
|
track_x = f1, track_z = f2, track_x_len = f3, track_z_len = f4;
|
||||||
|
|
||||||
unsigned width = hm.size();
|
unsigned width = hm.size();
|
||||||
@ -189,7 +191,8 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin
|
|||||||
{
|
{
|
||||||
ParticleData *particles = new ParticleData[count], *initialvalue = new ParticleData[count];
|
ParticleData *particles = new ParticleData[count], *initialvalue = new ParticleData[count];
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; i++) {
|
for (unsigned i = 0; i < count; i++)
|
||||||
|
{
|
||||||
particles[i].PositionX = 0;
|
particles[i].PositionX = 0;
|
||||||
particles[i].PositionY = 0;
|
particles[i].PositionY = 0;
|
||||||
particles[i].PositionZ = 0;
|
particles[i].PositionZ = 0;
|
||||||
@ -300,6 +303,7 @@ void ParticleSystemProxy::FlipParticleVAOBind(GLuint PositionBuffer, GLuint Quat
|
|||||||
|
|
||||||
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_rotationvec);
|
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_rotationvec);
|
||||||
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_anglespeed);
|
glEnableVertexAttribArray(ParticleShader::FlipParticleRender::attrib_anglespeed);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, QuaternionBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, QuaternionBuffer);
|
||||||
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_rotationvec, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
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)));
|
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_anglespeed, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float)));
|
||||||
@ -307,6 +311,7 @@ void ParticleSystemProxy::FlipParticleVAOBind(GLuint PositionBuffer, GLuint Quat
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
|
||||||
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||||
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
||||||
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
|
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
|
||||||
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::FlipParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
|
||||||
@ -330,6 +335,7 @@ void ParticleSystemProxy::SimpleParticleVAOBind(GLuint PositionBuffer)
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer);
|
||||||
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||||
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float)));
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
||||||
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
|
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0);
|
||||||
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::SimpleParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float)));
|
||||||
@ -364,19 +370,22 @@ void ParticleSystemProxy::SimpleSimulationBind(GLuint PositionBuffer, GLuint Ini
|
|||||||
|
|
||||||
void ParticleSystemProxy::HeightmapSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer)
|
void ParticleSystemProxy::HeightmapSimulationBind(GLuint PositionBuffer, GLuint InitialValuesBuffer)
|
||||||
{
|
{
|
||||||
|
// Position buffer
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_position);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_position);
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_lifetime);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_lifetime);
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_velocity);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_velocity);
|
||||||
// glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_size);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, PositionBuffer);
|
||||||
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0);
|
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0);
|
||||||
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float)));
|
||||||
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float)));
|
||||||
//glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float)));
|
|
||||||
|
// Initial values buffer
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_position);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_position);
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_lifetime);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_lifetime);
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_velocity);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_velocity);
|
||||||
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_size);
|
glEnableVertexAttribArray(ParticleShader::HeightmapSimulationShader::attrib_initial_size);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, InitialValuesBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, InitialValuesBuffer);
|
||||||
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0);
|
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0);
|
||||||
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float)));
|
glVertexAttribPointer(ParticleShader::HeightmapSimulationShader::attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float)));
|
||||||
@ -534,7 +543,8 @@ void ParticleSystemProxy::drawNotFlip()
|
|||||||
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
setTexture(1, static_cast<video::COpenGLFBOTexture *>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
|
setTexture(1, static_cast<video::COpenGLFBOTexture *>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
|
||||||
|
|
||||||
ParticleShader::SimpleParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1);
|
ParticleShader::SimpleParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(),
|
||||||
|
irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1, this);
|
||||||
|
|
||||||
glBindVertexArray(current_rendering_vao);
|
glBindVertexArray(current_rendering_vao);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||||
|
@ -19,6 +19,8 @@ protected:
|
|||||||
GLuint current_rendering_flip_vao, non_current_rendering_flip_vao;
|
GLuint current_rendering_flip_vao, non_current_rendering_flip_vao;
|
||||||
bool m_alpha_additive, has_height_map, flip;
|
bool m_alpha_additive, has_height_map, flip;
|
||||||
float size_increase_factor, track_x, track_z, track_x_len, track_z_len;
|
float size_increase_factor, track_x, track_z, track_x_len, track_z_len;
|
||||||
|
float m_color_from[3];
|
||||||
|
float m_color_to[3];
|
||||||
|
|
||||||
static GLuint quad_vertex_buffer;
|
static GLuint quad_vertex_buffer;
|
||||||
|
|
||||||
@ -55,8 +57,12 @@ public:
|
|||||||
virtual void setEmitter(scene::IParticleEmitter* emitter);
|
virtual void setEmitter(scene::IParticleEmitter* emitter);
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual void OnRegisterSceneNode();
|
virtual void OnRegisterSceneNode();
|
||||||
void setAlphaAdditive(bool);
|
void setAlphaAdditive(bool val) { m_alpha_additive = val; }
|
||||||
void setIncreaseFactor(float);
|
void setIncreaseFactor(float val) { size_increase_factor = val; }
|
||||||
|
void setColorFrom(float r, float g, float b) { m_color_from[0] = r; m_color_from[1] = g; m_color_from[2] = b; }
|
||||||
|
void setColorTo(float r, float g, float b) { m_color_to[0] = r; m_color_to[1] = g; m_color_to[2] = b; }
|
||||||
|
const float* getColorFrom() const { return m_color_from; }
|
||||||
|
const float* getColorTo() const { return m_color_to; }
|
||||||
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
void setHeightmap(const std::vector<std::vector<float> >&, float, float, float, float);
|
||||||
void setFlip();
|
void setFlip();
|
||||||
};
|
};
|
||||||
|
@ -248,6 +248,40 @@ protected:
|
|||||||
core::vector2df ScaleFactor;
|
core::vector2df ScaleFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
class ColorAffector : public scene::IParticleAffector
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
core::vector3df m_color_from;
|
||||||
|
core::vector3df m_color_to;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorAffector(const core::vector3df& colorFrom, const core::vector3df& colorTo) :
|
||||||
|
m_color_from(colorFrom), m_color_to(colorTo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void affect(u32 now, scene::SParticle *particlearray, u32 count)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i<count; i++)
|
||||||
|
{
|
||||||
|
const u32 maxdiff = particlearray[i].endTime - particlearray[i].startTime;
|
||||||
|
const u32 curdiff = now - particlearray[i].startTime;
|
||||||
|
const f32 timefraction = (f32)curdiff / maxdiff;
|
||||||
|
core::vector3df curr_color = m_color_from + (m_color_to - m_color_from)* timefraction;
|
||||||
|
particlearray[i].color = video::SColor(255, (int)curr_color.X, (int)curr_color.Y, (int)curr_color.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual scene::E_PARTICLE_AFFECTOR_TYPE getType() const
|
||||||
|
{
|
||||||
|
return scene::EPAT_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
@ -487,7 +521,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
|||||||
{
|
{
|
||||||
m_emitter = m_node->createPointEmitter(velocity,
|
m_emitter = m_node->createPointEmitter(velocity,
|
||||||
type->getMinRate(), type->getMaxRate(),
|
type->getMinRate(), type->getMaxRate(),
|
||||||
type->getMinColor(), type->getMaxColor(),
|
type->getMinColor(), type->getMinColor(),
|
||||||
lifeTimeMin, lifeTimeMax,
|
lifeTimeMin, lifeTimeMax,
|
||||||
m_particle_type->getAngleSpread() /* angle */
|
m_particle_type->getAngleSpread() /* angle */
|
||||||
);
|
);
|
||||||
@ -503,7 +537,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
|||||||
box_size_x, box_size_y, -0.6f - type->getBoxSizeZ()),
|
box_size_x, box_size_y, -0.6f - type->getBoxSizeZ()),
|
||||||
velocity,
|
velocity,
|
||||||
type->getMinRate(), type->getMaxRate(),
|
type->getMinRate(), type->getMaxRate(),
|
||||||
type->getMinColor(), type->getMaxColor(),
|
type->getMinColor(), type->getMinColor(),
|
||||||
lifeTimeMin, lifeTimeMax,
|
lifeTimeMin, lifeTimeMax,
|
||||||
m_particle_type->getAngleSpread()
|
m_particle_type->getAngleSpread()
|
||||||
);
|
);
|
||||||
@ -536,7 +570,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
|||||||
m_particle_type->getSphereRadius(),
|
m_particle_type->getSphereRadius(),
|
||||||
velocity,
|
velocity,
|
||||||
type->getMinRate(), type->getMaxRate(),
|
type->getMinRate(), type->getMaxRate(),
|
||||||
type->getMinColor(), type->getMaxColor(),
|
type->getMinColor(), type->getMinColor(),
|
||||||
lifeTimeMin, lifeTimeMax,
|
lifeTimeMin, lifeTimeMax,
|
||||||
m_particle_type->getAngleSpread()
|
m_particle_type->getAngleSpread()
|
||||||
);
|
);
|
||||||
@ -600,6 +634,38 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type->getMinColor() != type->getMaxColor())
|
||||||
|
{
|
||||||
|
if (m_is_glsl)
|
||||||
|
{
|
||||||
|
video::SColor color_from = type->getMinColor();
|
||||||
|
static_cast<ParticleSystemProxy *>(m_node)->setColorFrom(color_from.getRed() / 255.0f,
|
||||||
|
color_from.getGreen() / 255.0f,
|
||||||
|
color_from.getBlue() / 255.0f);
|
||||||
|
|
||||||
|
video::SColor color_to = type->getMaxColor();
|
||||||
|
static_cast<ParticleSystemProxy *>(m_node)->setColorTo(color_to.getRed() / 255.0f,
|
||||||
|
color_to.getGreen() / 255.0f,
|
||||||
|
color_to.getBlue() / 255.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
video::SColor color_from = type->getMinColor();
|
||||||
|
core::vector3df color_from_v = core::vector3df(color_from.getRed(),
|
||||||
|
color_from.getGreen(),
|
||||||
|
color_from.getBlue());
|
||||||
|
|
||||||
|
video::SColor color_to = type->getMaxColor();
|
||||||
|
core::vector3df color_to_v = core::vector3df(color_to.getRed(),
|
||||||
|
color_to.getGreen(),
|
||||||
|
color_to.getBlue());
|
||||||
|
|
||||||
|
ColorAffector* affector = new ColorAffector(color_from_v, color_to_v);
|
||||||
|
m_node->addAffector(affector);
|
||||||
|
affector->drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const float windspeed = type->getWindSpeed();
|
const float windspeed = type->getWindSpeed();
|
||||||
if (windspeed > 0.01f)
|
if (windspeed > 0.01f)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "graphics/callbacks.hpp"
|
#include "graphics/callbacks.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
|
#include "graphics/gpuparticles.hpp"
|
||||||
#include "graphics/shaders.hpp"
|
#include "graphics/shaders.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
@ -1293,7 +1294,9 @@ namespace ParticleShader
|
|||||||
GLuint SimpleParticleRender::uniform_dtex;
|
GLuint SimpleParticleRender::uniform_dtex;
|
||||||
GLuint SimpleParticleRender::uniform_screen;
|
GLuint SimpleParticleRender::uniform_screen;
|
||||||
GLuint SimpleParticleRender::uniform_invproj;
|
GLuint SimpleParticleRender::uniform_invproj;
|
||||||
|
GLuint SimpleParticleRender::uniform_color_from;
|
||||||
|
GLuint SimpleParticleRender::uniform_color_to;
|
||||||
|
|
||||||
void SimpleParticleRender::init()
|
void SimpleParticleRender::init()
|
||||||
{
|
{
|
||||||
Program = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str());
|
Program = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str());
|
||||||
@ -1310,9 +1313,15 @@ namespace ParticleShader
|
|||||||
uniform_invproj = glGetUniformLocation(Program, "invproj");
|
uniform_invproj = glGetUniformLocation(Program, "invproj");
|
||||||
uniform_screen = glGetUniformLocation(Program, "screen");
|
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
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_invproj, 1, GL_FALSE, InvProjMatrix.pointer());
|
||||||
glUniform2f(uniform_screen, width, height);
|
glUniform2f(uniform_screen, width, height);
|
||||||
@ -1320,6 +1329,11 @@ namespace ParticleShader
|
|||||||
glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());
|
glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer());
|
||||||
glUniform1i(uniform_tex, TU_tex);
|
glUniform1i(uniform_tex, TU_tex);
|
||||||
glUniform1i(uniform_dtex, TU_dtex);
|
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::Program;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
typedef unsigned int GLuint;
|
typedef unsigned int GLuint;
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
class ParticleSystemProxy;
|
||||||
|
|
||||||
class SharedObject
|
class SharedObject
|
||||||
{
|
{
|
||||||
@ -361,10 +362,12 @@ class SimpleParticleRender
|
|||||||
public:
|
public:
|
||||||
static GLuint Program;
|
static GLuint Program;
|
||||||
static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz;
|
static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz;
|
||||||
static GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_dtex, uniform_screen, uniform_invproj;
|
static GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_dtex, uniform_screen, uniform_invproj, uniform_color_from, uniform_color_to;
|
||||||
|
|
||||||
static void init();
|
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);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlipParticleRender
|
class FlipParticleRender
|
||||||
|
Loading…
Reference in New Issue
Block a user