I am working on a particle system using a computational shader right now. I put all my particles into the shader storage buffer. A particle contains two vertices, the current position and the previous position.
struct Particle{ glm::vec4 _currPosition; glm::vec4 _prevPosition; };
After I send my computational shader, I want to draw all the particles directly from the buffer storage shader. So here is what I am doing:
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBufferID); _shaderManager->useProgram("computeProg"); glDispatchCompute((_numParticles/WORK_GROUP_SIZE)+1, 1, 1); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); _shaderManager->useProgram("shaderProg"); glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBufferID); glVertexPointer(4,GL_FLOAT, sizeof(glm::vec4), (GLvoid*)0); glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(GL_POINTS, 0, _numParticles); glDisableClientState(GL_VERTEX_ARRAY);
The problem is that I see _numParticles on the screen, but one half is displayed with the _prevPosition attribute of my particle structure. This means that one particle is interpreted as two vertices that are drawn on the screen. But I want it to skip the _prevPosition attribute in every particle structure. Where is my mistake?
Perhaps the way that I initialize the storage shader buffer is important:
GLuint shaderStorageBufferID; glGenBuffers(1, &shaderStorageBufferID); glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferID); glBufferData(GL_SHADER_STORAGE_BUFFER, numParticles*sizeof(Particle), NULL ,GL_STATIC_DRAW); struct Particle* particles = (struct Particle*) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, numParticles*sizeof(Particle), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for(int i = 0; i < numParticles; ++i){ particles[i]._currPosition = glm::vec4(i, 0, 0.0, 1.0f); particles[i]._prevPosition = glm::vec4(i, 0, 1.0, 1.0f); }