I am trying to figure out how SSBO works with a very basic example. The vertex shader:
#version 430
layout(location = 0) in vec2 Vertex;
void main() {
gl_Position = vec4(Vertex, 0.0, 1.0);
}
And the fragment shader:
#version 430
layout(std430, binding = 2) buffer ColorSSBO {
vec3 color;
};
void main() {
gl_FragColor = vec4(color, 1.0);
}
I know they work because if I replace vec4(color, 1.0)
with vec4(1.0, 1.0, 1.0, 1.0)
I see a white triangle in the center of the screen.
I initialize and bind the SSBO with the following code:
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
float color[] = {1.f, 1.f, 1.f};
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(float), color, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
What is wrong here?
My guess is that you are missing the SSBO binding before rendering. In your example, you are copying the content and then you bind it immediately, which is unnecessary for the declaration. In other words, the following line in your example:
...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
...
Must be placed before rendering, such as:
...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
/*
Your render calls and other bindings here.
*/
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
...
Without this, your shader (theoretically) will not be able to see the content.
In addition, as Andon M. Coleman has suggested, you have to use padding for your elements when declaring arrays (e.g., use vec4 instead of vec3). If you don't, it will apparently work but produce strange results because of this fact.
The following two links have helped me out understanding the meaning of an SSBO and how to handle them in your code:
https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object http://www.geeks3d.com/20140704/tutorial-introduction-to-opengl-4-3-shader-storage-buffers-objects-ssbo-demo/
I hope this helps to anyone facing similar issues!
P.S.: I know this post is old, but I wanted to contribute.
When drawing a triangle, three points are necessary, and 3 separate sets of red green blue values are required for each point. You are only putting one set into the shader buffer. For the other two points, the value of color drops to the default, which is black (0.0,0.0,0.0). If you don't have blending enabled, it is likely that the triangle is being painted completely black because two of its vertices are black.
Try putting 2 more sets of red green blue values into the storage buffer to see it will load them as color values for the other two points.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With