Archived

This topic is now archived and is closed to further replies.

MARS_999

I need help on setting up VBO's in my code

Recommended Posts

MARS_999    1627
I have looked all over the net for a good tutorial on how to use "GL_ARB_vertex_buffer_object" as an extension and haven''t found one. I have a Radeon 9700. I would appreciate any help on find a good tutorial or some example code. Thanks

Share this post


Link to post
Share on other sites
Trienco    2555
hm... isnt it sad when this ( http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt ) will not just explain them a lot better but also offer about 4 times as many examples?

Share this post


Link to post
Share on other sites
Sneftel    1788
Yeah, don''t bother with tutorials... just read the extension spec. You''ll get a much better feel for VBOs.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
MARS_999    1627
Ok I am assuming this because it says arrays that I can use 3D arrays with VBO's.

float terrain[y][x][z];

struct Vertex
{
float x;
float y;
float z;
};

Vertex terrain[MAP_Z][MAP_X];


Can I use multi-dimension arrays with VBO's?
Will their be any performance decrease for 3D arrays? I am also assuming I can't send a array of structures?

[edited by - Mars_999 on August 7, 2003 3:58:16 PM]

Share this post


Link to post
Share on other sites
MARS_999    1627
Ok, I got the code up and running for VBO's. I am using vertex arrays and trying to use VBO's also and my FPS drop about 80fps!!! What gives? Don't you have to use vertex arrays first before you can use VBO's? Here is my code.


//init functino

glGenBuffersARB(1, &vertex_buffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, (sizeof(float) * 3) * MAP_Z * MAP_X, terrain, GL_STATIC_DRAW_ARB);

glGenBuffersARB(1, &indices_buffer);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indices_buffer);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, (sizeof(unsigned int) * 2) * MAP_Z * MAP_X, indices, GL_STATIC_DRAW_ARB);

//draw function

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indices_buffer);

for(int z = 0; z < MAP_Z - 1; z++)
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &indices[z * MAP_X * 2]);

//and of course I have deleted the buffers also



What is wrong with my code? I get a atioglxx.dll access violation error if I remember right. Do I need to setup my arrays with dynamic memory? Thanks

[edited by - Mars_999 on August 16, 2003 11:59:04 PM]

Share this post


Link to post
Share on other sites
Trienco    2555
somehow im missing a call to glvertexpointer. also i trust your indices are all below 65xxx and with deleting the buffers you mean deleting them when you close the app.

Share this post


Link to post
Share on other sites
Raloth    379
Don''t call GenBuffers every single time you render. Do it once at initialization, and then for rendering all you have to do is bind your buffers and call DrawElements.

Share this post


Link to post
Share on other sites
MARS_999    1627
quote:
Original post by Trienco
somehow im missing a call to glvertexpointer. also i trust your indices are all below 65xxx and with deleting the buffers you mean deleting them when you close the app.


Do I need to call glVertexPointer() everytime in my rendering function? I call it in my initialization function. And no my indices isn't below 65k its 132k so what am I to do about that? My vertex array isn't either.

struct Vertex
{
float x,y,z;
};
Vertex terrain[256][256] = {0};
thats 65k elements and 786k bytes right?
and
indices is
unsigned int indices[MAP_Z * MAP_X * 2];
thats 256*256*2 = 131k elements or 524k bytes right?

So my indices would have to be reduced to 65k how is that going to work? Could I make the indices like my Vertex struct using two floats such as
struct Vertex2
{
unsigned int x;
unsigned int y;
};

Vertex2 indices[256][256] = {0};

or not?

Also I get the error on this line??
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &indices[z * MAP_X * 2]);


[edited by - Mars_999 on August 17, 2003 8:58:40 PM]

Share this post


Link to post
Share on other sites
Trienco    2555
quote:
Original post by MARS_999
Do I need to call glVertexPointer() everytime in my rendering function? I call it in my initialization function.



in theory the driver is allowed to move the buffer around as much as he likes. so it would be safer even though i wouldnt think thats the problem (as long as you set the pointer AFTER finishing setting up the buffer and not before or in the middle of it).

quote:

And no my indices isn''t below 65k its 132k so what am I to do about that? My vertex array isn''t either.



then it would be time to check if your card can handle indices higher than 65k. on of those glGet functions will return the max index.

quote:

Vertex terrain[256][256] = {0};



i might be wrong, but i think this would set the first element to 0 and ignore the rest.

quote:

