I'm working on a multiplayer game and will be displaying other players near the player. At most 16 players could be near the gamer however there could also be 0. What I'm thinking of doing is setting up 16 empty VBOs so they're ready to load with character's position when the client receives them. Is it valid to create empty VBOs? If not how should I go about rendering data that may or may not be there depending on what the server is sending the client?
The thing you seem to be missing is the concept of transforming objects. A mesh doesn't have a position in the world; it's just a collection of vertex data. When you render the mesh, you transform that vertex data from its default location to a place in the world.
This is what all of that matrix stuff people use does; vertex positions can be transformed by transformation matrices. Vertex shaders are primarily responsible for this.
This means that you don't modify the vertex data on the CPU. You don't translate it yourself; you let the GPU do the translations. When you render an object, you provide a transformation to the GPU, and your vertex shader will apply it.
This is obviusly bad approach. By creating empty VBO you will not gain any extra performance and you will waste memory.
So from the rendering point of view:
- If you wanna save memory: Create VBO per object if it is visible. If it is not visible, release it. But i do not recommend this for a simple game, since you are slowing game down.
- If you wanna be fast: Just have VBO per object and do not render it if it is not visible.
- If you wanna be super fast: Have all objects in one long VBO and render it using offset.
First, make a list of the resources (VBO, Texture, Shader, etc.) the current map/level needs to be rendered. Second, compute the amount of memory each resource consumes.
If everything fits in GPU memory, simply copy everything and render. If it doesn't fit, you'll have to devise a caching system.
Keep often used resources in GPU memory. Release unused resources when they're offscreen (and quite far from the current view). If rendering a single frame requires more memory than available, the process will be harder and quite slow.
To render only what's shown, you need a list of renderable "objects" along with their position and, maybe, their bounding volume. Keep a camera frustum updated in your game code and cull objects against it. Then, build a list of objects to render and send those to your renderer.
OpenGL will allow you to render objects, but you still need to build a minimal framework to identify what you want it to render. If your game is very simple, a simple distance test might be enough instead of frustum culling.