• Advertisement
Sign in to follow this  

VBO with index array woes

This topic is 3722 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
unsigned int vertOffset = 0;
unsigned int normalOffset = totalVertices * 3;
/*ommited nested for loop going through z < height and x < width*/
//fill index buffer
terrainIndexArray[vertOffset] = float(x);
terrainIndexArray[vertOffset+1] = y;
terrainIndexArray[vertOffset+2] = float(z);
vertOffset +=3;
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
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, terrainVBO);

  // 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
					 totalVertices * 3 * sizeof(float), terrainVertices);
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);
				  totalVertices * 6 * sizeof(float), 
				  terrainIndexArray, GL_DYNAMIC_DRAW_ARB);

When time to draw the data
glEnableClientState( GL_VERTEX_ARRAY );						// Enable Vertex Arrays
glEnableClientState( GL_NORMAL_ARRAY );
glEnableClientState( GL_INDEX_ARRAY );

  glBindBufferARB( GL_ARRAY_BUFFER_ARB, terrainVBO );
  glVertexPointer( 3, GL_FLOAT, 0,  BUFFER_OFFSET(0) );		// Set The Vertex Pointer To The Vertex Buffer
  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

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

Share this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites
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++ )
*vPtr++ = x;
*vPtr++ = mHeightMap->getHeight(x,z);
*vPtr++ = z;
//texture coords
*vPtr++ = x/mTerrainSize;
*vPtr++ = z/mTerrainmSize;

//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 up

GLushort *iPtr = static_cast<GLushort*>(mIndexBuffer->mapData());
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);

//Set our vertex buffer offset and stride,multiply by 4 to convet to bytes
mBufferStride = (3 + 2)*4; //we have 3 lots of verts and 2 lots of tex coords
mVertexOffset = 0*4;
mTextureOffset = 3*4;

//////////////////// rendering function
//after enabling all the states and binding the buffers
glVertexPointer( 3, GL_FLOAT, mBufferStride, BUFFER_OFFSET(mVertexOffset) );


hope that helps

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement