4
\$\begingroup\$

I can't understand how the camera is working. It's a 2D game, so I'm displaying a game map from (0, 0, 0) to (mapSizeX, 0, mapSizeY).

I'm initializing the camera as follow :

Camera::Camera(void)
  : position_(0.0f, 0.0f, 0.0f), rotation_(0.0f, 0.0f, -1.0f)
{}

void            Camera::initialize(void)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glTranslatef(position_.x, position_.y, position_.z);
  gluPerspective(70.0f, 800.0f/600.0f, 1.0f, 10000.0f);
  gluLookAt(0.0f, 6000.0f, 0.0f,
            0.0f, 0.0f, -1.0f,
            0.0f, 1.0f, 0.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
}

So the camera is looking down. I currently see the up right border of the map in the center of my window and the map expand to the down left border of my window. I would like to center the map.

The logical thing to do should be to move the camera to eyeX = mapSizeX / 2 and the same for z. My map has 10 x 10 cases with CASE = 400, so I should have :

gluLookAt((10 / 2) * CASE /* = 2000 */, 6000.0f, (10 / 2) * CASE /* = 2000 */,
            0.0f, 0.0f, -1.0f,
            0.0f, 1.0f, 0.0f);

But that doesn't move the camera, but seems to rotate it.

Am I doing something wrong?

EDIT :

I tried that:

gluLookAt(2000.0f, 6000.0f, 0.0f,
            2000.0f, 0.0f, -1.0f,
            0.0f, 1.0f, 0.0f);

Which correctly moves the map in the middle of the window in width. But I can't move if correctly in height. It always returns the axis Z. When I go up, It goes down and the same for right and left.

I don't see the map anymore when I do :

gluLookAt(2000.0f, 6000.0f, 2000.0f,
                2000.0f, 0.0f, 2000.0f,
                0.0f, 1.0f, 0.0f);
\$\endgroup\$
3
  • 2
    \$\begingroup\$ How are you drawing your map? Could you post a few lines of that? \$\endgroup\$ May 31 '13 at 14:34
  • \$\begingroup\$ You should not be doing the glTranslatef and gluLookAt on the GL_PROJECTION stack. They are setting up the view, so they go on the GL_MODELVIEW stack. I believe the gluLookAt should also come before glTranslatef. \$\endgroup\$ Jul 30 '13 at 13:28
  • \$\begingroup\$ (Oh, in this case it won't matter, because your glTranslatef doesn't do anything) \$\endgroup\$ Jul 30 '13 at 13:35
3
\$\begingroup\$

How does gluLookAt work?

It seems you need help with gluLookAt - it takes these nine parameters:

  1. Parameters 1 through 3 are the XYZ coordinates of your camera's position.
  2. Parameters 4 through 6 define the XYZ coordinates of the point that your camera will be centered on.
  3. Parameters 7 through 9 define which direction is "up". This allows you to roll the camera.

Where should one apply camera transformations?

Next, you should transform your view (move your camera) by using the Model-View matrix and not the Projection matrix.

The gluLookAt() function gives you a transformation matrix that transforms a rotation of an object in your scene. So this is clearly a model transformation and must go into the GL_MODELVIEW matrix.

Source

So your code should initialize function should look more like this:

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(70.0f, 800.0f/600.0f, 1.0f, 10000.0f);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(position_.x, position_.y, position_.z);
  gluLookAt(0.0f, 6000.0f, 0.0f,
            0.0f, 0.0f, -1.0f,
            0.0f, 1.0f, 0.0f);

  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

Is there a better way?

I think that instead of using gluLookAt, you should simply translate the camera instead. I'm not sure how you are drawing your 2D images, but typically you will draw your images with an X and Y coordinate and leave Z at 0. If you go this route, I recommend using gluOrtho instead of glPerspective.

Find a good book

I recommend finding a good book about OpenGL viewing transformations. Although this book is outdated, the concepts in this chapter remain useful: http://www.glprogramming.com/red/chapter03.html

