These VBO indices are still confusing me...

Started by
2 comments, last by sirSolarius 19 years, 2 months ago
Sorry for all the posts, but I feel like I've done everything I could possibly do, and a little more, to fix this situation. I want to load my terrain into the graphics card as a VBO, and then to use indices to draw it. Maybe I don't understand how indices work, but can anyone look at this code for me? First, I load the vertices:

	for(int x=0; x < m_mapWidth; ++x)
	{
		for(int z=0; z < m_mapLength; ++z)
		{
			int j=x+z*m_mapWidth;

			textureData[2*j]=x/((float)m_mapWidth);
			textureData[2*j+1]=1.0-(z/((float)m_mapLength));

			mapData[3*j]=x;
                        mapData[3*j+1]=GetHeight(x, z);
			mapData[3*j+2]=z;
		}
	}

So that should mean that if I go to mapData[3*(x+z*m_mapWidth)] then I have the point (x, Height(x, z), z), right? So then if I want to draw these points as a triangle strip, I need to draw them like:

5---4
|-/-|
3/--2
|-/-|
1/--0

Right? If so, then I don't understand why the following index doesn't work:

	int index=0;
	for(int z=0; z < m_mapWidth; ++z)
	{
		for(int x=0; x < m_mapLength; ++x)
		{
			m_indices[index++]=x+(z+1)*m_mapLength;
			m_indices[index++]=x+z*m_mapLength;
		}
	}

I then draw (or try to draw) the terrain using glDrawElements(GL_TRIANGLE_STRIP, m_mapLength*m_mapWidth*2, GL_UNSIGNED_SHORT, (GLvoid*)m_indices) Where am I going wrong? The end result is a strip of correct terrain down the x-axis, but then there's a big trianglular prism of terrain that surrounds it, and a bunch of junk everywhere. Thanks for the help, this is really frustrating me!
Advertisement
int j=x+z*m_mapWidth;

I am sure this is not the only problem with your code, but that statement should be
int j = x * m_mapWidth + z;//and thismapData[3*(x+z*m_mapWidth)];//should bemapData[3*(x * m_mapWidth + z];


And I am not sure if you are using CCW or CW rotations you might want to check that.

and your index buffer is setup wrong
I would use this pattern instead easier to read...


1---3---5
|-\-|-\-|
0--\2--\4

int index = 0;int current_index = 0;for(int z = 0; z < m_mapWidth; z++){     for(int x = 0; x < m_mapLength; x++)     {        current_index = z * m_mapWidth+ x;        m_indices[index++] = current_index;	m_indices[index++] = current_index + m_mapWidth;     }}
Still doesn't work... it's now a bunch of scattered strips that run down the z-axis...

Just to make sure that I didn't mistype anything, here is the full code that I have right now:
void HeightMap::LoadMap(std::string mapfile){ //....(Height loading, etc. done up to this point).....        float *mapData=new float[m_mapLength*m_mapWidth*3];		float *textureData=new float[m_mapLength*m_mapWidth*2];	m_indices=new unsigned short[m_mapLength*m_mapWidth*2];		m_tallestPoint=-HEIGHT_CONSTANT;	float tempHeight;	for(int x=0; x < m_mapWidth; ++x)	{		for(int z=0; z < m_mapLength; ++z)		{			int j=x*m_mapWidth+z;			textureData[2*j]=x/((float)m_mapWidth);			textureData[2*j+1]=1.0-(z/((float)m_mapLength));			mapData[3*j]=x;			if((tempHeight=mapData[3*j+1]=GetHeight(x, z)) > m_tallestPoint)				m_tallestPoint=tempHeight;			mapData[3*j+2]=z;		}	}	int index=0;	for(int z=0; z < m_mapWidth; ++z)	{		for(int x=0; x < m_mapLength; ++x)		{			unsigned short j = x * m_mapWidth+ z;			m_indices[index++]=j;			m_indices[index++]=j+m_mapWidth;		}	}	// send to a VBO	glGenBuffersARB(1, &m_vboNum);	glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vboNum);	//store data into buffer object, which is accelerated gc memory 	//when available	glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(mapData[0])*m_mapLength*m_mapWidth*3, 							mapData, GL_STATIC_DRAW_ARB);	// Generate And Bind The Texture Coordinate Buffer	glGenBuffersARB( 1, &m_texVBO );	glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_texVBO );	// Load The Data	glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_mapLength*m_mapWidth*2*sizeof(float), 										textureData, GL_STATIC_DRAW_ARB );	delete [] textureData;	delete [] mapData;}void HeightMap::draw(){	glColor3f(1, 1, 1);	if(!m_heightData)		return;	glEnableClientState( GL_VERTEX_ARRAY );						// Enable Vertex Arrays	glEnableClientState( GL_TEXTURE_COORD_ARRAY );				// Enable Texture Coord Arrays	glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_vboNum );	glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );		// Set The Vertex Pointer To The Vertex Buffer	glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_texVBO );	glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );		// Set The TexCoord Pointer To The TexCoord Buffer	glDisable(GL_CULL_FACE);	m_texture->Bind();		glDrawElements(GL_TRIANGLE_STRIP, m_mapLength*m_mapWidth*2, GL_UNSIGNED_SHORT, 																(GLvoid*)m_indices);	m_texture->Unbind();	glEnable(GL_CULL_FACE);	// Disable Pointers	glDisableClientState( GL_VERTEX_ARRAY );				// Disable Vertex Arrays	glDisableClientState( GL_TEXTURE_COORD_ARRAY );			// Disable Texture Coord Arrays	}


This is just such a confusing and frustrating problem for me... I've been stuck just trying to figure out how to brute force this terrain using indices for about 4 days now. Before I was just storing the vertices in order (with repeated verts, etc.) and it was working perfectly. Obviously that method is wasteful of graphics memory, so I'd like to switch, but I honestly can't figure out what's wrong.

Thanks!
EDIT: Solved it, finally.

It turns out that the unsigned short couldn't hold the vertex numbers... I up'd it to an unsigned int and it works.

Geez, what a trip.

Thanks to everyone for the help!

[Edited by - sirSolarius on February 8, 2005 9:40:01 PM]

This topic is closed to new replies.

Advertisement