0
\$\begingroup\$

How do i stream to a vertex buffer using Direct State Access? I want to update my vertex buffer of matrices every frame so i can use it in my Shader. This is how i specify my buffer. I do this once in my application when i initialize my VAO.

    glNamedBufferStorage(StaticModelData::instanceDataID, sizeof(InstanceData)*10, nullptr, 0);
    glMapNamedBufferRange(StaticModelData::instanceDataID, 0, sizeof(InstanceData) * 10, GL_MAP_UNSYNCHRONIZED_BIT);
    glVertexArrayVertexBuffer(StaticModelData::vaoID, 1, StaticModelData::instanceDataID, 0, 0);

    glVertexArrayAttribBinding(StaticModelData::vaoID, 3, 1);
    glVertexArrayAttribFormat(StaticModelData::vaoID, 3, 4, GL_FLOAT, GL_FALSE, 0);

    glVertexArrayAttribBinding(StaticModelData::vaoID, 4, 1);
    glVertexArrayAttribFormat(StaticModelData::vaoID, 4, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4);

    glVertexArrayAttribBinding(StaticModelData::vaoID, 5, 1);
    glVertexArrayAttribFormat(StaticModelData::vaoID, 5, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8);

    glVertexArrayAttribBinding(StaticModelData::vaoID, 6, 1);
    glVertexArrayAttribFormat(StaticModelData::vaoID, 6, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 12);

    glVertexArrayBindingDivisor(StaticModelData::vaoID, 1, 1);

Every frame i do this to render

    instanceDatas = updateMatrices();    
    updateShader();
    glBindVertexArray(StaticModelData::vaoID);
    glNamedBufferData(StaticModelData::instanceDataID, sizeof(InstanceData)*(instanceDatas.size()), &instanceDatas[0], 0);

    glBindTexture(GL_TEXTURE_2D, 1);//hardcoded

    glDrawElementsInstanced(GL_TRIANGLES, it->second.modelIndexNum, GL_UNSIGNED_INT, (void*)(sizeof(int)*(it->second.indexOffset)), it->second.instances.size());
\$\endgroup\$
1
\$\begingroup\$

Your question has nothing to do with direct state access. Your problems would still happen if you weren't using DSA functions.

glNamedBufferStorage(StaticModelData::instanceDataID, sizeof(InstanceData)*10, nullptr, 0);

That last value tells OpenGL how you intend to access the storage from the CPU. By passing zero, you're saying that you're not going to access the storage from the CPU. At all. Since you made a promise not to access its storage from the CPU, OpenGL doesn't let you break that promise.

Furthermore, since you created immutable storage for this buffer, you cannot later call glNamedBufferData or glNamedBufferStorage on the buffer.

The general buffer streaming techniques don't change just because you're using DSA. Personally, since you're using immutable storage buffers anyway, I'd say that you should use persistent&coherent mapped memory with your buffers.

So you should create your buffer with MAP_WRITE_BIT, PERSISTENT_BIT, and COHERENT_BIT. You should map it once (with those bits too) and just keep the pointer around.

Now, you should still double-buffer your instances, so that you're not overwriting data that the GPU is still reading from.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.