2
\$\begingroup\$

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?

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ That much I assumed. Without doing X/Y plane rotation and un-zooming myself, is it possible to abuse glUnProject() for that? \$\endgroup\$
    – sunside
    Commented Sep 12, 2012 at 20:30
  • \$\begingroup\$ 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. \$\endgroup\$
    – Kevin Reid
    Commented Sep 13, 2012 at 1:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .