Before going into specifics, I'm mostly interested in making simple 2D games with some 3D elements, not fancy AAA.
Based on what I've gathered, everyone seems to suggest to use OpenGL 3+ with shaders, instead of the 2.x style of glVertex/glBegin/glEnd
. Now I do understand the reasoning behind moving to VBO and shaders, as it gives greater control and performance.
But it seems that it also forces me to produce all of the geometry beforehand, buffer is it somehow, generate the VBO, and then send all that to a single vertex/fragment shader to render it, correct?
It also seems that I need to have a single shader process completely different types of vertices, which means there has to be a lot of redundant information in the VBO? Or is there a way to have multiple VBOs? I know it is possible to have multiple shaders and swap them, but I haven't figured out when one would need that, considering I only have a single active VBO?
Now comes the real question.
Consider I'm making something like a procedurally generated growing plant, where each frame changes the whole geometry slightly (or just adds something). For simplicity, let's just say the plant is a bunch of colored ellipses. How do I structure the algorithm for "drawing" the plant? Would I just build the whole VBO from scratch, given that the vertex data changes all the time?
Also considering that the number of plants and their size can vary greatly, how do I avoid re-allocate memory for the VBO on each frame? Do I just use a large enough buffer, which would be able to store the maximum amount of geometry I can manage in my shaders (like a 512MB static array)?
Answer
Your assumption that there should be only a single VBO and shader is incorrect. You can, up to the limits of available memory, have as many VBOs as you want. For smaller games you can get away with having one VBO per drawable object, but ideally you should share VBOs between objects that require the same set of uniforms, shaders, and textures, so that each set of objects can be drawn in one shot using glDrawArrays
or glDrawElements
.
As far as structuring the VBOs in the case of your procedurally generated plant, it would probably be best to give each plant its own VBO, so as to not have to worry about moving vertices from other objects around to accommodate the increasing or decreasing number of plant vertices. You can allocate a "large" VBO up front to avoid reallocation as the plant grows, but 512mb would be way too much (and may even fail.) You can easily calculate the size of your vertex data, and estimate how large the plant could ever grow to be, and only make your VBO that big.
If your plant growth could be precalculated, you could load a VBO with all of the "frames" end-to-end before hand, and then just page through those frames at the appropriate rate with your calls to glDraw*
, but if not, then yes, you should just refill the VBO every frame.
No comments:
Post a Comment