Direct State Access Instance attribute buffer specification

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:
	glVertexAttribDivisor(3, 1);
        //static data upload (only for debugging, later this buffer should be updated every frame)
	glNamedBufferStorage(positionVBO, sizeof(glm::vec4)*positionBuffer.size(), &positionBuffer[0], 0);

Wow, okay…

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

instead of

	glVertexAttribDivisor(3, 1);

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).

1 Like