PDA

View Full Version : Direct State Access Instance attribute buffer specification



stimulate
03-13-2017, 11:00 AM
I have a model i want to render instances of. Every instance should have a different position and this should be provided from one continuous buffer of positions that will be read from the shader as a vertex attribute and that will advance for every instance.

This means i have the usual vertex data buffer which is indexed by the element buffer and provides vertex attributes 0, 1 and 2 with data. But now i also have another buffer of positions (vec4s in my case) which should provide vertex attribute 3 with data. How can i do this using VAOs and direct state access?

This was my attempt



glCreateVertexArrays(1, &instancingVAO);
glCreateBuffers(1, &positionVBO); //for instance positions
glCreateBuffers(1, &meshVBO); //for mesh data
glCreateBuffers(1, &meshIBO); //mesh data indices

glEnableVertexArrayAttrib(instancingVAO, 0);
glEnableVertexArrayAttrib(instancingVAO, 1);
glEnableVertexArrayAttrib(instancingVAO, 2);
glEnableVertexArrayAttrib(instancingVAO, 3);

glVertexArrayAttribBinding(instancingVAO, 0, 0);
glVertexArrayAttribBinding(instancingVAO, 1, 0);
glVertexArrayAttribBinding(instancingVAO, 2, 0);

glVertexArrayAttribBinding(instancingVAO, 3, 1);// i expected this binding to do the trick..


///Mesh Data
glVertexArrayVertexBuffer(instancingVAO, 0, meshVBO, 0, sizeof(OpenGL::glVertex)); //bound to binding 0
glVertexArrayElementBuffer(instancingVAO, meshIBO);

//format specification
glVertexArrayAttribFormat(instancingVAO, 0, 3, GL_FLOAT, GL_FALSE, offsetof(OpenGL::glVertex, position));
glVertexArrayAttribFormat(instancingVAO, 1, 3, GL_FLOAT, GL_FALSE, offsetof(OpenGL::glVertex, normal));
glVertexArrayAttribFormat(instancingVAO, 2, 2, GL_FLOAT, GL_FALSE, offsetof(OpenGL::glVertex, uv));

//static data upload
glNamedBufferStorage(meshVBO, sizeof(OpenGL::glVertex)*allMeshVertices.size(), &allMeshVertices[0], 0);
glNamedBufferStorage(meshIBO, sizeof(unsigned int)*allMeshIndices.size(), &allMeshIndices[0], 0);


///dynamic & per instance attributes
///position data
glVertexArrayVertexBuffer(instancingVAO, 1, positionVBO, 0, sizeof(glm::vec4)); //bound to binding 1

//format specification for the instance position
glVertexArrayAttribFormat(instancingVAO, 3, 4, GL_FLOAT, GL_FALSE, 0);

//glVertexAttribDivisor does not have DSA, so:
glBindVertexArray(instancingVAO);
glVertexAttribDivisor(3, 1);
glBindVertexArray(0);

//static data upload (only for debugging, later this buffer should be updated every frame)
glNamedBufferStorage(positionVBO, sizeof(glm::vec4)*positionBuffer.size(), &positionBuffer[0], 0);

stimulate
03-13-2017, 11:13 AM
Wow, okay....

right after posting this (which was after 2 hours of debugging) i found the solution.

instead of


glBindVertexArray(instancingVAO);
glVertexAttribDivisor(3, 1);
glBindVertexArray(0);

to say that this attribute should only change per instance, i had to say


glVertexArrayBindingDivisor(instancingVAO, 1, 1);

to say that all attributes bound to this binding point (1) should change per instance (I guess).