PDA

View Full Version : Instancing with Direct State Access... glVertexArrayBindingDivisor?



Stradigos
05-10-2015, 04:59 PM
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 );
}

Alfonse Reinheart
05-10-2015, 05:47 PM
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.

Stradigos
05-10-2015, 06:59 PM
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.

Alfonse Reinheart
05-10-2015, 10:22 PM
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)`.