Let’s say I have a simple 2D scene with a certain amount of sprites being drawn from the same texture atlas (for example, a tile map). The game world itself can be big (possibly with large number of such sprites), but at any given moment only tiny portion of it is visible.
I can see two somewhat efficient ways to render such scene:
1. Use VBO for the whole scene
The easiest way would be to create one VBO for all sprites and render them in a single draw call (since they use same texture/shaders/blending etc.). With this approach, VBO only needs to be updated when sprites are added/removed or modified. But the disadvantage is that vast majority of sprites will be outside of clip space after vertex shader, so part of the GPU work will be wasted.
2. Update VBO each frame to only contain visible sprites
Alternatively, for each frame I could check which sprites are visible, and then update VBO to only contain these sprites with something like glMapBufferRange(…). Thus, only visible sprites will be rendered (no wasted GPU work). But obviously this would require some work on CPU and VBO updates every frame.
I am trying to figure out in general, when approach #1 is more efficient and when #2. For example, at what conditions extra work in the approach #2 can be justified in comparison to #1? Does drawing primitives outside of clip space trashes GPU cache? Would the answers be different for mobile (OpenGL ES) platforms?
Sorry for the vague question. I understand that definitive answer can only be given for a specific platform after profiling. But I am just trying to understand some general performance considerations and make an educated guess.