VBO with index array woes

Started by
1 comment, last by 3dmania 16 years, 3 months ago
I have been trying to convert some intermediate terrain generating into VBO, I am just learning it but its producing unfavorable results. I am not sure what to populate the index array with, or if i am populating it correctly via the offsets or if the size of the memory allocated is correct. When i run the app, something shows up quickly add disappears,but it doesnt have the shape of the terrain. It sort of resembles a single triangle that is elongated as a huge plane. I populate the index array with the vertices and normals like so

//vertex index offset
//vertices
unsigned int vertOffset = 0;
//normals
unsigned int normalOffset = totalVertices * 3;
/*ommited nested for loop going through z < height and x < width*/
//fill index buffer
//vertex
terrainIndexArray[vertOffset] = float(x);
terrainIndexArray[vertOffset+1] = y;
terrainIndexArray[vertOffset+2] = float(z);
vertOffset +=3;
	
//Normal
terrainIndexArray[normalOffset] = nodeNormal.x;
terrainIndexArray[normalOffset+1] = nodeNormal.y;
terrainIndexArray[normalOffset+2] = nodeNormal.z;
normalOffset +=3;


I am just using the actual point position and the normal, when i initialize the VBO it looks like this

totalVertices = length * width;

  terrainVertices = new Vertex[totalVertices];
  //terrainTextures = new TexUV[totalVertices];
  //terrainColors = new Vertex[totalVertices];
  terrainNormals = new Vector3D[totalVertices];

  terrainIndexArray = new float[totalVertices * 6 * sizeof(float)];
  
  //Create buffer object Arrays
  glGenBuffersARB(currentVBOIndex,&terrainVBO);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, terrainVBO);
  nextVBOIndex();

  // create a data store large enought for all but unInitialize		
  //We will give the same chunks over and over agian so we need them in app and gpu memory
glBufferDataARB(GL_ARRAY_BUFFER_ARB, totalVertices * 6 * sizeof(float),//3 vertices,3normals,3color 2 textures 
	  NULL, GL_DYNAMIC_DRAW_ARB);				     //11
  
//Vertex data
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0,
					 totalVertices * 3 * sizeof(float), terrainVertices);
 
//Normals
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, totalVertices * 3 * sizeof(float),
					 totalVertices * 3 * sizeof(float), terrainNormals);

//index buffer
glGenBuffersARB(currentVBOIndex, &terrainIndexBO);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, terrainIndexBO);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, 
				  totalVertices * 6 * sizeof(float), 
				  terrainIndexArray, GL_DYNAMIC_DRAW_ARB);
nextVBOIndex();


When time to draw the data

glEnableClientState( GL_VERTEX_ARRAY );						// Enable Vertex Arrays
glEnableClientState( GL_NORMAL_ARRAY );
glEnableClientState( GL_INDEX_ARRAY );


if(GL_ARB_vertex_buffer_object)
{
  glBindBufferARB( GL_ARRAY_BUFFER_ARB, terrainVBO );
  //vertices
  glVertexPointer( 3, GL_FLOAT, 0,  BUFFER_OFFSET(0) );		// Set The Vertex Pointer To The Vertex Buffer
  //Normals;
  glNormalPointer(GL_FLOAT, 0,  BUFFER_OFFSET(totalVertices * 3 * sizeof(float)) );
  //index buffer
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrainIndexBO);
} 
// Render
glDrawElements( GL_TRIANGLES,totalVertices * 6 * sizeof(float),GL_UNSIGNED_INT,terrainIndexArray);	// Draw All Of The Triangles At Once

//unbinded
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Disable arrays
glDisableClientState( GL_VERTEX_ARRAY );						// Enable Vertex Arrays
glDisableClientState( GL_NORMAL_ARRAY );
// Enable Texture Coord Arrays
glDisableClientState( GL_INDEX_ARRAY );


Advertisement
I think you are misunderstanding the concept of indexed rendering.

Basically you have a list of vertices, normals, and other stuff
and an index buffer that says which points belong to which primitive.
This buffer usually stores unsigned integer offsets into the vertex buffer.

So say you have a buffer that contains say 20 vertices
Your index buffer will be a list containing offset into this buffer.
0 1 2 3 2 1 4 5 6 ...
if you render this list using GL_TRIANGLES every three indices form a primitive.

Hope this helps.

Here is a quick bit of code for you to help explain how todo it.

/////////////////////////////////////////////////////////////////////////////////// init function//////////////////////////////////////////////////////////////mVertexCount = mTerrainSize * mTerrainSize;mIndiceCount = (mTerrainSize-1)*(mTerrainSize-1)*6;GLfloat *vPtr = mVertexBuffer->mapData();for(size_t z=0; z<mTerrainSize; z++ ){	for(size_t x=0; x<mTerrainSize; x++ )	{		//position		*vPtr++ = x;		*vPtr++ = mHeightMap->getHeight(x,z);		*vPtr++ = z;		//texture coords		*vPtr++ = x/mTerrainSize;		*vPtr++ = z/mTerrainmSize;	}}mVertexBuffer->unmapData();//now the index array////we are using GL_TRIANGLES as the primitive.////be aware of the limit of 16bit intergers ;-) ..u may need to use 32bit,depending on size of the terrain and if/how you break it upGLushort *iPtr = static_cast<GLushort*>(mIndexBuffer->mapData());i=0;for(size_t z=0; z<mTerrainSize-1; z++ ){	for(size_t x=0; x<mTerrainSize-1; x++ )	{	//triangle 1	*iPtr++ = x +(mTerrainSize *z);	*iPtr++ = x + (mTerrainSize * (z+1));	*iPtr++ = (x+1) + (mTerrainSize * (z+1));	//triangle 2	*iPtr++ = (x+1) + (mTerrainSize* (z+1));	*iPtr++ = (x+1) + (mTerrainSize * z);	*iPtr++ = x +(mTerrainSize *z);	}}mIndexBuffer->unmapData();//Set our vertex buffer offset and stride,multiply by 4 to convet to bytesmBufferStride = (3 + 2)*4; //we have 3 lots of verts and 2 lots of tex coordsmVertexOffset = 0*4;mTextureOffset = 3*4;/////////////////////////////////////////////////////////////////////////////////// rendering function////////////////////////////////////////////////////////////////after enabling all the states and binding the buffersglVertexPointer( 3, GL_FLOAT, mBufferStride, BUFFER_OFFSET(mVertexOffset) );glTexCoordPointer(2,GL_FLOAT,mBufferStride,BUFFER_OFFSET(mTextureOffset));glDrawElements(GL_TRIANGLES,mIndiceCount,GL_UNSIGNED_SHORT,BUFFER_OFFSET(0));


hope that helps

This topic is closed to new replies.

Advertisement