Archived

This topic is now archived and is closed to further replies.

RuneLancer

OpenGL: To ortho, or not to ortho...

Recommended Posts

I''ve decided to work on a 2D RPG. Think "oldschool" Final Fantasy type of game engine. To benefit from hardware acceleration, I''ve decided to use OpenGL. So far so good. Now, I''ve heard orthographic projection is "the" means of doing 2D in OpenGL. Excellent. That''s exactly what I want. However, having followed NeHe''s tutorials, I have next to no experience with this. The Z coordinate is no longer available in ortho, right? Can things still be overlapped as though they had different depths (ie, can I superpose a window with the rest of my game) or would stuff intersect as though they all had the same Z? And does anyone have experience with this? I''m curious how good using it would be. Thanks!

Share this post


Link to post
Share on other sites
Unless OpenGL in this respect is completely different than any other 3D experience I have, then using ortho mode in no way takes away the Z value. Ortho mode should still be fully 3D. The only difference is that things don't appear smaller the farther off they get. This is the only real difference. And because of this, whenever you view surfaces that are completely perpendicular to the camera's line of sight, they appear to be completely 2D. And typically, the camera's line of site is direct along the Z axis. Thus, every surface that has identical Z coordinates for all its vertices appears 2D. But the fact that two surfaces have two different sets of Z coordinates still affects depth and everything.

In fact, there are a good number of games probably that do use ortho mode, but are still 3D. An example from a while back would by Final Fantasy Tactics. It was 3D, but you'll notice that everything is always the same size, regardless of location. Many isometric games are basically simulating 3D ortho mode (even though technically their graphics engine is indeed 2D).

[edited by - Agony on May 20, 2004 5:08:00 PM]

Share this post


Link to post
Share on other sites
(I''ve never really worked with OpenGL, but it''s probably like this..)

The ''Z'' is still available. Ortho means ''perspective''-less. You can still make objects smaller/bigger, by moving the ''Z''-value of an object.

Just try it!

--
You''re Welcome,
Rick Wong
- Google | Google for GameDev.net

+------------+
| Forum FAQ |
| Read it! |
+------------+

Share this post


Link to post
Share on other sites
i have a decent amount of code done for a top down tile RPG in SDL... after seeing what a crappy framerate i was getting (due to software rendering), i decided to learn OpenGL.. anyway im in the process of learning openGL (using 2d Ortho mode) to change my drawing code from SDL... the point is, i have some questions:

if im using ortho mode, i can no longer resize the screen, and things wont scale as i resize? so basically no resizing allowed?

if im using ortho mode, can i give the player a "zoom" key, where he can press, and the screen will zoom in, and zoom out?
(is this what runes asking?)

does drawing things in openGL ortho mode work the same way with SDL, in the fact that (if my code looked like this)

Draw_background()
Draw_player()

the player will appear to be on top of the background ? (again is this similar to runes question?)

what else limitations should i know about, or any general hints for someone with no knowledge on 3d graphics/ openGL moving from SDL ? thanks for any help!!!

Share this post


Link to post
Share on other sites
Using glOrtho, you specify the near and far planes(z-axis). Anything between these planes will be drawn. Those that are closer(a more positive z value) will be visible so you can do layers as you are asking.

There is another command gluOrtho2D that doesn't take any near/far planes. It uses near=0, far=1 but essentially it is expected that you will only use glVertex2? with it.

For what you want to do, glOrtho is the best choice.

karg

Edit: fixed near and far values for gluOrtho2D

