Jump to content
  • Advertisement
Sign in to follow this  
ashstampede

VBO with index array woes

This topic is 3907 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
//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 );


Share this post


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

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++ )
{
//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 up

GLushort *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 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) );
glTexCoordPointer(2,GL_FLOAT,mBufferStride,BUFFER_OFFSET(mTextureOffset));

glDrawElements(GL_TRIANGLES,mIndiceCount,GL_UNSIGNED_SHORT,BUFFER_OFFSET(0));




hope that helps

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!