So my indices would have to be reduced to 65k how is that going to work?



your terrain is made of more than 130k triangles and you probably shouldnt render it all at once anyway (how would you remove the parts you cant see?). and having smaller parts requires lower indices.

Share this post


Link to post
Share on other sites
python_regious    929
Technically VBO doesn''t have index limits. However, the NV_vertex_array_range(2) extension did. It seems that the nVidia drivers are still a bit buggy when it comes to indices in VBO that are over the VAR limits. For clarity, the limits are:

65536 for <= GF2.
1048576 or there abouts for >= GF3.

Newer drivers should eliminate this problem.

Trenco:

You can just cull indices. So effectively, you have one large vertex array, and a quadtree ( or whatever ) of indices. But I agree with reducing the size of vertex arrays. Split the terrain up into multiple "chunks", each with it''s own vertex array.

You have to remember that you''re unique, just like everybody else.

Share this post


Link to post
Share on other sites
python_regious    929
Wait... I just noticed that you''re using ATI hardware. I have no idea if it even has index limits with VAO, if so, then it could have the same problem with VBO as nVidia does.



You have to remember that you''re unique, just like everybody else.

Share this post


Link to post
Share on other sites
Trienco    2555
quote:
Original post by python_regious
Trenco:

You can just cull indices. So effectively, you have one large vertex array, and a quadtree ( or whatever ) of indices. But I agree with reducing the size of vertex arrays. Split the terrain up into multiple "chunks", each with it''s own vertex array.


id probably just leave the vertex buffer as it is, adapt the index buffer and change the offset into the vertex buffer. but i thought id rather not talk about how to do it as it might be a little confusing. also im not sure if i should advice saving memory by "spreading" your indices over half the vertex buffer.

Share this post


Link to post
Share on other sites
MARS_999    1627
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &temp);

After using this function I got this 786,432 as a value. Well that is the value of my struct 256*256*12 = 786,432. What does glGetBufferParameterivARB do for sure? Does it tell me the size of my object or the max amount my object can be? Also should I be using this for my index array? glIndexPointer()? I thought that this was for colors? I seen an example now that is using it for index arrays? Because I am not using it. Thanks

[edited by - Mars_999 on August 20, 2003 2:10:57 AM]

Share this post


Link to post
Share on other sites
MARS_999    1627
Now when I run my code through debug mode and reduce my array size to 128x128 I am well within 65k now and my program doesn''t crash at glDrawElements() anymore but crashes when it comes to SwapBuffers()??? I completely lock my system up now. Any ideas? Here is my code for


void CTerrain::DrawTerrain(unsigned int *texture)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buffer);

/* glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS_DETAIL]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
*/

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glEnable(GL_RESCALE_NORMAL);
glEnableClientState(GL_VERTEX_ARRAY);
// glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glEnableClientState(GL_NORMAL_ARRAY);

glVertexPointer(3, GL_FLOAT, 0, terrain);
// glTexCoordPointer(2, GL_FLOAT, 0, tex_coord);

glNormalPointer(GL_FLOAT, 0, normal);

// glClientActiveTextureARB(GL_TEXTURE0_ARB);

// glClientActiveTextureARB(GL_TEXTURE1_ARB);


for(int z = 0; z < MAP_Z - 1; z++)
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &indexs[z * MAP_X * 2]);

// glDisable(GL_TEXTURE_2D);

// glActiveTextureARB(GL_TEXTURE0_ARB);

// glDisable(GL_TEXTURE_2D);

glDisable(GL_NORMALIZE);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHTING);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}


Here is my rendering function

void Render(CTerrain &terrain)
{
float radians = float(PI * (move_x - 90.0f) / 180.0f);

camera_x = look_x + sin(radians) * move_y;
camera_y = look_y + move_y / 2.0f;
camera_z = look_z + cos(radians) * move_y;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

//glRotatef(30.0f, 1.0f, 0.0f, 0.0f); //top down


gluLookAt(camera_x, camera_y, camera_z, look_x, look_y, look_z, 0.0, 1.0, 0.0);

glCallList(terrain.skybox_list);
terrain.DrawTerrain(textures);
terrain.SetupLighting();

SwapBuffers(ghdc);
}


Thanks

Share this post


Link to post
Share on other sites
BGCJR    100
after a bindbuffer, use NULL as the pointer to indices.

So as it is written so shall it be done.
oss.sgi.com registry examples.

Share this post


