Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

For a 2D board game I'd like to move and rotate an orthogonal camera in coordinates given in a reference system (window space), but simply can't get it to work.

The idea is that the user can drag the camera over a surface, rotate and scale it. Rotation and scaling should always be around the center of the current viewport.

The camera is set up as:

gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(-width/2, width/2, -height/2, height/2, nearPlane, farPlane);

where width and height are equal to the viewport's width and height, so that 1 unit is one pixel when no zoom is applied.

Since these transformations usually mean (scaling and) translating the world, then rotating it, the implementation is:

gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();

gl.glRotatef(rotation, 0, 0, 1); // e.g. 45°
gl.glTranslatef(x, y, 0); // e.g. +10 for 10px right, -2 for 2px down
gl.glScalef(zoomFactor, zoomFactor, zoomFactor); // e.g. scale by 1.5

That however has the nasty side effect that translations are transformed as well, that is applied in world coordinates. If I rotate around 90° and translate again, X and Y axis are swapped.

If I reorder the transformations so they read

gl.glTranslatef(x, y, 0);
gl.glScalef(zoomFactor, zoomFactor, zoomFactor);
gl.glRotatef(rotation, 0, 0, 1);

the translation will be applied correctly (in reference space, so translation along x always visually moves the camera sideways) but rotation and scaling are now performed around origin.

It shouldn't be too hard, so what is it I'm missing?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

In order to move your camera about in space using camera-relative controls, you must apply the camera transform to your camera position delta before adding it to the current camera position. There is no good way to have OpenGL do it for you. Once you have set that up, the proper order of transformations for rendering is: scale and rotate (either order), then translate.

share|improve this answer
    
That much I assumed. Without doing X/Y plane rotation and un-zooming myself, is it possible to abuse glUnProject() for that? –  Markus Sep 12 '12 at 20:30
    
Perhaps, but you'll be much better off in the long run by finding or writing a decent matrix/vector arithmetic library. It's really not that complex, and there's a lot of uses for it in game programming. –  Kevin Reid Sep 13 '12 at 1:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.