1
\$\begingroup\$

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)?

\$\endgroup\$
  • \$\begingroup\$ Just a hint: If you can choose between recreating a VBO every frame vs replacing all the contents of a VBO every frame, you should definitely replace all contents and not recreate the VBO. It's much faster. \$\endgroup\$ – Tara Aug 8 '16 at 4:52
2
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

There are two more options solutions to overwriting single buffer in 3.x (few more in later versions):

  1. use the buffer as ringbuffer, locking and updating only a part equal to current "pointer" + required size. Moving round the buffer using modulus.
  2. use technique called buffer orphaning, where you just discard the buffers from your point of view and rely on the drivers do the optimization

both solutions are(or should be on typical hardware) faster, but basically as said in other answer - do not fix what is not broken, there is no reason to optimize unless your game is too slow. There is hardly any bigger productivity killer than premature optimization.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.