Take the 2-minute tour ×

I'm creating a very render expensive scene in opengl (using vertex buffer objects) and while all objects stay in place, I want to do something like a 'smooth pursuit' of the objects. That is: leave the objects where they are and move the camera / point of view to the left or right with a certain constant speed. Currently I do this by calling glTranslatef in my draw function, followed by code which re-draws all objects. This is however very expensive (lot's of objects!). Is there a way to just move the camera, without redrawing the entire scene?

share|improve this question
What language? If you don't care about the language, remove all, rather than adding every possible binding of opengl. –  David Rodríguez - dribeas Mar 27 '12 at 16:32
@DavidRodríguez-dribeas I've implemented my code in both python and c, but there's not much of a difference regarding performance. –  memyself Mar 27 '12 at 16:39
How could it be possible? If the camera moves, the view of every object changes in some way. –  leftaroundabout Mar 27 '12 at 16:40
@leftaroundabout that's why I'm asking :) I don't really know what's possible ;-) –  memyself Mar 27 '12 at 16:41
@memyself: Yes, it can be done in anyone of the languages, but the question is not about java, c++, c or python, it is pure opengl. The languages should not be tags. –  David Rodríguez - dribeas Mar 27 '12 at 16:58
show 2 more comments

4 Answers

up vote 5 down vote accepted

There is no camera in OpenGL. Or if you really want to think there is, then you have to realize that the "camera" stays at the origin in OpenGL, always looking in the same direction. The "camera" effect is simulated by moving and rotating all objects in the world, while the "camera" sits at the origin.

So if you want to move the "camera", you really have to move the world (or all objects in the world). In other words, there really isn't a way to "move the camera without redrawing all objects". One option, if you really want, would be to render the scene to a texture that is larger than the screen, and then shift the texture around to simulate the "camera" moving. Note that if you're using a perspective projection, it'll look very wrong when you do this. This will only look decent if you're using an orthographic projection.

However, it sounds like you're drawing in immediate mode, which is an ancient and slow method. You should be using modern draw calls with shaders and vertex array objects/vertex buffer objects.

share|improve this answer
thanks! I'm actually already using vertex buffer objects but since I have so many of them, rendering still takes a lot of time! (see my sample code above) –  memyself Mar 27 '12 at 16:48
add comment

I'm creating a very render expensive scene in opengl

No you don't. You're drawing a very complex scene. But OpenGL does not work with scenes. OpenGL offers you points, lines and triangles and draws them to a two dimensional framebuffer according to your commands. But once you've sent the drawing commands, and the geometry has been drawn OpenGL no longer has any recollection of what you told it.

What you end up is a picture. If you want to change any aspect of it, and be it only the vantage point, you have to redraw the whole thing.

share|improve this answer
ok, thanks for your explanation! –  memyself Mar 27 '12 at 18:27
add comment

Hmm, you could render the scene to a texture that is bigger than the viewport. Then slide the viewport on that texture. Whenever you get near the edges of the texture you'd have to redraw the scene, but not every frame.

Note however, that this has several drawbacks:

  • since the perception of depth depends on the position of the camera moving the camera without updating the depth information might result unwanted and noticable visual artifacts such as the scene appearing flat etc.

  • you could not turn the camera since then the visual artifacts would be even more visible or the viewport might leave the textured space.

So as an alternative, try to optimize your scene drawing. There are several approaches to do so, some of which are:

  • occlusion culling
  • rendering flat imposters/sprites for distant objects
  • reducing the view depth
  • using vertex and index buffers
  • instancing
  • etc.


Rereading your question it seems like the glTranslatef etc. calls might be the problem. In modern OpenGL (as well as Direct3D) applications you'd calculate the matrices yourself (maybe using OpenCL but not glTranslatef etc.), store them and pass them to the shaders to render the objects.

What might eat up performance could be the matrix calculations if they are done every update. If your objects don't move very often you might want to calculate the matrices only when they move and when drawing you just pass them to OpenGL. For further optimization you might want to think about data locality in order reduce cache misses etc. - but that's an already really low level optimization.

To summarize the answer: don't try to reduce the number of frame updates but try to optimize the individual updates. When the "camera" moves you need to update the view (i.e. rerender) and thus your only option is to reduce the work necessary for those updates.

share|improve this answer
I'm already using vertex buffer objects and therefore I don't need to send the data to the GPU anymore. However, because I have so many objects, calling all the gl* functions kills my performance. How could instancing help here? –  memyself Mar 27 '12 at 16:55
@memyself Well, instancing might reduce the amount vertext/index buffer accesses if you have multiple instances of the same shape drawn at different locations. Besides that in modern graphics applications you shouldn't use glTranslate and the like, I'll add more information in my answer. Besides that, try to profile which functions actually eat up your performance. –  Thomas Mar 27 '12 at 20:38
add comment

No, the entire scene must be redrawn.

The glTranslatef call changes the model view matrix, which is the first matrix which your geometry is transformed by. Changing the matrix means that everything in the pipeline after the matrix would be invalid, which because its the first step would be practically everything. By translating, instead of moving the 'camera', it more like moving the entire world and the camera is staying still.

Besides OpenGL (and video hardware) simply doesn't work in the manner you want.

There is a technique called billboarding which is used to render geometry that is far away. The geometry is rendered to a texture which is then used as a sprite when rendering the main scene. As long as the camera remains close to the point where the billboard was generated then the error is acceptable (or imperceptible). The scene is still is still rendered every frame, but you're cheating slightly. This is usually used for far away terrain and trees.

Bilboarding isn't something you should be looking into by the sounds of things, because it's quite hard to get right. To improve performance first look at using vertex buffer objects and frustum culling.

share|improve this answer
Or not VBOs, seems you are already using them. Try state sorting and level of detail techniques. –  eyesathousand Mar 27 '12 at 17:05
If you are limited by the speed of the draw calls and you have many small VBOs then (if it makes sense) adding them together can improve performance. If you are limited by the speed of the GPU, then state sorting will improve cache locality in the GPU and avoid state changes. –  eyesathousand Mar 27 '12 at 17:09
yes, I do have many small VBOs. Rendering the same amount of objects using fewer VBOs is way faster. Unfortunately, I need to shift the view every 20ms and draw new objects. That's why I decided to break all objects up into VBOs which correspond to my 20ms update interval. this way I just remove one VBO and add a new one. but still I have to draw all of them. How could this be improved? –  memyself Mar 27 '12 at 17:13
Do any of these object remain fixed relative to each other –  eyesathousand Mar 27 '12 at 17:26
It would be a lot easier to know what these 'objects' are. If they are chunks of terrain they can be made larger or smaller to trade between raw rendering speed and culling granularity. –  eyesathousand Mar 27 '12 at 17:30
add comment

Your Answer


