粒子系统错误

时间:2013-04-26 15:39:18

标签: opengl glsl shader fragment-shader vertex-shader

我在本教程中使用粒子系统类Particles - Anton's OpenGL 4 Wiki - Dr Anton Gerdelan

代码:

//Pixel Shader 

// shader to update a particle system based on a simple kinematics function
#version 150

in vec3 v; // initial velocity
in float tZero; // start time

uniform mat4 projViewModelMatrix;

uniform vec3 emitterPos_wor; // emitter position in world coordinates
uniform float T; // system time T in seconds

out float opacity;

void main() {
// work out how many seconds into our particle's life-time we are (after its starting time)
float t = T - tZero;
vec3 p;
// gradually make particle more transparent over its life-time
opacity = 1 - (t / 3) - 0.2;

// particle stays put until it has reached its birth second
if (t > 0) {
// gravity
vec3 a = vec3(0,-10,0);
// this is a standard kinematics equation of motion with velocity (from VBO) and acceleration (gravity)
p = emitterPos_wor + v * t + 0.5 * a * t * t;
} else {
p =  emitterPos_wor;
}
gl_Position = projViewModelMatrix * vec4(p, 1);
}


// Vertex shader

// shader to render simple particle system's points
#version 150

uniform sampler2D textureMap; // I used a texture for my particles
out vec4 fragColour;

uniform vec4 Color;

in float opacity;

void main() {
vec4 texcol = texture2D(textureMap, gl_PointCoord); // using point uv coordinates which are pre-defined over the point
fragColour = vec4(1-opacity,1-opacity,1-opacity,1-opacity) * texcol * Color; // bright blue!
}

/////// CPU

bool ParticleSystem::init(vec3 Position){

std::vector<vec3> Velocidad;
std::vector<float> Life;

for ( int i = 0; i < MAX_PARTICLES; i++ ) {
Velocidad.push_back(vec3(0,-1,0));
}

for ( int i = 0; i < MAX_PARTICLES; i++ ) {
Life.push_back(0.001f * (float)(i));
}


glGenVertexArrays( 1, &m_VAO );
glBindVertexArray( m_VAO );

glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);

glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VEL_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Velocidad[0]) * Velocidad.size(), &Velocidad[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);    

glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[LIF_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Life[0]) * Life.size(), &Life[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);    

glBindVertexArray(0);

return true;
}

/////////////////// FINAL RENDER 

bool ParticleSystem::render(){

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,ModeloOrtho.getTextureFromID(24));

glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable(GL_POINT_SPRITE);
glPointSize(150.0f);
shaderParticle.setUniform("projViewModelMatrix",vsml->get(VSMathLib::PROJ_VIEW_MODEL));
shaderParticle.setUniform("emitterPos_wor",ParticleInit);
shaderParticle.setUniform("T",ParticleTime);
shaderParticle.setUniform("Color",ColorParticle);

glUseProgram(shaderParticle.getProgramIndex()); 

glBindVertexArray(m_VAO);
glDrawElements(GL_POINTS, 0, GL_UNSIGNED_INT, 0); 
glBindVertexArray(0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,0);
return true;
}

问题在于没有任何反应。

如果我更改此行: glDrawElements(GL_POINTS,MAX_PARTICLES,GL_UNSIGNED_INT,0); 崩溃系统。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

顶点着色器

/* shader to update a particle system based on a simple kinematics function */
#version 410 core

layout (location = 0) in vec3 v_i; // initial velocity
layout (location = 1) in float start_time;

uniform mat4 V, P;
uniform vec3 emitter_pos_wor; // emitter position in world coordinates
uniform float elapsed_system_time; // system time in seconds

// the fragment shader can use this for it's output colour's alpha component 
out float opacity;

void main() {
// work out the elapsed time for _this particle_ after its start time
float t = elapsed_system_time - start_time;
// allow time to loop around so particle emitter keeps going
t = mod (t, 3.0);
opacity = 0.0;

vec3 p = emitter_pos_wor;
// gravity
vec3 a = vec3 (0.0, -1.0, 0.0);
// this is a standard kinematics equation of motion with velocity and
// acceleration (gravity)
p += v_i * t + 0.5 * a * t * t;
// gradually make particle fade to invisible over 3 seconds
opacity = 1.0 - (t / 3.0);

gl_Position = P * V * vec4 (p, 1.0);
gl_PointSize = 15.0; // size in pixels
}

片段着色器

/* shader to render simple particle system points */
#version 410 core

in float opacity;
uniform sampler2D tex; // optional. enable point-sprite coords to use
out vec4 frag_colour;

const vec4 particle_colour = vec4 (0.4, 0.4, 0.8, 0.8); 

void main () {
// using point texture coordinates which are pre-defined over the point
vec4 texel = texture (tex, gl_PointCoord);
frag_colour.a = opacity * texel.a;
frag_colour.rgb = particle_colour.rgb * texel.rgb;
}