Using VBOs and Index arrays

Started by Swiffdy, September 06, 2011, 09:06:16

Previous topic - Next topic

Swiffdy

I have recently been learning both java and lwjgl in order to write a simple game, and I've almost finished the engine but I am having an issue using VBOs, which is probably showing my incompetence.

I'm using a (finite) 3d voxel based terrain of about the scale of Minecraft (1 metre per side of a cube) but only about 128 blocks in each axis. Current I'm using display lists of the various kinds of blocks I want and when I render the terrain I scale and translate them appropriately to form the terrain. The bottleneck at the moment is CPU usage, as (I think) the CPU has to push all the transformation matrices to the graphics card.

My current thought is, I would like to transfer to using a VBO containing all the possible vertices (128³) and at render time form the index array so that it will create the relevant quads in the viewing frustum and order them nicely for z buffering. Clearly I don't want to interleave my VBO with all the possible normals and texture coordinates at each vertex, so I thought (tell me if I'm wrong) I could store the 6 possible normals and the small number of texture coordinates at the beginning of the VBO and in the index array point to them in amongst the vertices in an order like NTVTVTVTV. In a sense I'd like to interleave my index array. Is this possible? Am I going about this in completely the wrong way?

Sorry if I'm being very stupid and thankyou in advance for any help.

(EDIT: I just realised I might mean element arrays, not index arrays, sorry if my terminology is off >.<)

spasi

That is not possible I'm afraid. If you really want to get rid of the normals and texcoords from the VBO stream, one option would be to use a vertex shader. You could map the vertex index to the proper set of normal/texcoord. Depending on the target hardware, the vertex index could be either gl_VertexID or a custom attribute in the VBO stream.

The only other option is to include the normals and texcoords. Since they're fixed for all cubes, you could probably pre-allocate a separate VBO for them and reuse it in every draw call.


CodeBunny

jonnyh, calm down and stop insulting people (and if you must, please improve your grammar when doing so). Show some simple respect for other people; even if someone else is doing a bad job, it is most likely due to simple inexperience. And when that is the case, the most intelligent thing to do is to offer advice that will help them gain a better understanding of the task at hand.

Additionally, why on earth do you think a link to a French site will help? What do you think he will do, enter every single paragraph into Google translate, and receive tech advice that is in broken English?

johnnyh

Ok sorry man I did not want to be rude. Btw thats funny to critizise my bad english whereas you are saying that a french link does not help. Please show some respect for those for who english is not natural language. Thank you.

Swiffdy

Quote from: spasi on September 06, 2011, 09:30:45
The only other option is to include the normals and texcoords. Since they're fixed for all cubes, you could probably pre-allocate a separate VBO for them and reuse it in every draw call.

I've been thinking about this and, again, may be being stupid, but have a little issue. I am using a hierarchical octree model to store my cube information (possibly overkill for this scale, but I am planning to have many cells of this size in a map). The nodes in the octree all reference to a single static bytebuffer, to which I map the element buffer object (I think it's called that?) before I call the render function. The render function recursively goes through the tree to determine which nodes are within the viewing frustum and once a node with no children which is in the frustum is reached, the vertex pointers are added to the bytebuffer.

I believe you can only edit one VBO at a time, and binding to different VBOs repeatedly is costly, which is why I was trying to fit all the pointers into one element array. So again, I am uncertain how I would put pointers into several element buffers to store normal and texture coordinates separately to vertices given that running through the octree twice would clearly be sub-optimal.

Thankyou for any clarification. Also any ideas for wildly different strategies which I could implement would be helpful.

(I don't think I'm quite at the stage where I'd be comfortable attempting to use a vertex shader)

Also johnnyh, thanks for the link, but as suggested by CodeBunny, I'm finding it difficult to get any useful information out of the translated thread, though I am going to keep trying.  :-\

spasi

You don't need to go through the octree twice. Say the maximum render batch size is 1000 cubes. You build a VBO at load time that contains normals for those 1000 cubes. Since all cubes have the same normals, you just repeat the same normals 1000 times and put them in that VBO. At render-time, you go through the octree filling another VBO with positions/texcoords/etc (the dynamic stuff). That second VBO will be the only one that needs to be bound during frustum culling.