Atomic Counters in OpenFrameworks

An image of a slime mold simulation titled Rainbow Tendrils
slime mold simulation done in compute shader (instagram: @_samuelcho_ )

Setting up the buffers

There is only one data type used with atomic counters and that is atomic_uint . The data type that maps to this is GLuint. So we need to create a GLuint vector of size 1.

vector<GLuint> counter;
ofBufferObject counterBuffer;
counterBuffer.allocate(counter, GL_DYNAMIC_DRAW);
counterBuffer.bindBase(GL_ATOMIC_COUNTER_BUFFER, 0);

Setting up the shader

I’m going to make a particle system, so I will be using compute shaders. The setup looks like this:

ofShader compute;
compute.setupShaderFromFile(GL_COMPUTE_SHADER, "shader.comp");

Writing the shader

Since we bound the atomic counter buffer to the binding point 0 earlier, we can access it in the shader. To access data at binding points, we can use the layout qualifier in GLSL. One thing to note is that the atomic counter type is opaque. This means that we need to declare it as a uniform in the shader.

layout(binding = 0) uniform atomic_uint counter;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main(){

Reading the data from ofBufferObject

For debugging, we might want to check the counter in our host application. Since we created 69 particles, we expect that the counter reads 69 since we incremented it 69 times.

GLuint result[1];
glGetNamedBufferSubData(counterBuffer.getId(), 0, sizeof(GLuint), result);


That’s it for atomic counters! This is a simple way to get atomic counters working without resorting to the verbose OpenGL API. I hope this has helped!



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sam Tsao

Sam Tsao

New Music Performer . Composer . Creative Coder