\$\endgroup\$
4
  • \$\begingroup\$ I tried to gluLookAt in GL_MODELVIEW, it doesn't change anything. I see the map plan, but not the objects on it anymore. I don't understand why I have to set the z point view (6th param) at -1.0. It's suppose to look at the z = -1.0 , but when I change it to 0.0 (which shouldn't change anything), I only see the clear color of the window. That's the problem now. I've moved the camera on the X axis at 2000, the eye too so I don't see the scene by its side. BUT I can't move the camera on the Z axis as the X axis because of this -1.0 in param of the point looked. \$\endgroup\$
    – Elfayer
    May 31 '13 at 8:39
  • \$\begingroup\$ Edit Camera constructor \$\endgroup\$
    – Elfayer
    May 31 '13 at 8:47
  • 1
    \$\begingroup\$ This is working if I move the camera withe the glTranslatef(x,y,0) and glLookAt(0,z,0,0,0,-1,0,1,0) !! For a map 10 x 10, x = y = 2000 and for example z = 5000. \$\endgroup\$
    – Elfayer
    May 31 '13 at 10:03
  • 1
    \$\begingroup\$ @Elfayer You're misunderstanding glLookAt. It is for looking at a particular point in the world. You are making it look at point (0, 0, -1) which is always the point next to the corner of your map. It is not a direction (and if it were, it'd be the wrong direction). It doesn't matter where the camera is moved to, it will always look towards that point. The problem here is that you don't want to look at a particular point all the time, you want to look in a particular direction, so you should be using glRotate. You want to make your camera look down the y-axis. \$\endgroup\$ Jul 30 '13 at 13:45
1
\$\begingroup\$

First understand the difference between the GL_MODELVIEW and GL_PROJECTION matrix stacks.

The GL_MODELVIEW matrix is for positioning and orientating the objects in the world with respect to the camera. This moves your objects through the following coordinate spaces:

Object Space -> World Space -> Eye Space

In object space, the object is the centre of everything. It does not yet know where in the world it is. You then apply the model transformation to the object and it positions it in the world. When this is done to every object, you have them all in world space. At this point, the (0,0,0) coordinate is just some arbitrary origin point in the world.

Your camera has some position and orientation in the world space. The view transformation rotates and translates the world space so that the camera is at the origin (0,0,0) and looking along the negative Z-axis. This is eye space. In eye space, the camera is the centre of everything.

These two transformations are combined into one, the modelview transformation, since they really just both work together to move objects around in the world with respect to the camera.

The GL_PROJECTION matrix transforms your objects through the following spaces:

Eye Space -> Clip Space

This can be a difficult transformation to imagine conceptually. If you imagine the frustum of the camera as a 6-faced volume (which is very near to the origin in eye space), this transformation moves and warps it so that it is in the shape of a cube with the centre of the cube at (0,0,0).

The first problem you've got is that you're trying to apply the view transformation to the GL_PROJECTION matrix. That's wrong. The view transformation should be part of the GL_MODELVIEW matrix. The view transformations you're applying are a glTranslatef and gluLookAt. These should be applied to the GL_MODELVIEW matrix.

Your second problem is that you misunderstand gluLookAt - in particular, the 4th to 6th arguments. You are attempting to give it a direction in which the camera should look, (0,0,-1), along the negative z-axis. Firstly, if this was what gluLookAt expected, it would still be wrong, because you want your camera to look along the y-axis. Nonetheless, it actually expects a position in the world to look at. No matter where you place your camera, it will look at the point (0,0,-1), which happens to be right next to the corner of your map, which is at (0,0,0).

You shouldn't be using gluLookAt at all, because you don't want to look at a particular point. This is much easier to do with a rotation to make the camera look along the negative Y-axis, combined with a translation so that the camera is at a height away from the map. Note, you should apply the inverse transformations than you expect to, because you're really moving the map away from the camera, and not the camera away from the map. Something like this:

glRotatef(1.0f, 0.0f, 0.0f, 90.0f); // Rotate the camera to look down the y-axis
glTranslatef(-position_.x, -position_.y, -position_.z); // Move camera to correct location

Make sure these are the first transformations on the GL_MODELVIEW matrix.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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