So this is what I want to accomplish and find out:
Even while OF uses OpenGL to draw 3D shapes (ofRect, ofSphere,
), is it faster to use one or more VBO’s to draw complex shapes, OBJ’s, high poly count scenes,
? I was under the impression it was.
VBO’s: how many to use to keep a steady performance? I searched far and wide, but no one could give me a definite answer. One said “use max 4000 VBO’s per draw call”, others “max 4MB per VBO”,
That doesn’t really help me in determining the way to go and how to handle different situations.
More importantly: how to keep track of your objects in function of a VBO or multiple VBO’s? One VBO per object/class is easy, but I’m thinking it might not be that good of an idea if I want 10,000 spheres with ±1000 vertices each. That’s 10,000 instances of an ofVboMesh, each drawn separately instead of in a batch. Combining all object’s vertices in one array and drawing them with one VBO draw call seems the way to go, but for rapidly changing objects, it’s not so easy to manage the situation. Plus, a different material per object is not possible.
The possible situations:
(continuously changing objects) 1 VBO per ofMesh (or one ofVboMesh per object) -> draw call per object (custom material per mesh possible, but very intensive?)
(continuously changing objects) ofMesh array of 3D objects -> get vertices of an ofMesh and add to vertice array on each frame -> draw vertice array of multiple objects in one call via a single ofVbo (custom material per collection/draw/array, reduces calls, but needs to build vertice array of ALL objects if just one object’s vertex count changes, which can be costly I suppose). Building a system to keep track of each object’s index and manipulating the array itself is not so simple. See below.
(continuously changing objects) Point buffer: each point holds 3 places in the array for its position, so no need for custom conversion or whatsoever; write directly to array and draw all of them via ofVbo, keep status of point in parallel array (e.g. velocity, particle system)
Static meshes and points, same as previous situation: create objects, get vertices, add to buffer array and draw once using ofVbo with STATIC hint.
My incomplete, custom Processing “library” keeps a list of all 3D objects in a buffer (VBO array). If an object changes: finds the starting vertex of the object by index (previously returned after adding it, changes if any other object changes), deletes from there up to the object’s previous total vertex count and recreates the object at the end of the array. What you have then is an array with an updated object that’s ready to be drawn by the VBO. But in the application I used it in, objects changed all the time so ultimately, the array manipulations got quite expensive on the CPU. Still, I could render up to 600,000 vertices so about 3000 spheres at a decent polygon count on a rather crappy laptop. Was I on the right track or is anyone like “wtf”?
Continued my search a bit.
in it we see that VBOs are more performant than arrays.
The reason we prefer VBOs is that the data is loaded onto the card, and so you don’t have to transfer it every frame. Depending on the type of VBO created, you can give the graphics driver hints on the usage (write-many, read-many vs. write-many, never-read, etc).
VBOs are really good for static geometry like terrain that you don’t expect to change, or for instanced geometry.
Vertex arrays are good for data that changes frequently but that also is read by the host machine–so, for directly rendering data that is being manipulated (laser rangefinder data buffers, for example, are where I’ve used them) frequently. If you can get away with never reading the data on the host device (so, just pushing it out onto the card), VBOs in write-only mode are a good option.
If I change my VBO vertex buffer and “re-upload” it each frame, I’m actually defeating the purpose of a VBO? Vertex Arrays would be the way to go then? But then:
Vertex Arrays These are available in OpenGL prior to 3.0, deprecated in 3.0, and gone in 3.1+. OpenGL ES supports them (OpenGL ES 2 does not).
VBOs These are available after OpenGL 1.5. These are the only way to store geometry data in OpenGL ES 2 (and so, WebGL).
Vertex Arrays are now deprecated, which means, in any situation using lots of geometry: VBO for the win? But I’m still trying to understand how to handle great number of different (static and dynamic) objects with different materials and how to use the GPU to render them while reserving my CPU for other tasks.
Basically with what I opened my post: single ofVboMesh per object (easy to track and change) vs large buffers (arrays) with converted vertices from ofMeshes and how to keep track of and change each object in those huge collections.
Gentlemen, I thank you for reading (if you got this far) and possible answers!