VBO: GL_ELEMENT_ARRAY_BUFFER with tex UV coords ?

[/b]Hi,

I am attempting to write a small VBO demo.
In this demo I have a cube represented by the following structures.

	fVertex		arrCube_Vertices[] = {
		{  1.0f,  1.0f,  1.0f},	//0
		{  1.0f,  1.0f, -1.0f},	//1
		{  1.0f, -1.0f,  1.0f},	//2
		{  1.0f, -1.0f, -1.0f},	//3
		{ -1.0f,  1.0f,  1.0f},	//4
		{ -1.0f,  1.0f, -1.0f},	//5
		{ -1.0f, -1.0f,  1.0f},	//6
		{ -1.0f, -1.0f, -1.0f},	//7
	};
		
	fQuadIndex		arrCube_fQuadIndices[] = {		
		{ 0, 4, 5, 1},
		{ 0, 1, 3, 2},		
		{ 0, 2, 6, 4},
		{ 7, 3, 1, 5},
		{ 7, 6, 2, 3},
		{ 7, 5, 4, 6}
	};		
		
	fTexUV		arrCube_fTexUVs[] = {
		{0.0,0.0}, //0
		{0.0,1.0}, //1
		{1.0,0.0}, //2
		{1.0,1.0}, //3	
	};
		
	fTexQuad	arrCube_fTexQuadIndices[] = {
		{ 2, 3, 1, 0},
		{ 2, 3, 1, 0},
		{ 2, 3, 1, 0},
		{ 2, 3, 1, 0},
		{ 2, 3, 1, 0},
		{ 2, 3, 1, 0},
	};

I managed to render the cube without textures using GL_ELEMENT_ARRAY_BUFFER for the indexed quad faces in the arrCube_fQuadIndices array.

When I attempt to texture the cube using GL_ELEMENT_ARRAY_BUFFER,
I have incorrect texture mapping.

The code used for rendering is as follows:


		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnableClientState(GL_VERTEX_ARRAY);	
		
		glEnable(GL_TEXTURE_2D);
		glBindTexture( GL_TEXTURE_2D, oCube.m_idTexture );
		glClientActiveTexture(GL_TEXTURE0);
		
		glBindBuffer(GL_ARRAY_BUFFER, oCube.m_idVBOTexUVs);	
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oCube.m_idVBOTexQuadIndices);	
		glTexCoordPointer(2,GL_FLOAT,0,0);	

		glBindBuffer(GL_ARRAY_BUFFER, oCube.m_idVBOVertices);	
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oCube.m_idVBOQuadIndices);
		glVertexPointer(3, GL_FLOAT, 0, 0);		
		
		glDrawElements(GL_QUADS, SIZE_CUBE_INDICES, GL_UNSIGNED_INT, 0);
		
		glDisable(GL_TEXTURE_2D);
									
		glBindBuffer(GL_ARRAY_BUFFER, 0);	
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);

