[SOLVED]Setting up OpenGl's projection mode units?
Moderator: Coders of Rage
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
[SOLVED]Setting up OpenGl's projection mode units?
Is there a way to do this? I read about it in the opengl facts, saying to translate ( 0.375, 0.375, 0 ) but I couldn't get it to work properly.
Last edited by like80ninjas on Mon Apr 11, 2011 2:19 pm, edited 1 time in total.
- Nokurn
- Chaos Rift Regular
- Posts: 164
- Joined: Mon Jan 31, 2011 12:08 pm
- Favorite Gaming Platforms: PC, SNES, Dreamcast, PS2, N64
- Programming Language of Choice: Proper C++
- Location: Southern California
- Contact:
Re: Setting up OpenGl's projection mode units to equal pixels?
If I'm understanding the question properly, you want (0,0) to be the top-left corner, and (w,h) to be the bottom-right corner, correct?
To do that, you would use this code:
If you're using something like glut, it should be in your reshape handler. If you're using SDL without SDL_RESIZE, you can just put it after your SDL_SetVideoMode(); otherwise, call it both after SDL_SetVideoMode() and in your SDL_VIDEORESIZE event handler.
This will allow you to use pixel coordinates for your vertices' X and Y coordinates. Z will still be in the range [-1,1]. Makes 2D rendering much easier.
Edit: If you wanted to switch between 2D- and 3D-style coordinates, you could do something like this:
And maybe add some stuff in there to disable/enable the depth buffer, and render in the appropriate order. Good for doing HUDs.
To do that, you would use this code:
Code: Select all
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
//glLoadIdentity(); // You only need this line if you don't call glLoadIdentity() every frame.
This will allow you to use pixel coordinates for your vertices' X and Y coordinates. Z will still be in the range [-1,1]. Makes 2D rendering much easier.
Edit: If you wanted to switch between 2D- and 3D-style coordinates, you could do something like this:
Code: Select all
void Enable2D()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void Disable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
Last edited by Nokurn on Sun Apr 10, 2011 4:09 pm, edited 1 time in total.
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
Re: Setting up OpenGl's projection mode units to equal pixels?
No no, I don't want to use ortho, I want to use perspective, but I was wondering if there is a way to get the "units" used by opengl to be equal to the size of a pixel?
Re: Setting up OpenGl's projection mode units to equal pixels?
If I understand what you're saying correctly. If the coords of the screen are -1,1,-1,1,-1,1 for example on each axis but your window size is lets say 640,480like80ninjas wrote:No no, I don't want to use ortho, I want to use perspective, but I was wondering if there is a way to get the "units" used by opengl to be equal to the size of a pixel?
Then if you have a rectangle member in a sprite class you could do
Code: Select all
void Sprite::Render() {
///blah
glTranslatef(x / 640,y / 640,z);
///Render shit
///blah
}
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
Re: Setting up OpenGl's projection mode units to equal pixels?
Basically what i'm trying to say is that I'm use to working with 2d, such as SDL, so the coordinate system is based on pixels. I'm using OpenGL now, and I don't really understand the units it uses for it's coordinate system. I was wondering if there is a way to convert these units to equal or be close to 1 unit = 1 pixel.
- ibly31
- Chaos Rift Junior
- Posts: 312
- Joined: Thu Feb 19, 2009 8:47 pm
- Current Project: Like... seven different ones
- Favorite Gaming Platforms: Xbox 360, Gamecube
- Programming Language of Choice: C++, ObjC
- Location: New Jersey.
Re: Setting up OpenGl's projection mode units to equal pixels?
OpenGL is neat in the fact that it doesn't have a coordinate system in the way you are thinking. Basically it lets you set up your viewport in the way that you want and draw everything in the way that you want. It doesn't have anything set exactly like SDL does. I think what you want to do is make the viewport equal to the window size, and make the projection matrix equal to that same thing but give it a depth and everything like a frustum has. I can't give you any code because I use OpenGLES for most of my projects.
Here is a GREAT blog post for you to read to get the ideas straight in your head. You *can* probably use some of the code but keep in mind it is coded for the iPhone so some stuff may need to be changed.
http://iphonedevelopment.blogspot.com/2 ... art-3.html
He uses Apple-framework-specific data types but just change it so it uses whatever you are using.
Here is a GREAT blog post for you to read to get the ideas straight in your head. You *can* probably use some of the code but keep in mind it is coded for the iPhone so some stuff may need to be changed.
http://iphonedevelopment.blogspot.com/2 ... art-3.html
He uses Apple-framework-specific data types but just change it so it uses whatever you are using.
Website/Tumblr
My Projects
The best thing about UDP jokes is that I don’t care if you get them or not.
Re: Setting up OpenGl's projection mode units to equal pixels?
I just gave you a example on how to do this.
I don't see why you would want to convert it like that though...
I don't see why you would want to convert it like that though...
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Setting up OpenGl's projection mode units to equal pixels?
I don't understand at all.
The entire point of perspective is that it performs perspective division on the scene based on the camera's distance from the view frustum... how the hell could that ever give you a 1-1 mapping between your plane of projection and your viewport?
Krolgar gave you the exact code to do what you want...
The entire point of perspective is that it performs perspective division on the scene based on the camera's distance from the view frustum... how the hell could that ever give you a 1-1 mapping between your plane of projection and your viewport?
Exactly. So you DO want to use glOrtho() and not perspective.like80ninjas wrote:Basically what i'm trying to say is that I'm use to working with 2d, such as SDL, so the coordinate system is based on pixels. I'm using OpenGL now, and I don't really understand the units it uses for it's coordinate system. I was wondering if there is a way to convert these units to equal or be close to 1 unit = 1 pixel.
Krolgar gave you the exact code to do what you want...
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
Re: Setting up OpenGl's projection mode units to equal pixels?
No, I don't want to use glOrtho(), to be honest my real issue here is that I don't understand the scale of the units used in GL. For example a lot of tutorials use very small numbers for coordinates and sizing geometry. I think I just need to find a good basis for the scale of the units. Is there any sort of standard for the size of the primitives and other things?
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Setting up OpenGl's projection mode units to equal pixels?
No, your problem is that you don't understand how OpenGL's projection matrix works.like80ninjas wrote:No, I don't want to use glOrtho(), to be honest my real issue here is that I don't understand the scale of the units used in GL. For example a lot of tutorials use very small numbers for coordinates and sizing geometry. I think I just need to find a good basis for the scale of the units. Is there any sort of standard for the size of the primitives and other things?
I'm sorry, but you keep insisting that you do not wish to use an orthographic projection while literally describing something that MUST be done with an orthographic projection.
A perspective projection is a frustum. As the distance between your objects and the frustum's front face (projection plane) increases or decreases, so does the size of the object. This is called perspective division. If the size and location of your object are changing based on its distance from the camera, how in god's name can you EVER refer to coordinates within the frustum as if they were 2D pixel coordinates (as you do in a 2D, software-based rendering environment like SDL/Allegro)? This is a mathematical fallacy.
I'll tell you how. It can only be done when NO perspective division is present. It can only only be done when your distance from the projection plane does NOT affect your geometry. It can only be done when you are referring to a DIRECTION OF PROJECTION rather than a CENTER OF PROJECTION. This, my friend, is EXACTLY what an orthographic projection is.
Once again, your request makes no sense mathematically. Unless you are literally planning on ALWAYS keeping your objects the perfect distance away from the camera to produce no perspective division (a perspective division of 1 on your vertices), you are never going to be able to simply specify your geometry in screen coordinates. If you really do use this approach, it's absolutely pointless. That's exactly what an orthographic projection is.
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
Re: Setting up OpenGl's projection mode units to equal pixels?
Yes, you are right, I don't understand how it works, because I'm in the process of learning how it works. I understand what you are saying, but I think my original question failed to actually explain the issue I was having. Consider what I said before invalid, and now consider that my issue is that I don't quite understand the units that OpenGL uses. This is also why in my last post I asked if there was some sort of standard for the unit size of geometry in a game. However, after reading through there FAQ however I have figured out that the unit is literally whatever you want it to be, and that I should probably just make my own size scale for the geometry up. Is this the correct way of going about it?
Also, your explanation did help me understand a bit about the difference between the two modes mathematically.
Finally, I'd also like to mention that I was previously using glOrtho, and it was working fine and the coordinates worked like pixels, just like you are saying, and I made some "2D" projects with it, but now I'm working with perspective and want to venture into the mysterious world of 3D. I hope this better explains my issue, sorry for the confusion.
Also, your explanation did help me understand a bit about the difference between the two modes mathematically.
Finally, I'd also like to mention that I was previously using glOrtho, and it was working fine and the coordinates worked like pixels, just like you are saying, and I made some "2D" projects with it, but now I'm working with perspective and want to venture into the mysterious world of 3D. I hope this better explains my issue, sorry for the confusion.
- Falco Girgis
- Elysian Shadows Team
- Posts: 10294
- Joined: Thu May 20, 2004 2:04 pm
- Current Project: Elysian Shadows
- Favorite Gaming Platforms: Dreamcast, SNES, NES
- Programming Language of Choice: C/++
- Location: Studio Vorbis, AL
- Contact:
Re: Setting up OpenGl's projection mode units to equal pixels?
THERE you go. Now you're understanding.like80ninjas wrote:I have figured out that the unit is literally whatever you want it to be, and that I should probably just make my own size scale for the geometry up. Is this the correct way of going about it?
There is no 1-1 correlation between the world space locations of your geometry and the literal screen coordinates of your geometry unless you're using an orthographic projection. A perspective projection introduces perspective division which literally transforms your objects once again from world space to screen coordinates. This means that you cannot specify (or even think of your object locations) in the form of screen coordinates.
Your projection matrix serves as a map from a THREE-DIMENSIONAL VOLUME to a TWO-DIMENSIONAL VIEW PLANE. If something is at pixel 320x240 on your 2D view volume (after perspective division), that does not reflect its true 3-dimensional world-space coordinate.
Now you have to learn to stop thinking about units, and especially stop thinking about pixels. OpenGL abstracts "units" away from the programmer. Look at this function:
Code: Select all
glColor3f(1.0f, 1.0f, 0.5f);
If you're using 8 bits per pixel, 1.0f is 255. If you're using 16-bit color, that's 2^16... and so on. There are no units here.
Now the same holds true with the view volume that you establish with your glPerspective() call. YOU are constructing your frustum. YOU are giving it a size. If you want to pretend like each "unit" is a meter and wish to model a particular volume, do it. It depends on your requirements and your application.
Just remember that "units" are arbitrarily chosen by the program. The "units" that you use to describe your geometry in 3D world-space are transformed by your projection matrix and "mapped" to your 2-dimensional projection plane. And once again, don't forget that this means there is no direct mapping between your screen coordinates and world coordinates.
-
- Chaos Rift Regular
- Posts: 101
- Joined: Thu Dec 09, 2010 2:13 am
Re: Setting up OpenGl's projection mode units to equal pixels?
Thanks, Falco! I think I'm starting to get the hang of these units, I've just been working with them doing different little "I wonder what what happens if I..." programs. I think in the end the way OpenGL uses these units is awesome because it's so flexible. I'm going to change this topic to solved, thanks for all the help!