I am working on a small particle system using OpenGL.
The problem is that updating the positions in the compute shader do not seem to work.
Here's the code:
Buffers
struct ParticleInfo {
Vec4f position; // w: s coordinate
Vec4f normal; // w: t coordinate
float materialIndex;
Vec3f oldPosition;
};
Init buffers
glGenVertexArrays(1, &mParticleVAO);
glBindVertexArray(mParticleVAO);
glGenBuffers(1, &mParticleVBO);
glBindBuffer(GL_ARRAY_BUFFER, mParticleVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(ParticleInfo) * mNumParticles, particleData.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)NULL);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + sizeof(Vec4f)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + 2*sizeof(Vec4f)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
update buffers with a compute shader
gl->setUniform(mParticleMoveProgram->getUniformLoc("numParticles"), mNumParticles);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mParticleVBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mAttractorSSBO);
int localSizeX = 64*8;
int groupSizeX = (mNumParticles + localSizeX - 1) / localSizeX;
glDispatchCompute(groupSizeX, 1, 1);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
shader code
#version 450
layout(local_size_x = 64) in;
struct ParticleInfo {
vec4 position; // modify only the position;
vec4 normal;
float materialIndex;
vec3 oldPosition;
};
struct Attractor {
vec3 position;
float mass;
};
layout(binding = 0, std430) buffer ParticleArray {
ParticleInfo particles[];
};
layout(binding = 1, std430) buffer AttractorArray {
Attractor attractors[];
};
uniform int numParticles;
vec3 verlet(in vec3 a, in vec3 x, in vec3 xOld, in float dt) {
return 2.0 * x - xOld + a * dt*dt;
}
void main() {
const int PARTICLES_PER_THREAD = 8;
int index = int(gl_LocalInvocationIndex)*PARTICLES_PER_THREAD;
if (index >= numParticles) return;
Attractor attr = attractors[0];
const float G = 9.8;
for (int i = 0; i < PARTICLES_PER_THREAD; ++i)
{
particles[i+index].position = vec4(0.0);
particles[i+index].normal = vec4(0.0);
particles[i+index].oldPosition = vec3(0.0);
}
}
It is as @derhass commented. The memory structure didn't match. There seemed to be also a problem with proper indexing per thread. I fixed it by setting the index per thread as:
index = PARTICLES_PER_THREAD * int(gl_WorkGroupSize.x * gl_WorkGroupID.x + gl_LocalInvocationID.x);
Thanks for the help.