and the code used to create the VBOs :


		// Create a cube using VBO
		oCube.m_idVBOVertices = 0;
		nDataSize = sizeof(arrCube_Vertices);
		cout << nDataSize <<endl;
		target = GL_ARRAY_BUFFER;
		glGenBuffers( 1, &oCube.m_idVBOVertices);
		glBindBuffer( target, oCube.m_idVBOVertices);
		glBufferData( target, nDataSize, &arrCube_Vertices[0], GL_STATIC_DRAW);
		nBufferSize = 0;
		glGetBufferParameteriv(target,GL_BUFFER_SIZE,&nBufferSize);
		if(nDataSize != nBufferSize)
		{
			glDeleteBuffers(1, &oCube.m_idVBOVertices);
			oCube.m_idVBOVertices = 0;
			cout << "VBO creation failed for vertices
";
			exit(-1);
		}
		glBindBuffer( target, 0);				
		
		oCube.m_idVBOQuadIndices = 0;
		nDataSize = sizeof(arrCube_fQuadIndices);
		cout << nDataSize <<endl;
		target = GL_ELEMENT_ARRAY_BUFFER;
		glGenBuffers( 1, &oCube.m_idVBOQuadIndices);
		glBindBuffer( target, oCube.m_idVBOQuadIndices);
		glBufferData( target, nDataSize, &arrCube_fQuadIndices[0], GL_STATIC_DRAW);
		nBufferSize = 0;
		glGetBufferParameteriv(target,GL_BUFFER_SIZE,&nBufferSize);
		if(nDataSize != nBufferSize)
		{
			glDeleteBuffers(1, &oCube.m_idVBOQuadIndices);
			oCube.m_idVBOQuadIndices = 0;
			cout << "VBO creation failed for indices
";
			exit(-1);
		}		
		glBindBuffer( target, 0);
		
		oCube.m_idVBOTexUVs = 0;
		nDataSize = sizeof(arrCube_fTexUVs);
		cout << nDataSize <<endl;
		target = GL_ARRAY_BUFFER;
		glGenBuffers( 1, &oCube.m_idVBOTexUVs);
		glBindBuffer( target, oCube.m_idVBOTexUVs);
		glBufferData( target, nDataSize, &arrCube_fTexUVs[0], GL_STATIC_DRAW);
		nBufferSize = 0;
		glGetBufferParameteriv(target,GL_BUFFER_SIZE,&nBufferSize);
		if(nDataSize != nBufferSize)
		{
			glDeleteBuffers(1, &oCube.m_idVBOTexUVs);
			oCube.m_idVBOTexUVs = 0;
			cout << "VBO creation failed for uvs
";
			exit(-1);
		}
		glBindBuffer( target, 0);				
		
		oCube.m_idVBOTexQuadIndices = 0;
		nDataSize = sizeof(arrCube_fTexQuadIndices);
		cout << nDataSize <<endl;
		target = GL_ELEMENT_ARRAY_BUFFER;
		glGenBuffers( 1, &oCube.m_idVBOTexQuadIndices);
		glBindBuffer( target, oCube.m_idVBOTexQuadIndices);
		glBufferData( target, nDataSize, &arrCube_fTexQuadIndices[0], GL_STATIC_DRAW);
		nBufferSize = 0;
		glGetBufferParameteriv(target,GL_BUFFER_SIZE,&nBufferSize);
		if(nDataSize != nBufferSize)
		{
			glDeleteBuffers(1, &oCube.m_idVBOTexQuadIndices);
			oCube.m_idVBOTexQuadIndices = 0;
			cout << "VBO creation failed for uvindices
";
			exit(-1);
		}		
		glBindBuffer( target, 0);

Please help me understand the problem and find a solution.

Regards,
Anup

[/b]

Ok, I think I understand what your trying to do here but it’s a little off.

glBindBuffer(GL_ARRAY_BUFFER, oCube.m_idVBOTexUVs);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oCube.m_idVBOTexQuadIndices);
glTexCoordPointer(2,GL_FLOAT,0,0);

looks like your tying to use an index buffer to index through your texture coords and then use another index buffer to sort through your vertex positions. It’s a slight miss-understanding of how this works.

Position, Texture Coords, Color, etc… are all attribute of the vertex, and your index buffer indexes through them. So when you call the glBindBuffer(GL_ELEMENT_ARRAY,…) the second time by glVertexPointer, it’s override the first call. It should look something like this…

glBindBuffer(GL_ARRAY_BUFFER, oCube.m_idVBOTexUVs);
glTexCoordPointer(2,GL_FLOAT,0,0);

glBindBuffer(GL_ARRAY_BUFFER, oCube.m_idVBOVertices);
glVertexPointer(3, GL_FLOAT, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oCube.m_idVBOQuadIndices);

glDrawElements(GL_QUADS, SIZE_CUBE_INDICES, GL_UNSIGNED_INT, 0);

So your index buffer indexes through both the texture coords and the positions at the same time. Meaning, when the index buffer uses 0, it uses the first position element and the first texture coord.

It’s a common problem with simple meshes like a cube, because 1 vertex will need multiple different texture coords, so basicly you have to have 24 vertices for a cube with only 8 unique vertex positions. So index buffers don’t benifit you at all. They’re main strength is on high poly count models. You will always have duplicate vertices on UV seams, just the way it works.

If someone else has a better solution that would be great to. :slight_smile:

Hi PatriotBob,

Thank you for your clear reply.
I have changed my code to accomodate for the points you mentioned.
I am successfully able to use VBO now.

With Kind Regards,
Anup