I'm learning OpenGL compute shaders and following this guy's code, and I have stuff drawing, but not updating. The particles are spread out in their starting positions, but they stay there.
Particle manager initialization
void ParticleManager::Init(unsigned int programId,
unsigned int computeProgramId,
unsigned int numParticles)
{
...reset all particles...
_unifLocDeltaTimeSec = glGetUniformLocation(_computeProgramId, "uDeltaTimeSec");
_shaderBufferId = 0;
glGenBuffers(1, &_shaderBufferId);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, _shaderBufferId);
glBufferData(GL_SHADER_STORAGE_BUFFER, _allParticles.size() * sizeof(Particle), _allParticles.data(), GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _shaderBufferId);
...vertex array buffer and attribute array initialization...
}
Particle manager update
void ParticleManager::Update(float deltaTimeSec)
{
glUseProgram(_computeProgramId);
glUniform1f(_unifLocDeltaTimeSec, deltaTimeSec);
GLuint numWorkGroupsX = (_allParticles.size() / 128) + 1;
GLuint numWorkGroupsY = 1;
GLuint numWorkGroupsZ = 1;
glDispatchCompute(numWorkGroupsX, numWorkGroupsY, numWorkGroupsZ);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
glUseProgram(0);
}
Particle manager render
void ParticleManager::Render()
{
glUseProgram(_programId);
glBindVertexArray(_vaoId);
glDrawArrays(GL_POINTS, 0, _allParticles.size());
glUseProgram(0);
}
Compute shader
#version 440
struct Particle
{
vec2 _position;
vec2 _velocity;
int _isActive;
};
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
layout (binding = 0) buffer ParticleBuffer {
Particle AllParticles[];
};
uniform float uDeltaTimeSec; // self-explanatory
void main()
{
uint index = gl_GlobalInvocationID.x;
Particle p = AllParticles[index];
vec2 deltaPosition = p._velocity * uDeltaTimeSec;
p._position = p._position + deltaPosition;
AllParticles[index] = p;
}
I've looked through various forum posts (stack exchange, stack overflow, OpenGL forums) and read at least one tutorial and followed another guy's github project (only allowed 2 links in a post), but I haven't been able to figure out why nothing moves.
My top culprits are:
- Something in the compute shader's "delta position" is evaluating to 0.
- The compute shader is not getting called.
- The draw shader is not getting access to the compute shader's updated info.
Doubts:
- I hard coded a change in position, so all particles should have moved some on every frame, and when that didn't work, I hard-coded a position, and that didn't work either, so the shader might not even be getting to main().
numWorkGroupsX
evaluates to 79 (non-zero), so the compute shader should at least reach main().- I called
glMemoryBarrier(...)
withGL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT
, so the vertex array buffer should have access to the updated info.
Also, no errors or warnings are reported during GLSL compilation or at runtime, so the computer is evidently happy with what I provided it.
Help? Why are my particles never moving beyond initialization?