[edited by - Karg on May 20, 2004 5:24:03 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Karg
There is another command gluOrtho2D that doesn''t take any near/far planes. I think it just uses 1/-1 but essentially it is expected that you will only use glVertex2? with it.

For what you want to do, glOrtho is the best choice.


Ah! That''s what I got confused with!! I remember reading that you''d use glVertex2 to set vertices and that''s where my concerns with depth came in. Excellent, that makes everything work out just fine then.

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
if im using ortho mode, i can no longer resize the screen, and things wont scale as i resize? so basically no resizing allowed?


You can resize just like you were using glFrustum

quote:
if im using ortho mode, can i give the player a "zoom" key, where he can press, and the screen will zoom in, and zoom out?
(is this what runes asking?)


Sure, just have a variable in your glOrtho call:
glOrtho( left*zoom, right*zoom, top*zoom, bottom*zoom, near, far );
where zoom gets smaller as the user zooms in(not sure on the order of the arguments, but you get the idea).

quote:
does drawing things in openGL ortho mode work the same way with SDL, in the fact that (if my code looked like this)

Draw_background()
Draw_player()

the player will appear to be on top of the background ?


Depends on how you set it up, but you can get it to work that way. Make sure everything is drawn with the same z value(easiest to use glVertex2?) and set the opengl depth test to less than or equal:
glDepthFunc( GL_LEQUAL );

Now, as to if you want to do it that way, it can also be done this way. Have the z be which "layer" the object is on. That way, objects can be drawn in any order and it will still come out correctly. Just another way to get the same result.

karg

Share this post


Link to post
Share on other sites
but how do you effect which z axis to draw on? i thought you were suposed to use glVertex2f() with ortho mode? keep in mind im calling glOrtho2D( make 0,0 top left corner);

so basically your saying, i could draw everything on the same Z plane, and the layers would be whichever order i drew things (my example above with b/g and player, and using vertex2f), OR, the differnt layers would be on different Z planes and i would draw with glVertex3f, but then, wouldnt what gets draw last be on top? im confused....

also, in glOrtho mode, isnt everything in terms of pixels, IE no longer "units", but exact screen pixels?(ie player.yPos += 4 would move the player down 4 pixels) this seems to be whats happening, but im getting confused now.. how could resizing things work if everything is in terms of pixels???

thanks for any further help

Share this post


Link to post
Share on other sites
As I understand it, let''s suppose you have a window and a map.

The map''s Z is 0.

The window''s Z is -1.

This means that, with depth culling on, you''d draw the window in front of the map whenever you render your scene. Not in the order in which you draw them (that is, unless depth culling is off...?)

Share this post


Link to post
Share on other sites
quote:
Original post by Pipo DeClown
You can still make objects smaller/bigger, by moving the ''Z''-value of an object.


No. Foreshortening is a perspective projection feature. With an orthographic projection, objects appear the same for any "Z-value".

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
but how do you effect which z axis to draw on? i thought you were suposed to use glVertex2f() with ortho mode? keep in mind im calling glOrtho2D( make 0,0 top left corner);

so basically your saying, i could draw everything on the same Z plane, and the layers would be whichever order i drew things (my example above with b/g and player, and using vertex2f), OR, the differnt layers would be on different Z planes and i would draw with glVertex3f, but then, wouldnt what gets draw last be on top? im confused....


glVertex2?( x, y ) is the same as glVertex3?( x, y, 0 ).
gluOrtho2D( left, right, bottom, top ) is the same as
glOrtho( left, right, bottom, top, 0, 1 ).
if the z value is between the near and far planes, then it will be rendered. If the depth is less than the current depth, then it will overwrite what is there, just the same OpenGL pipline.

quote:
also, in glOrtho mode, isnt everything in terms of pixels, IE no longer "units", but exact screen pixels?(ie player.yPos += 4 would move the player down 4 pixels) this seems to be whats happening, but im getting confused now.. how could resizing things work if everything is in terms of pixels???


glOrtho mode is in terms of what ever you set it to be. The arguments: left, right, bottom, top define a rectangle. Anything inside that rectangle is tested against the current depth (using what ever test is specified by glDepthFunc) and if it passes, it is drawn. OpenGL doesn''t work on monitor pixels, just on units.

karg

Share this post


Link to post
Share on other sites
quote:
Original post by Karg
glOrtho mode is in terms of what ever you set it to be. The arguments: left, right, bottom, top define a rectangle. Anything inside that rectangle is tested against the current depth (using what ever test is specified by glDepthFunc) and if it passes, it is drawn. OpenGL doesn't work on monitor pixels, just on units.

karg


ok, im really confused...

gluOrtho2D(0,width,height,0); (where width and height are 800x600 for a 800x600 screen..?)

this sets my origin, (0,0) to the top left corner of the screen. and it sets my axis to Y increases going down, and X increases going right. correct?

but how do i tell now what the 'units' really are? i mean, if my tile images are 32x32, how would i know how many quads to draw to fill up the screen, and what the w/h of these quads should be? keep in mind i want my collision detection to be un-changed from the way it works in the 2d version of my game (i just want to change the drawing code to use OpenGL instead of SDL)

thanks for any help....



[edited by - graveyard filla on May 20, 2004 6:27:25 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
i have a decent amount of code done for a top down tile RPG in SDL... after seeing what a crappy framerate i was getting (due to software rendering), i decided to learn OpenGL.. anyway im in the process of learning openGL (using 2d Ortho mode) to change my drawing code from SDL... the point is, i have some questions:

if im using ortho mode, i can no longer resize the screen, and things wont scale as i resize? so basically no resizing allowed?

if im using ortho mode, can i give the player a "zoom" key, where he can press, and the screen will zoom in, and zoom out?
(is this what runes asking?)

does drawing things in openGL ortho mode work the same way with SDL, in the fact that (if my code looked like this)

Draw_background()
Draw_player()

the player will appear to be on top of the background ? (again is this similar to runes question?)

what else limitations should i know about, or any general hints for someone with no knowledge on 3d graphics/ openGL moving from SDL ? thanks for any help!!!



SDL a crappy framerate?
Have you ever played Project; Starfighter?
That thing runs even faster than I can press my keys
and it is written completely in SDL.

Share this post


Link to post
Share on other sites
Have you ever tries transluscent blits?

On my PIII 650, YES, IT DOES LAG. A fullscreen game in 800x600 with a transluscent layer on top of my map, which contains two tile layers and a sprite layer, and a parallaxed BG, I get painful framerates that often drop under 10 FPS, if not much, much less.

The problem with SDL is that the 2D libraries are all software. I believe there''s no hardware support at all. If there is, it''s very minimal...

Share this post


Link to post
Share on other sites
quote:
ok, im really confused...

gluOrtho2D(0,width,height,0); (where width and height are 800x600 for a 800x600 screen..?)

this sets my origin, (0,0) to the top left corner of the screen. and it sets my axis to Y increases going down, and X increases going right. correct?

but how do i tell now what the ''units'' really are? i mean, if my tile images are 32x32, how would i know how many quads to draw to fill up the screen, and what the w/h of these quads should be? keep in mind i want my collision detection to be un-changed from the way it works in the 2d version of my game (i just want to change the drawing code to use OpenGL instead of SDL)

thanks for any help....





You choose whatever the units are. If you use gluOrtho2D(0,width, height,0), "width" and "height" being your screen''s width and height, then one unit represents one pixel on your screen. Sticking to one set of values for these two is recommended, since you won''t have to worry about the resolution of the user''s monitor (for example, (342,289) will be at the same place on the user''s screen, no matter what resolution he''s using).

Share this post


Link to post
Share on other sites
quote:
Original post by RuneLancer
Have you ever tries transluscent blits?

On my PIII 650, YES, IT DOES LAG. A fullscreen game in 800x600 with a transluscent layer on top of my map, which contains two tile layers and a sprite layer, and a parallaxed BG, I get painful framerates that often drop under 10 FPS, if not much, much less.

The problem with SDL is that the 2D libraries are all software. I believe there''s no hardware support at all. If there is, it''s very minimal...


SDL_HWPALLETTE and SDL_HWSURFACE

tried htem?

Share this post


Link to post
Share on other sites
quote:
Original post by incubator01
quote:
Original post by RuneLancer
Have you ever tries transluscent blits?

On my PIII 650, YES, IT DOES LAG. A fullscreen game in 800x600 with a transluscent layer on top of my map, which contains two tile layers and a sprite layer, and a parallaxed BG, I get painful framerates that often drop under 10 FPS, if not much, much less.

The problem with SDL is that the 2D libraries are all software. I believe there''s no hardware support at all. If there is, it''s very minimal...


SDL_HWPALLETTE and SDL_HWSURFACE

tried htem?

Always.

Share this post


Link to post
Share on other sites
What is the behavior of OpenGL if you use glVertex2? for overlapping images? Is it the first one rendered, the last one rendered, or dependent on the implementation?

Share this post


Link to post
Share on other sites
If depth test is enabled, the one with the bigger/smaller Z value is shown (depending how you set it up, as in glDepthFunc)
With depth testing, it''s plain ol'' 2D graphics.
When you draw something, it overwrites whatever was there before (There are no "layers"). So the last one will show up.
(unless, of course, wait-for-vsync is off (and you''re not using double buffering) and it happens to catch you in the middle of drawing )

Share this post


Link to post
Share on other sites
quote:
Original post by Goldfish
You choose whatever the units are. If you use gluOrtho2D(0,width, height,0), "width" and "height" being your screen's width and height, then one unit represents one pixel on your screen. Sticking to one set of values for these two is recommended, since you won't have to worry about the resolution of the user's monitor (for example, (342,289) will be at the same place on the user's screen, no matter what resolution he's using).


thanks for the help.. but could you explain this a little more? i dont understand how having the 0/0 w/h make one unit = one pixel... maybe because i dont understand what glOrtho() is doing? (i only know to send it 0,w,h,0 to make 0,0 top left corner, but i dont udnerstand how this works at all, i only know that it works because someone told me... what do these parameters do, and how does it all work? thanks for your help!!



[edited by - graveyard filla on May 21, 2004 2:54:48 AM]

Share this post


Link to post
Share on other sites
glOrtho and glFrustum are intended for use on the projection matrix. This matrix is applied after the model view matrix. It handles mapping of OpenGL logical coordinates to actual window coordinates.

In 3d mode the projection matrix reduced the x and y coords of a vertex in proportion to the z coord.

I ortho mode, this doesn''t happen. Verteces x,y position is irrelevant of the z coord.

glOrtho sets up the top, bottom, left and right edges of the screen. If you want a pixel to appear at the top of the screen, make its y coord equal the value you specified for top. If you want a pixel to appear at the bottom left of the screen, make its y coord equal the value you specified for bottom and the x equals to the left value.

The point it, if you set glOrtho to have top = 0, left = 0, bottom = 600, right = 800, the bottom right pixel will be specified by a vertex with the xy coords of [800,600]. This will be the case whatever size the screen is. Even if you screen is 20000x10 pixels, the bottom right will still be at [800,600] as far as specifing verteces to OpenGL goes.

If you specify the right and bottom coords to equal the width and height of the screen respectivly, then one OpenGL unit will equal one pixel.

Share this post


Link to post
Share on other sites
Just a quick comment...

glVertex2f(x,y) == glVertex3f(x,y,0)

does that help clear anything up?

Share this post


Link to post
Share on other sites
glortho/gluortho2D are the same thing as setting up a window in any old 2D library. Without any depth testing it''ll display stuff like any 2D lib as well. Thing about glortho is if you set the near and far to regular 3D values and add in depth testing you could have a 3D world without perpestive, which is pretty cool. The benifit of ortho lies in the fact the your game will be completely hardware accelerated and have access to fog, light, alphablending, and numerous other effects.

"Life is a double edged sword, we always hope to strike though adversity with the shining side..."

jkettles16 of Venosoft

Share this post


Link to post
Share on other sites
@Graveyardfilla:
Think of it this way...

If you set your world to be 0,0, 1600,1200 and your resultion is 800x600, every two units would translate to one pixel on your screen. If you''d set it to 0,0, 800,600, every unit would translate to a pixel on your screen. 0,0, 400,300, every half unit.

Basically, it''s like if you had a second screen and were drawing to it. Then when you display it on your screen, that screen is stretched to fit in your window.

Share this post


Link to post
Share on other sites