Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411512 Posts in 69376 Topics- by 58431 Members - Latest Member: Bohdan_Zoshchenko

April 27, 2024, 07:58:35 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)2D Ortho Camera in OpenGL
Pages: [1]
Print
Author Topic: 2D Ortho Camera in OpenGL  (Read 7614 times)
raigan
Level 5
*****


View Profile
« on: December 09, 2009, 09:09:53 AM »

I have a scene made up of a bunch of worldspace polygons, and I'd like to be able to pan/zoom my camera around the scene. Also in case you can't tell, I have very little experience with OpenGL Smiley

AFAICT, there are two ways to realize pan+zoom: using a non-identity GL_MODELVIEW matrix so that the scene is transformed relative to the camera, or using glOrtho() to change the view volume (i.e moving and scaling it around in the world).

My question is: what are the differences between the two approaches? Are there any best practices, strengths/weaknesses with either approach, etc? What is everyone else doing?

Sorry if this is a stupid question!
Logged
Gold Cray
Level 10
*****


Gold Cray


View Profile WWW
« Reply #1 on: December 09, 2009, 09:39:36 AM »

I don't know much about the inner working of openGL, but for some reason I feel like it's cheaper to call glTranslated() n times than it is to call glOrtho() n times. I think glOrtho is really meant more as a one-time thing to setup the view. That said, I have in the past switched between 2d and 3d each frame using gluPerspective and gluOrtho2D without taking any noticeable performance hit, so it might just be a matter of personal preference.
Logged
brog
Level 7
**



View Profile WWW
« Reply #2 on: December 09, 2009, 09:48:47 AM »

There's no significant difference in efficiency - they both perform a single matrix multiplication.  glOrtho has to perform a few arithmetic operations to build the matrix, so technically it's slower, but not so much as you'd ever notice.

Generally I just set up the perspective transformation at the start of rendering a frame and then use the modelview matrix to do the kind of thing you're talking about.  It seems more intuitive that way, but they're equivalent.
Logged
powly
Level 4
****



View Profile WWW
« Reply #3 on: December 09, 2009, 09:50:32 AM »

With a glOrtho approach you will not be able to rotate your things, but of course pan and zoom will work. I'd use GL_MODELVIEW though, just because it's able to rotate and you don't really want to get used to changing the projection matrix - it's more complicated and won't work very well if you want to do a perspective projection instead.

It's also very simple, no calculations involved.

Code:
glLoadIdentity();
glTranslated(-x, -y, -z);
glScaled(zoom, zoom, zoom);

Gold, glTranslated/glScalef indeed is faster (glOrtho needs some calculations inside opengl) but doing it once per frame you won't notice the difference. If you need a lot of the same glOrtho or glFrustum, it might be a good idea to store that matrix into a DL.
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #4 on: December 09, 2009, 09:55:05 AM »

I could be wrong on some of this but...

glOrtho is generally called once to set up an ortho projection matrix - not a modelview matrix. It's a good function and easy to use.

That said, I set up my own projection matrix... if I recall this was because I wanted some crazy nonstandard ortho projections in Deadrock. But it seems convenient for me now. I take the screen width/height and multiply by the camera zoom, and put that in the scale part of the matrix, then load the position of the camera to the matrix. Then I use glLoadMatrixf to upload the projection to OpenGL (after having set the matrix mode to projection of course). Then I set the matrix mode to modelview, and load identity. Then I draw whatever is on the screen (I can get the visible screen rectangle from my camera class, which knows where it is, the current zoom, and the screen size and can calculate it from this data).

If you'd like the code (it's in C#) I can post it.

This is, however, apparently the wrong way to do it.
Logged

raigan
Level 5
*****


View Profile
« Reply #5 on: December 09, 2009, 10:01:52 AM »

Thanks for the fast feedback! Looks like modelview wins it Smiley
Logged
dspencer
Level 3
***


View Profile WWW
« Reply #6 on: December 09, 2009, 10:04:01 AM »

I don't have time to give a full answer right now (stupid going to class!) but have you looked into gluLookAt?

In terms of it being the "Wrong Way" - it doesn't matter, really, unless you decide you want to do something that isn't compatible with it. I ran into that same problem with adding Fog to a project once. So, if you aren't sure that you wont be adding anything else, doing it the "right way" might actually be a good idea, even if it doesn't seem as simple as your current way (it probably is, but just simple in a different direction).
Logged