Link to post
Share on other sites
MARS_999    1627
I am now staring to get pissed! Why in the ***k is this so hard to implement? We are talking like 3 functions here and it like way harder to get working than vertex arrays. I am not sure but think I seen my cards max indexs is 65k so this would mean 65k elements for my index array right? Well that shouldn''t be a problem anymore beings I reduced my map to 64x64 and now when I run my code my screen is totally hosed up. Like my index array isn''t being called correctly? Get this now my fps is 10fps!!!! WTF anyone who is willing to look over my code I am more than happy to send you it. Maybe someone with a lot more experience can figure it out but I am about to dump VBO''s because I am not seeing a fps increase but a HUGE decrease. And yes I have looked over at the extension registry. The only thing I am not doing from what I can see is using dynamic memory. Thanks

Share this post


Link to post
Share on other sites
Trienco    2555
never ever look at the fps as long as your screen is just displaying garbage. if youre out of bounds with your indices or whatever then youre lucky it doesnt crash, expecting it to be fast would be too much.

Share this post


Link to post
Share on other sites
MARS_999    1627
quote:
Original post by Trienco
never ever look at the fps as long as your screen is just displaying garbage. if youre out of bounds with your indices or whatever then youre lucky it doesnt crash, expecting it to be fast would be too much.


But I am not out of bounds anymore. I reduced from 256x256 to 64x64 to be way under the 65k limit. The program will run but when I exit I get a crash. When its running I go to wireframe mode and I see that all my polygons want to start from a center point and render out from that point? This makes no sense because I haven't changed nothing since I got them to work with vertex arrays? Any ideas? Thanks

[edited by - Mars_999 on August 21, 2003 11:08:28 AM]

Share this post


Link to post
Share on other sites
Trienco    2555
quote:
Original post by MARS_999
But I am not out of bounds anymore. I reduced from 256x256 to 64x64 to be way under the 65k limit.


but did you make sure, that youre not indexing vertices that dont exist? if your geometry is that screwed up it usually has to be bad indices. did you try drawarrays with a line strip to check if your vertices are correct?

Share this post


Link to post
Share on other sites
MARS_999    1627
quote:
Original post by Trienco
quote:
Original post by MARS_999
But I am not out of bounds anymore. I reduced from 256x256 to 64x64 to be way under the 65k limit.


but did you make sure, that youre not indexing vertices that dont exist? if your geometry is that screwed up it usually has to be bad indices. did you try drawarrays with a line strip to check if your vertices are correct?



But why would that be? I had no issues under vertex arrays? I had no issues with my vertices being drawn incorrectly then?

Well I reverted back to vertex arrays with my current index array <- I call index array instead of vertices and vertex array. No issues with rendering my GL_TRIANGLE_STRIP. So what gives when I use VBO's? Do I have to store the data in someother format for VBO's vs. vertex arrays? I doubt this is an issue but I do have 2D arrays for my texture and vertex arrays and a 1D array for the index array. I used GL_POINTS with the VBO's enabled and the points are totally screwed. But remove the VBO code and run glDrawElements() with vertex arrays instead no issues? Now what?

[edited by - Mars_999 on August 21, 2003 7:04:15 PM]

Share this post


Link to post
Share on other sites
MARS_999    1627
I will add this also about VBO''s. From what I am starting to see VBO''s are good for models and small areas of terrain engines. From what I see it''s not possible to use VBO''s on large areas. I don''t want to render only 64x64 area of a map. I would like the player to see at least 128x128 and up to 256x256. Vertex arrays so far are the only way I see. But I still would like to figure out why VBO''s aren''t working for me with my code? Thanks

Share this post


Link to post
Share on other sites
Trienco    2555
theres no real limit. i store 9 sectors, each 513x513 and all texture coords in one big buffer, so why should it only work for small objects? if indices and vertices are correct you must be making a mistake when setting it up (setxxxpointer, etc.) forgetting to unmap (if you map) or something.

Share this post


Link to post
Share on other sites
Ysaneya    1383
quote:

From what I see it''s not possible to use VBO''s on large areas.



Try looking again. I''ve had no problems using VBOs with scenes of millions of triangles, rendering at 75 Millions triangles per second, and the total implementation time was 5 minutes (including debugging).

Stop complaining and try to debug your code; you must be doing a fundamental mistake somewhere. In the doubt, also make sure you''ve got the latest ATI drivers installed.

Y.

Share this post


Link to post
Share on other sites