PDA

View Full Version : Problems with indexed VBO



Shelling
04-20-2009, 10:37 AM
Hey guys,

I've a little problem with an indexed vbo. The call to glDrawElements is causing a crash.


glDrawElements(GL_TRIANGLES,CurMesh[i]->GetIndexCount(),GL_UNSIGNED_INT,0);
That's the call. CurMesh[i]->GetIndexCount() returns the number of indices, in this case 36. The Mesh is a simple Cube, so it has only 8 vertices and is made of triangles, which sums up to 36 indices.

The code to build the vbo looks like this:

glGenBuffers(1,&VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER,VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, nVertices*12,pVertices,GL_STATIC_DRAW);

glGenBuffers(1,&NormalBuffer);
glBindBuffer(GL_ARRAY_BUFFER,NormalBuffer);
glBufferData(GL_ARRAY_BUFFER, nNormals*12,pNormals,GL_STATIC_DRAW);

glGenBuffers(1,&IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndexes*4, pIndexes, GL_STATIC_DRAW);

nNormals holds the number of normals(36, one normal for each index) and nVertices holds the number of vertices (8, it's a simple cube). Both values are multiplied by 12 (3 floats and 4 bytes).

Can you guys help me? I have a book about this next to me, but I don't see any mistakes...

Thanks in advance
bye
Shelling

Ido_Ilan
04-20-2009, 12:11 PM
Hi,

1. glBufferData don't know your type for normal, vertex, or index, You must pass the size of your array in bytes. if you have one normal (x,y,z) of type float, the size is sizeof(float) * 3.
2. Did you try switching try vertex array? did you saw the cube?

Ido

Shelling
04-20-2009, 12:22 PM
Hi,

thanks for your answer :)

1. The size in bytes should be correct. sizeof(float) returns 4 and multiplied by 3 it's 12, so instead of call sizeof to get a value I already know, I write down the multiplication directly.

2. Unfortunatly, I can't try that. The data is available only in indexed form.

I checked the values again, everything seems to be ok. Is there anything I forgot?

Maybe it will be usefull for you, to see the whole render call:

glBindBuffer(GL_ARRAY_BUFFER,CurMesh[i]->GetVertexBuffer());
glVertexPointer(3,GL_FLOAT,0,0);

glBindBuffer(GL_ARRAY_BUFFER,CurMesh[i]->GetNormalBuffer());
glNormalPointer(GL_FLOAT,0,0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,CurMesh[i]->GetIndexBuffer());
glDrawElements(GL_TRIANGLES,CurMesh[i]->GetIndexCount(),GL_UNSIGNED_INT,0);

I'm sorry, I forgot this last time...

bye
Shelling

Ido_Ilan
04-20-2009, 12:38 PM
1. The size in bytes should be correct. sizeof(float) returns 4 and multiplied by 3 it's 12, so instead of call sizeof to get a value I already know, I write down the multiplication directly.

OK, I see.



2. Unfortunatly, I can't try that. The data is available only in indexed form.


You can still use vertex array with index array.
Just pass pIndexes to glDrawElements instead on null.

Also does CurMesh[i]->GetIndexCount() return the number of indexes or the number of bytes in the array?

Ido

dletozeun
04-20-2009, 01:01 PM
Did you enable client side vertex array capabilility calling, before suppling vertices and indices data:

glEnableClientState( GL_VERTEX_ARRAY );

Shelling
04-20-2009, 01:12 PM
Hi

thanks again for your effort.

CurMesh[i]->GetIndexCount() returns the number of indexes.

I tried to use a vertex array now, it still crashes.

glDrawElements(GL_TRIANGLES,CurMesh[i]->GetIndexCount(),GL_UNSIGNED_INT,CurMesh[i]->GetIndexPointer());

Do I have to multiply CurMesh[i]->GetIndexCount() by 4 (sizeof(int)) as well?

bye
Shelling

dletozeun
04-20-2009, 01:38 PM
Have you read what I have posted?

Can you trace the code and see where it crashes precisely? Vertex_buffer_object extension might be not successfully loaded.

To not use vbos, you do not have to call glBindBuffer and glBufferData. Just give to gl*Pointer the actual data location in system memory instead of an offset. This way you will see if vbo is actually supported.

And read the man pages to understand each function parameters:
http://www.opengl.org/sdk/docs/man/

Shelling
04-20-2009, 02:16 PM
Ah, sorry dletozeun, haven't read your post yet. GL_VERTEX_ARRAY is enabled, yes. I load the extensions with glew, as far as i know vbos are in core in version 2.1, so i relied on the fact, that it would be loaded successfully.

However, i just checked if GLEW_ARB_vertex_buffer_object is available and glew tells me it is. But it also tells me that GLEW_ARB_vertex_array_object isn't available. This is probably the reason why it crashed some minutes ago while trying vertex arrays...
To be honest, i'm a bit confused now.

I will look through the documentation, thanks for the advice, i hope it helps somehow :)

Is there any way to solve that problem since vertex array objects aren't supported? i hope so...

bye
Shelling

dletozeun
04-20-2009, 02:39 PM
No, VAO is not what you think! :)
http://www.opengl.org/registry/specs/ARB/vertex_array_object.txt

What Ido Ilan and I meant with "vertex array" is simply giving the vertex attributes (position, normal, etc) to Opengl without using vbos.

You can do this setting data location to gl*Pointer as an adress in the system memory. Then calling glDrawArrays, the driver will read the vertex data directly in the system memory then feed the gpu with it.
When you use vbos, you create a buffer directly managed by the opengl driver and update its content calling for example glBufferData or mapping the buffer data. Since the buffer is handled by the driver, this one may speed up memory transfers/reads/writes by putting the data in system or video memory depending of the buffer use.

Good reading:
http://www.opengl.org/wiki/VBO

Shelling
04-20-2009, 03:25 PM
At first, guys, you are awesome, thanks for you patient :)

Oh, i understood what you meant then :)

glVertexPointer(3,GL_FLOAT,0,CurMesh[i]->GetVertexPointer());
glDrawArrays(GL_TRIANGLES,0,CurMesh[i]->GetVertexCount());

However, even this crashes during the call of glDrawArrays. The problem is CurMesh[i]->GetVertexCount() returns 8, so OpenGL can't finish the last triangle because 1 vertex is missing.

So i'm using the index pointer

glVertexPointer(3,GL_FLOAT,0,CurMesh[i]->GetVertexPointer());
glDrawElements(GL_TRIANGLES,CurMesh[i]->GetIndexCount(),GL_UNSIGNED_INT,CurMesh[i]->GetIndexPointer());
this, however, crashes during the call of glDrawElements. I decided to check the IndexArray and to which data of the vertexarray it refers. The result was normal, 36 floating point numbers in the range of -2.1 to -0.2. The indices are all unsigned ints in a range of 0 to 7, it looks pretty good.

However, and that's definently a problem, the next 2 objects have an indexcount of several thousands, a bit too much ;)

But well, the first object, the cube, has normal data...

bye
Shelling

dletozeun
04-20-2009, 03:47 PM
Something came up to my mind... You did not forget to previously allocate buffer memory calling glBufferData for each generated vbo, did you?

If you can provide a little ready to compile code snippet that illustrates what you are doing I may take a look at it when I would have time.

Shelling
04-20-2009, 04:19 PM
Sure, i'll do my best, but i'll need some time to do that...