Voxel based program structure
Before I ask my question I just want to put something aside. I am not trying to make a Minecraft clone, I have had a lot of negative response to questions on the subject on other forums and even insults and threats! I am merely attempting to expand my programming knowledge into the realm of 3D graphics and procedural generation, which seems to be the way that games and serveral other types of programs these days are developing.
Anyway, onto my main question(s).
I am exploring the concept of procedural generation through a voxel based worlds created in Java and OpenGL and am stumbling at understanding the general structure of how things work. My background is in physical computing and web development and am currently a mechanical engineering student so I have no experience whatsoever when it comes game development and 3D environments. What I would like some clarification on is the procedure through which these types of worlds work.
How I imagine it from my current research is something like this:
- The program creates arrays or "chunks" of a certain size which store block data in a range of locations and which can be dynamically generated, edited, saved and loaded.
- From these chunks, algorithm's determine which blocks are visible and in view and then generate a display list/vertex buffer object which store the vertex information for the blocks in the VRAM for quick rendering.
- These lists/vbo's are then left alone once they have been generated on the first loop, until one of the blocks is changed by some other variable such as user interaction or another piece of the program, at which point, the offending vertices are removed from the list/vbo and any new ones that need to be added are calculated and added (eg if a "deeper" block becomes visible).
I would like to know if what I have concluded above is somewhat correct. I am also having trouble grasping as to how it is that the above method can be achieved in such a dynamic way. I have also seen a lot of "GL_QUADS is bad, use triangle strips" and am wondering how one would apply triangle strips to a huge array of blocks stacked upon each other in a dynamic fashion. e.g. if a block was destroyed/moved, this would effect the entire triangle strip, assuming that a single strip was used to render all the blocks in a chunk (or something along the same lines), and the whole thing would have to be recalculated which is obviously something that should be avoided if possible.
If anyone can either help me out with my questions or point me in the right direction as to any books or tutorials that would help me it would be much appreciated.
I think you are on the right direction. Here are some tips:
You can optimize rendering quads by using a geometry shader.
You only want to render visible quads. If have cubes next to each other, you don't want to render the hidden faces.
You can allocate ranges of VBO and IBO space for cubes with 1 face, 2 face, ... 6 faces. During update, adding a cube means appending to the range of right amount of faces. Removing cube means replacing it with the last cube in the range with right amount of faces and reducing the number of cubes in that range. Changing how many faces are visible means you need to remove it from one range and add to another range. This arrangement means you don't need to dynamically manage memory (but you must prepare to handle some fixed amount cubes in each range), but can be somewhat tricky to get right. I am not sure if it is worth the trouble, but I guess it might be.
You can map your buffer for editing and flush only edited parts with ARB_map_buffer_range extension (also in core since GL 3.0). You can might even get away without any synchronization. This can help update performance a lot.