Page 1 of 1

[SOLVED]Setting up OpenGl's projection mode units?

Posted: Sun Apr 10, 2011 3:55 pm
by like80ninjas
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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 4:03 pm
by Nokurn
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:

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.
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:

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();
}
And maybe add some stuff in there to disable/enable the depth buffer, and render in the appropriate order. Good for doing HUDs.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 4:08 pm
by like80ninjas
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?

Posted: Sun Apr 10, 2011 4:14 pm
by N64vSNES
like80ninjas 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?
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,480

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
}
This is assuming I understand your question correctly.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 4:34 pm
by like80ninjas
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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 4:41 pm
by ibly31
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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 6:14 pm
by N64vSNES
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...

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 6:41 pm
by Falco Girgis
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?
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.
Exactly. So you DO want to use glOrtho() and not perspective.

Krolgar gave you the exact code to do what you want...

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 9:16 pm
by like80ninjas
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?

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 10:39 pm
by Falco Girgis
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?
No, your problem is that you don't understand how OpenGL's projection matrix works.

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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Sun Apr 10, 2011 11:29 pm
by like80ninjas
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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Mon Apr 11, 2011 10:53 am
by Falco Girgis
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 you go. Now you're understanding.

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);
Think about that for a second. What display actually represents colors as a floating point value? What the fuck is 1.0? What the fuck is 0.0? This is a normalized color representation--this allows you to specify colors WITHOUT restricting yourself to any specific color format.

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.

Re: Setting up OpenGl's projection mode units to equal pixels?

Posted: Mon Apr 11, 2011 2:18 pm
by like80ninjas
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!