# problem with VBO's

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

## Recommended Posts

Hi. i'm trying to render a terrain using vbo's, everything compiles fine but when i try to run the program i get a run-time error: "... access violation reading location...". i'm using VC++ 2008 express edition, if that helps. i'm posting the code here to see if you guys can help. something tells me that it's a rookie mistake.
int vbosDL() {

GLuint build_aVerticesDL;

int z,x,i=0;
float* aVertices = new float[num_vertices*3];
GLuint verticesVBO;
float flX, flZ;

// Create the id for the display list
build_aVerticesDL = glGenLists(1);

// create the display list
glNewList(build_aVerticesDL,GL_COMPILE);

for( z = 0; z < terrainGridLength; z ++ )
{
for( x = 0; x < terrainGridWidth; x++ )
{
for( int nTri = 0; nTri < 6; nTri++ )
{
flX = (float)x + ((nTri == 1 || nTri == 2 || nTri == 5) ? 1 : 0);
flZ = (float)z + ((nTri == 2 || nTri == 4 || nTri == 5) ? 1 : 0);
// Set The Data, Using terrainGetHeight To Obtain The Y Value
aVertices = flX- ( terrainGridWidth / 2 ); i++;
aVertices = terrainGetHeight(flX,flZ);i++;
aVertices = flZ - ( terrainGridLength / 2 ); i++;

}
}
}

// Get Pointers To The GL Functions

// Generate And Bind The Vertex Buffer
glGenBuffersARB( 1, &verticesVBO );					// Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, verticesVBO );			// Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB, num_vertices*3*sizeof(float), aVertices, GL_STATIC_DRAW_ARB );

glEnableClientState(GL_VERTEX_ARRAY);

glBindBufferARB( GL_ARRAY_BUFFER_ARB, verticesVBO);
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );

glDrawArrays( GL_TRIANGLES, 0, num_vertices*3);

glDisableClientState( GL_VERTEX_ARRAY );

glEndList();

// return the list index so that the application can use it
return(build_aVerticesDL);
}


num_vertices is a global variable (to this file only), and num_vertices=terrainGridLength*terrainGridWidth*6, where terrainGridWidth and terrainGridLength are the width and length of the heightmap. hope you guys can help, this is for a school project for tommorrow.. :S

##### Share on other sites
Why not step through with the debugger and find out which line the access violation is happening on?

Also, are you aware that VBO != DL? Are you trying to use a Vertex Buffer Object, or a Display List?

##### Share on other sites
yeah, i know they are different things. i can try to do it without the display list but i dont think it'll change things. the problem with using the debugger is this: "There is no source code available for the current location.", and asks me if i want to look at the disassembly.. which i dont, and i dont think anyone would.

##### Share on other sites
Perhaps your ATI does not support VBO & FBO. Try this tool to find out: http://www.realtech-vr.com/glview/

##### Share on other sites
Quote:
 Original post by Ruiyeah, i know they are different things. i can try to do it without the display list but i dont think it'll change things. the problem with using the debugger is this: "There is no source code available for the current location.", and asks me if i want to look at the disassembly.. which i dont, and i dont think anyone would.thanks for the reply

Set a break-point in the code before the access violation happens (at the top of your vbosDL() method), and step through a line at a time. Don't wait for the violation to happen before attempting to debug it.

##### Share on other sites
yeah, i did that mantear, and found the problem to be in the glDrawArrays command.
Also, i ran the tool suggested by VerMan and discovered that although vertex buffer object is supported, frame buffer object is not. i dont know if that could be the problem.

##### Share on other sites
You have all your VBO stuff in between calls to glNewList() and glEndList(). I don't know if that is valid. Also, try calling glGetError() before your call to glDrawArrays and see if it returns any error codes.

I'm pretty sure you don't need frame buffer object support to do vertex buffer objects, so that shouldn't matter.

##### Share on other sites
i have removed the display list code and added the glGetError() call. it always returns zero, no luck there.

##### Share on other sites
hi Rui,
I'm not sure but this call:

glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );

looks strange. My guess is that it should be something like:

glVertexPointer( 3, GL_FLOAT, 0, aVertices );

##### Share on other sites
Quote:
 Original post by Ruiasks me if i want to look at the disassembly.. which i dont, and i dont think anyone would.

I do, sometimes...

Anyway, next time you get there, search for a window named "Call Stack". It will show you the functions which have been called, and you can see in which point your code crashed.

##### Share on other sites
Quote:
 Original post by VerManhi Rui, I'm not sure but this call: *** Source Snippet Removed ***looks strange. My guess is that it should be something like:*** Source Snippet Removed ***

Nope, the first call is correct. The second call is for client-side vertex arrays (last parameter is a pointer). The first is for server-side VBOs (last parameter is a byte offset).

The code looks correct, but the num_vertices variable has me worried. Triple-check that "num_vertices * 3 == z * x * 6".

##### Share on other sites
Quote:
 Original post by Rui...num_vertices=terrainGridLength*terrainGridWidth*6,where terrainGridWidth and terrainGridLength are the width and length of the heightmap....

Quote:
 Original post by Fiddler...Triple-check that "num_vertices * 3 == z * x * 6".

So, nope. They're not the same. But i got to admit i'm lost now, what do suggest i change in the code?

##### Share on other sites
Just remove the "* 3". You are instructing OpenGL to upload 66% more vertices than you have allocated, i.e. an out-of-bounds memory access.

After this change, your code won't crash - but it won't work, either. If you change glDrawArrays to render points, you should see that the points are in the correct places. Now all you need to do is instruct OpenGL how to form triangles out of these points.

Your best bet, is to use an element buffer (aka index buffer). This is a second VBO of type "GL_ELEMENT_ARRAY_BUFFER". Its data is int[] or short[] and consist of offsets into the vertex buffer. You can visualize it like this:

int element_array[] = { 0, 1, 2, 2, 3, 1, ...};

Which means:

Triangle 0 is formed by vertices 0, 1 and 2Triangle 1 is formed by vertices 2, 3 and 1...

Lookup glDrawElements on how to use it (any VBO tutorial worth its salt will cover this).

##### Share on other sites
remove where, exactly? i guess it would be in the glDataBufferARB call, but it didn't work. Tried to replace that with sizeof(aVertices), to make sure it uploads the same space as allocated, same result. always crashes :S

##### Share on other sites
Sorry, I should have paid more attention to your code. Suggestions:

   ...   std::vector<float> aVertices = std::vector<float>();   ...            aVertices.push_back(flX - terrainGridWidth / 2);            aVertices.push_back(terrainGetHeight(flX, flY));            aVertices.push_back(flY - terrainGridLength / 2);   ...   glBufferDataARB(GL_ARRAY_BUFFER_ARB, aVertices.size() * sizeof(float), &aVertices[0], GL_STATIC_DRAW_ARB);   ...   glDrawArrays(GL_TRIANGLES, 0, aVertices.size());

Edit: As an aside, if you are targeting OpenGL 1.5+, you don't need to use the ARB versions of the functions (i.e. you can use glBufferData() instead of glBufferDataARB()).