我在本教程中使用粒子系统类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); 崩溃系统。
我做错了什么?
答案 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;
}