Instancing with Direct State Access... glVertexArrayBindingDivisor?

Just trying to port some code to test out instancing with DSA functions. Getting my object, but no instances of it. Divisor doesn’t seem to be doing the trick. Do I have the right command?

It’s kind of hackish, but like I said, just testing stuff out.


// Vertex Buffer
	GLuint vertexBuffer;
	glCreateBuffers ( 1, &vertexBuffer );
	glBindBuffer ( GL_ARRAY_BUFFER, vertexBuffer );
	glBufferData ( GL_ARRAY_BUFFER, vertices.size () * sizeof ( GLfloat ), vertices.data (), GL_STATIC_DRAW );

	// Index Buffer
	GLuint indexBuffer;
	glCreateBuffers ( 1, &indexBuffer );
	glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
	glBufferData ( GL_ELEMENT_ARRAY_BUFFER, indices.size () * sizeof ( GLuint ), indices.data (), GL_STATIC_DRAW );

	// Offset Buffer
	GLfloat offsets[] = { 0.0f, 20.0f, -40.0f };
	
	GLuint offsetsBufferID;
	glCreateBuffers ( 1, &offsetsBufferID );
	glBindBuffer ( GL_ARRAY_BUFFER, offsetsBufferID );
	glBufferData ( GL_ARRAY_BUFFER, sizeof ( offsets ), offsets, GL_STATIC_DRAW );


GLuint vertexArray;
	glCreateVertexArrays ( 1, &vertexArray );

	glVertexArrayElementBuffer ( vertexArray, indexBuffer );
	
	glVertexArrayAttribBinding ( vertexArray, positionLocation, 0 );
	glVertexArrayAttribFormat ( vertexArray, positionLocation, 3, GL_FLOAT, GL_FALSE, 0 );
	glVertexArrayVertexBuffer ( vertexArray, positionLocation, vertexBuffer, 0, 3 * sizeof(float) );
	glEnableVertexArrayAttrib ( vertexArray, positionLocation );

	glVertexArrayAttribBinding ( vertexArray, 1, 0 );
	glVertexArrayAttribFormat ( vertexArray, 1, 1, GL_FLOAT, GL_FALSE, 0 );
	glVertexArrayBindingDivisor ( vertexArray, 1, 1 );
	glVertexArrayVertexBuffer ( vertexArray, 1, offsetsBufferID, 0, sizeof ( offsets ) );
	glEnableVertexArrayAttrib ( vertexArray, 1 );


	double x, y;
	while ( !glfwWindowShouldClose ( m_pWindow ) )
	{
		glfwPollEvents ();

		glfwGetCursorPos ( m_pWindow, &x, &y );
		mainCamera->mouseUpdate ( glm::vec2 ( x, y ) );
		
		glm::mat4 ProjectionMatrix = mainCamera->getProjectionMatrix ();
		glm::mat4 ProjectionAndCamera = ProjectionMatrix * mainCamera->getViewMatrix ();
		glm::mat4 ProjectionTranslationMatrix = glm::translate ( ProjectionAndCamera, glm::vec3 ( 0.0f, 0.0f, 0.0f ) );
		glm::mat4 FullTransformMatrix = glm::rotate ( ProjectionTranslationMatrix, 54.0f, glm::vec3 ( 1.0f, 0.0f, 0.0f ) );
		glProgramUniformMatrix4fv ( program, fullTransformMatrixLocation, 1, GL_FALSE, &FullTransformMatrix[0][0] );

		glClearColor ( 0.3f, 0.45f, 0.65f, 1.0f );
		glClear ( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

		glUseProgram ( program );

		glBindVertexArray ( vertexArray );

		glEnable ( GL_CULL_FACE );
		glCullFace ( GL_BACK );
		glFrontFace ( GL_CCW );

		glDrawElementsInstanced ( GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr, 3 );
		
		glfwSwapBuffers ( m_pWindow );
	}

glVertexArrayAttribBinding ( vertexArray, 1, 0 );
...
glVertexArrayBindingDivisor ( vertexArray, 1, 1 );
glVertexArrayVertexBuffer ( vertexArray, 1, offsetsBufferID, 0, sizeof ( offsets ) );

This is wrong. You’re setting the divisor and buffers for buffer binding 1. But you’re telling attribute index 1 to use buffer binding 0, which is where the position buffer is.

Good catch, thanks. Changed to the following.


	// positionLocation = 0
	glVertexArrayAttribBinding ( vertexArray, positionLocation, 0 ); // Map attribute position to binding index 0
	glVertexArrayAttribFormat ( vertexArray, positionLocation, 3, GL_FLOAT, GL_FALSE, 0 ); // Describe the attribute as 3 floats
	glVertexArrayVertexBuffer ( vertexArray, 0, vertexBuffer, 0, 3 * sizeof(float) ); // bind buffer to vertex buffer bind point
	glEnableVertexArrayAttrib ( vertexArray, positionLocation ); // Enable attribute

	// offsetLocation = 1
	glVertexArrayAttribBinding ( vertexArray, offsetLocation, 1);
	glVertexArrayAttribFormat ( vertexArray, offsetLocation, 1, GL_FLOAT, GL_FALSE, 0 );
	glVertexArrayVertexBuffer ( vertexArray, 1, offsetsBuffer, 0, sizeof ( offsets ) );
	glEnableVertexArrayAttrib ( vertexArray, offsetLocation );
	glVertexArrayBindingDivisor ( vertexArray, 1, 1 );

The object still isn’t being instanced though. :confused:

EDIT: Added in descriptions of what I think it’s doing.

Here’s another problem:


GLfloat offsets[] = { 0.0f, 20.0f, -40.0f };
...
glVertexArrayVertexBuffer ( vertexArray, 1, offsetsBuffer, 0, sizeof ( offsets ) );

sizeof(offsets) will return the size of the entire array, not the size of an element in that array. You want this to be sizeof(GLfloat).