Sign in to follow this  
sirSolarius

These VBO indices are still confusing me...

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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 this
mapData[3*(x+z*m_mapWidth)];
//should be
mapData[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;
}
}


Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this