Sign in to follow this  
Rui

problem with VBO's

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[i] = flX- ( terrainGridWidth / 2 ); i++;
				aVertices[i] = terrainGetHeight(flX,flZ);i++;
				aVertices[i] = flZ - ( terrainGridLength / 2 ); i++;

			}
		}
	}


	// Get Pointers To The GL Functions
		glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB");
		glBindBufferARB = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB");
		glBufferDataARB = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB");
		glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffersARB");

	// Generate And Bind The Vertex Buffer
	glGenBuffersARB( 1, &verticesVBO );					// Get A Valid Name
	glBindBufferARB( GL_ARRAY_BUFFER_ARB, verticesVBO );			// Bind The Buffer
	// Load The Data
	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 this post


Link to post
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 this post


Link to post
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.

thanks for the reply

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
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.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Rui
asks 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 this post


Link to post
Share on other sites
Quote:
Original post by VerMan
hi 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 this post


Link to post
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 this post


Link to post
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 2
Triangle 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 this post


Link to post
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 this post


Link to post
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()).

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