Should I create one Giant VBO, and use draw call based on offset??
Maybe. Try it that way and any other way that works for you on your target hardware. What works best in this regard can vary quite a bit with target hardware and driver version. "Giant" is a bit of a relative term, too. There's a big difference between 1,000 objects, 50,000 objects, and 1 million objects. Your definition of "giant" may not be all that big to the hardware, or it might be way too big. Depends on the hardware.
If I do that, then is there any limitation on glbufferData?? (or performance drop, if too much data in)
There is a limit, and particularly large updates can be slower than smaller incremental updates, though making a ton of small updates can be slower than making one big update. Whether it's faster to use a single array and update it with glBufferSubData
or multiple VBOs can, again, vary by hardware and driver.
Is there any method that vbo can contain different types of interleaved vertex?
Just append all the vertices of whatever types you want in contiguous chunks in the VBO(s). A VBO is really nothing more than a chunk of memory on the GPU. You can only use a single vertex layout per draw call, however. Nothing stops you from filling up a big VBO with a few thousand Position/Color vertices followed by several thousand Position/TexCoord/Normal vertices, assuming you don't intend to draw them all at the same time. VBO offsets are partly for handling this in the event you think you need it.
Is multiple "offset" draw call not affect performance unlike single draw call?
Again, it'll vary. In theory, it's one less bit of state to switch (VBO bindings) between draw calls which is usually a win, but a particular driver/GPU may be really good at such state changes and have a lot of draw call overhead. It may just be a balancing act on your hardware to find the right trade off between state changes and draw calls, assuming you come even remotely close to stressing the hardware in the first place (and if you don't, just do whatever is simplest and concentrate on more important aspects of your game).
Should I bind multiple texture atlas to each unit, and use uniform?
The uniform approach is unlikely to perform well from my understanding of how most modern GPUs works. Just bind a different texture per batch. It's easier. If unsure... profile on target hardware and find out.
Is there correct way for above #3 method?? (Feels like not correct)
Just don't write the object into the VBO. If you're dynamically updating the whole thing every draw call, just append your "live" objects to the buffer in a loop, and draw the corresponding number of vertices in your draw call. No reason to spend time copying vertices for invisible objects around. You don't need a particular sprite/object to maintain the same position in the VBO with each draw call; the GPU does not know or care what was in the VBO in the previous frame.
index = 0
for each object:
if object is visible:
vbo[++index] = object.topleft
vbo[++index] = object.bottomleft
vbo[++index] = object.bottomright
vbo[++index] = object.topright
Note that the "if object is visible" part can be more sophisticated than just checking a visibility flag. If you have a large play area and lots of objects, culling out objects which will be entirely off screen is often beneficial here, and it can be one of the easier parts of the engine to parallelize should you need that performance boost.
Just remember to use a dynamic/streaming (GL_DYNAMIC_DRAW
) VBO config.