I write some vertex data inside a shader to SSBO. Then I want to use the data written to the SSBO as VBOs. These will be used for the next draw call. How can this be done?
Here is, how I do it now, but it still segfaults:
int new_vertex_count = …;
int new_index_count = …;
int* new_indices = …;
GLuint ssbo[3];
glGenBuffers(3, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[1]);
glBufferData(GL_SHADER_STORAGE_BUFFER, new_vertex_count * 3 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo[1]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[2]);
glBufferData(GL_SHADER_STORAGE_BUFFER, new_vertex_count * 2 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo[2]);
glBindVertexArray(vao); //bind the original VAO
glPatchParameteri(GL_PATCH_VERTICES, 16);
glEnable(GL_RASTERIZER_DISCARD); //disable displaying
glDrawElements(GL_PATCHES, index_count, GL_UNSIGNED_INT, 0); //don't draw, just
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); //sync writing
glFinish();
glDisable(GL_RASTERIZER_DISCARD); //reanable displaying for next draw call
glBindVertexArray(0); //unbind original VAO in order to use new VBOs
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ssbo[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, ssbo[1]); //bind SSBO as VBO, is this even possible?
//or should I use new VBOs and copy? How would I copy then?
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, ssbo[2]);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glDrawElements(GL_PATCHES, new_index_count, new_indices, GL_UNSIGNED_INT, 0); //here the real drawing
There is no such thing as an "SSBO" or a "VBO". There are only buffer objects. Storage blocks and vertex arrays are uses for buffer objects, but a particular buffer is not inherently linked to a particular use. There's nothing stopping you from writing to a buffer through a storage block, then reading from it in a rendering operation.
So long as you follow the rules of incoherent memory access for those writes, of course. Writes through a storage block are not available for reading operations unless you explicitly make them available. You would use glMemoryBarrier
for this. And the way a memory barrier works is that the enumerator specifies the operations you want to be able to see the results of whatever was written.
You want the written data to be read as vertex attribute arrays. So you use:
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
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