Little problem with MultiDrawElementsIndirect


#1

Hi!

I have been working with glMultiDrawElementsIndirect, and works… but always rendering only the first mesh of the set, I have checked several times the composite of IndirectBuffer, also the composite of the “Matrix Transform” buffer but I can’t see the error that should be obvious.

I have tried to make it as easy as possible:

A ) First to all I generate the Buffers and the Matrix transform :

			glGenVertexArrays(1, &VAO);
			glGenBuffers(1, &VBO);
			glGenBuffers(1, &EBO);
			glGenBuffers(1, &MBO); //Matrix Buffer
			glGenBuffers(1, &gIndirectBuffer);

            int ammount = 3, 
	        
            glm::mat4 MatrixT[ammount];
	        MatrixT[0].glm::translate(MatrixT[0], glm::vec3(100, 0, 100));
	        MatrixT[1].glm::translate(MatrixT[1], glm::vec3(110, 0, 110));
	        MatrixT[2].glm::translate(MatrixT[2], glm::vec3(120, 0, 120));

B ) After I set the vertex and indices sizes :

	        vertexSize[0] = mesh_A->vertex.size();
	        vertexSize[1] = mesh_B->vertex.size();
	        vertexSize[2] = mesh_C->vertex.size();

	        V_bufferSize = (vertexSize[0]+vertexSize[1]+vertexSize[2]) * sizeof(GLfloat);

	        indiceSize[0] = mesh_A->indice.size();
	        indiceSize[1] = mesh_B->indice.size();
	        indiceSize[2] = mesh_C->indice.size();

	        I_bufferSize = (indiceSize[0]+indiceSize[1]+indiceSize[2]) * sizeof(GLuint);

C ) Them I build the vertex and indices arrays :

	vertex_Array = new GLfloat[vertexSize[0]+vertexSize[1]+vertexSize[2]];
	indices_Array = new GLuint[indiceSize[0]+indiceSize[1]+indiceSize[2]];

	GLuint sum = 0;
	for (GLuint i = 0; i < vertexSize[0]; i++) vertex_Array[i] = mesh_A->vertex[i];
	
	sum += vertexSize[0];
	for (GLuint i = 0; i < vertexSize[1]; i++) vertex_Array[i+sum] = mesh_B->vertex[i];
            
	sum += vertexSize[1];
	for (GLuint i = 0; i < vertexSize[2]; i++) vertex_Array[i+sum] = mesh_C->vertex[i];
           
    // same for indices_Array 

D) now I create the Indirect Buffer:

        int baseVert = 0;
		for(int i = 0; i < ammount; i++)  {
            vDrawCommand[i].count = indiceSize[i];
			vDrawCommand[i].instanceCount = 1;
			vDrawCommand[i].firstIndex = 0;
			vDrawCommand[i].baseVertex = baseVert;
			vDrawCommand[i].baseInstance = i;
			baseVert += vertexSize[i];
          }

	glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gIndirectBuffer);
	glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(vDrawCommand), vDrawCommand, GL_DYNAMIC_DRAW);

E) at the end I create the buffers

		glBindVertexArray(VAO);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBufferData(GL_ARRAY_BUFFER, V_bufferSize , vertex_Array , GL_DYNAMIC_DRAW);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, I_bufferSize , indices_Array ,GL_DYNAMIC_DRAW);


		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);

		glEnableVertexAttribArray(1);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));

		glEnableVertexAttribArray(2);
		glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));

		glEnableVertexAttribArray(3);
		glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));


		glBindBuffer(GL_ARRAY_BUFFER, MBO_building);
		glBufferData(GL_ARRAY_BUFFER, ammount * sizeof(glm::mat4), MatrixT, GL_DYNAMIC_DRAW);

		glEnableVertexAttribArray(4);
		glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, (4 * sizeof(glm::vec4)), (void*)0);

		glEnableVertexAttribArray(5);
		glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, (4 * sizeof(glm::vec4)), (void*)(sizeof(glm::vec4)));

		glEnableVertexAttribArray(6);
		glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, (4 * sizeof(glm::vec4)), (void*)(2 * sizeof(glm::vec4)));

		glEnableVertexAttribArray(7);
		glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, (4 * sizeof(glm::vec4)), (void*)(3 * sizeof(glm::vec4)));

		glVertexAttribDivisor(4, 1);
		glVertexAttribDivisor(5, 1);
		glVertexAttribDivisor(6, 1);
		glVertexAttribDivisor(7, 1);

And for sure, I call the draw command:

	glBindVertexArray(VAO);
	glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gIndirectBuffer);

	glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (GLvoid*)0, 3, 0);
	glBindVertexArray(0);

As I said before, it works but only rendered the first mesh of the buffer, so I’m thinking that I’m letting go something pretty obvious…
some idea that what could be?


#2

This should be the sum of prior values of indice[i], similar to how baseVert is calculated.


#3

Oh, thanks, I go it!

Ps. *%#$! the 30 minimum length value to post a reply…


#5

FYI: You don’t need to post a “thanks, I got it” message. You can just click the “solved” checkbox by the post that resolved your problem.


#6

Ok!, only that this forum is a little rare for me


#7

While not needed, it is good of the original poster to be appreciative for advice offered. The 30 character minimum is definitely a hindrance here. They should be able to say “thanks” and not have to be so *%#$! verbose about it!


#8

I said thanks in the first response, you must learn to read before sending critics, second: your forum sucks!


#9

Dude! I was agreeing with you!