mewse
Level 6
*



View Profile WWW
« Reply #7 on: December 09, 2009, 01:03:32 PM »

Also, this link is germane to the topic:  http://sjbaker.org/steve/omniv/projection_abuse.html
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #8 on: December 09, 2009, 03:22:11 PM »

Nice link Wink
Logged

Pishtaco
Level 10
*****


View Profile WWW
« Reply #9 on: December 09, 2009, 10:56:28 PM »

I've been putting the camera in the projection matrix. I'm doing my own fog and lighting in the pixel shader, and for both of these this is much simpler if you do it this way since the shader can see the world coordinates without having to do any messing around. I read that linked page, but haven't noticed anything wrong with the textures (or z buffer).

Logged

powly
Level 4
****



View Profile WWW
« Reply #10 on: December 09, 2009, 11:26:00 PM »

Pishtaco, it will work if done correcly but why on earth would you like to do a lot of difficult computations rather than put a single varying vec4 to your shaders? o:
Logged
Pishtaco
Level 10
*****


View Profile WWW
« Reply #11 on: December 09, 2009, 11:40:24 PM »

Pishtaco, it will work if done correcly but why on earth would you like to do a lot of difficult computations rather than put a single varying vec4 to your shaders? o:
What I'm doing at the moment is:
Store the observer location and some global lighting information in the GL_LIGHT variables - this is so I can just set them once each frame rather than separately for every shader
Do the lighting in the shader - I think putting the camera position in the projection matrix saves me having to remember what opengl does with lights when you do transformations
Do the fog in the shader - at the moment this doesn't do much, but in the end I will want rather complicated fog that depends on the y-coordinate

What are you suggesting?
Logged

Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #12 on: December 09, 2009, 11:47:53 PM »

I usually do my shaders in the camera's transformation space. So, for lighting the eye position is at 0,0,0 and I pass in the camera-transofrmed modelview to transform the vertices by.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
raigan
Level 5
*****


View Profile
« Reply #13 on: December 10, 2009, 06:15:14 AM »

Thanks again everyone for the help!

Here's what we have right now, which seems to be working -- things rotate/zoom around the center of the screen. Let me know if there are any mistakes, I'm definitely an OpenGL noob Smiley

Code:
//offset is the screenspace vector from the top-left corner to the center of the screen
//pos is the camera position in worldspace
//degrees is the camera orientation in worldspace
//scale is the screenspace length of a unit vector in worldspace
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(offset_x, offset_y,0);
glRotatef(-degrees, 0, 0, 1);
glScalef(scale, scale, 1);
glTranslatef(-pos_x, -pos_y, 0);

I wasted a lot of time trying to find a bug in our screenspace<->worldspace transformation code, before realizing that for some really stupid reason OpenGL uses degrees instead of radians.. WTF!
Logged
brog
Level 7
**



View Profile WWW
« Reply #14 on: December 10, 2009, 06:21:29 AM »

I wasted a lot of time trying to find a bug in our screenspace<->worldspace transformation code, before realizing that for some really stupid reason OpenGL uses degrees instead of radians.. WTF!

Yeah, it's crazy.  No idea why that did that, major design error if you ask me.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #15 on: December 14, 2009, 02:07:06 PM »

I wasted a lot of time trying to find a bug in our screenspace<->worldspace transformation code, before realizing that for some really stupid reason OpenGL uses degrees instead of radians.. WTF!

Yeah, it's crazy.  No idea why that did that, major design error if you ask me.
seconded, Its a really stupid thing to do. Sure you're making it easier to understand, but you're bogging it down with loads of otherwise unnecessary conversions.
Logged
Pishtaco
Level 10
*****


View Profile WWW
« Reply #16 on: January 03, 2010, 07:50:16 AM »

I have been punished for my projection matrix sins  Beg. I noticed that I was getting horrible z-fighting when far from the origin, but not far enough for it to be connected with floating point accuracy or anything.

I think I've fixed it now. The documentation on passing matrices to opengl is a pain.
Logged

powly
Level 4
****



View Profile WWW
« Reply #17 on: January 03, 2010, 10:32:30 AM »

Oh, it seems I forgot to reply ages ago Shocked It was my misunderstanding, I thought you were doing simple things overly complicated.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic