Jump to content
  • Advertisement
Sign in to follow this  
Ishaq

is there a better way to move a 2D Camera (with Zoom In and Zoom Out)

This topic is 3626 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Everyone, I have searched and seen some posts (http://www.gamedev.net/community/forums/topic.asp?topic_id=390115&forum_id=25&gforum_id=0) on GD which suggest manipulating paramerters to glOrtho for zooming in a 2D world, something like: glMatrixMode(GL_PROJECTION); glOrtho(-1.5 + zoom, 1.0 - zoom, -2.0 + zoom, 0.5 - zoom, -1.0, 3.5); in my case, however, I want a camera that can be moved around the screen (up, down, left, right) together with zooming, and I am doing it with something like: glViewport(0 + camera.x, 0 + camera.y, width * zoomFactor, height * zoomFactor); and it is working for me till now (but then, it is only a simple test in its current state), I want to know why is the glOrtho method better (or not better)? appreciate your time. Regards, MI

Share this post


Link to post
Share on other sites
Advertisement
glViewport defines how coordinates are mapped from eye space to actual pixels.
It depends on the display window and is restricted to GL_MAX_VIEWPORT_DIMS.

For zooming you should definitely use the projection matrix (glOrtho) since that's its job (like a lens). Moving the camera is normally done via a view matrix (in OpenGL part of the modelview matrix) but with glOrtho you can do this as well, as long as you don't want to rotate the camera.

Or do you want to have the viewport move within the display window? Then glViewport is your only choice since glOrtho only transforms vertices to eye space. However, moving the viewport won't move the contents, so (not speaking of zooming) moving around the viewport alone would mean that the same stuff is displayed on different location in your display window.

Share this post


Link to post
Share on other sites
Thanks Lord Evil,

however, here's the problem I am trying to solve:

- I have this big map shown to the user, the user can zoom in to view more detail and he/she can move up/down, left/right to navigate through the map.

i.e.

--------------------
|MMMMMMMMMMMMMMMMMM|
|MMMMM------MMMMMMM|
|MMMMM|SSSS|MMMMMMM|
|MMMMM------MMMMMMM|
|MMMMMMMMMMMMMMMMMM|
--------------------

S: Screen (View Port)
M: Map (2D World)


When I enlarge/shrink the viewport, it correctly zooms in/out of the map, and when I move the viewport around, it correctly use that area of the map to the screen.

For experiment, I tried to do the same with glOrtho(). However, when I try to do the same through glOrtho(), it zooms in just fine, now when I try to move (say towards left), it shows infinite blackness around the area that was actually showing on screen (i.e. before I moved left).

I have not tried the modelview matrix yet. but before that, I wanted to know, am I doing it wrong? i.e. is there something wrong with my perception of glOrtho and is that the reason I can't move the camer?

Share this post


Link to post
Share on other sites
Sure :) here it is (this is the one I am working with):


glViewport(0 + camera.x, 0 + camera.y,
width * zoomFactor, height * zoomFactor);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LINE_SMOOTH);

//....... drawing code ...........





and if I use a code like this (so that I zoom with glOrtho()), it doesn't work


glViewport(0 + camera.x, 0 + camera.y, width, height); // NOTE: Now I
// am not zooming in this call

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 + zoomFactor, 1.0 - zoomFactor, -1.5 + zoomFactor,
1.5 - zoomFactor, -1.0f, 1.0f); // NOTE: this line makes it
// zoom fine, moving the camera
// (viewport) up or down reveals
// black beyond edges.

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LINE_SMOOTH);

//....... drawing code ...........





I have yet to try using glTranslate for the modelview matrix.

Thanks for your replies, I appreciate it very much

Regards,
MI

Share this post


Link to post
Share on other sites
this is most bizarre, my viewport just stretches beyond the screen if I increase its width and height i.e. if I make a viewport of 1600x1200 on a 800x600 screen, only the lower-right part of it is being displayed on the screen, the rest is simply drawn off of the screen. is that normal? shouldn't it just shrink everything to make it fit on 800x600?

Regards,
MI

Share this post


Link to post
Share on other sites
Just to clarify that: the viewport IS NOT the camera. In effect there is no camera in OpenGL.

A short description of the transformation pipeline:

1a. transform from object space to world space: this uses your model matrix
1b. transform from world space to eye space (camera space): this uses your view matrix, normally camera movements are done here
2. transform from eye space to clip space: here the projection matrix is employed, normally zooming is done here (by changing the width and height of the ortho projection or the fov of the perspective projection)
3. transform from clipspace to actual pixels: here the viewport comes into play

(The reason I used 1a and 1b is that in OpenGL those transformations are contained in one matrix: the modelview matrix.)

You can see that the viewport is used to map the clip space coordinates (which are in range [-1, 1]) to pixels, so it defines where on the screen the scene is rendered. If the viewport is larger than the window size pixels are just dropped.

OpenGL will set the viewport dimensions to the window dimensions on window/context creation automatically. If you use glViewport it's your responsibility.

Moving the camera is simply a matter of calling glTranslatef(-cam.x, -cam.y, -cam.z) on the modelview matrix (normally the identity, then you add camera transformations and later model transformations).

Share this post


Link to post
Share on other sites
Thank you Lord_Evil, ma_hty

Thanks for the refresher on rendering pipeline, guess I needed that :). In the mean time however, I have found source of the problem, Something I had in my head wasn't there in the source that is why glOrtho() worked mysteriously, now I have tamed it.

(I do not, however, completely understand your point on doing camera transformations followed by model transformations, could you elaborate with an example please?).

ma_hty, great link, gluPickMatrix looks more readable than manipulating values in glOrtho() (or glPerspective() )

Thanks again

Regards,
MI

Share this post


Link to post
Share on other sites
Basically you can think of the camera as an ordinary object placed in the world. For displaying the world you need to transform everthing to the camera's local space (eye space).

Since the camera can be seen as an object its transformation matrix is contained in the modelview matrix.

The transformation of an object to eye space is thus:
1. transform it from local/object space to world space
2. transform it from world space to eye/camera local space

You can do this by combining the object's model/world matix (for transforming it to world space) and the inverse of the camera's world matrix (transforming from world to object space uses the inverse model/world matrix).

Generally you do it like this once per frame:

...
glLoadMatrixf(inverseCameraMatrix); //or glLoadIdentity() and then use appropriate combinations of glRotate() and glTranslate()
glPushMatrix(); //save the camera transformation
glMultMatrix(modelMatrix); //or combinations of glRotate() and glTranslate()
//render model
glPopMatrix(); //restore camera transformation
...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!