Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have researched this question from several sources and have yet to find a firm answer saying that "yes that is correct thinking" or "no, here is how it's done."

I am trying to ensure resolution independence with OpenGL rendering. The way I think I should go about it, is to create a projection using glOrtho with whatever I want the world coordinates to be. For example, glOrtho(-50.0, 50.0, -50.0, 50.0, 1.0, -1.0). Next, set the viewport to the screen resolution, i.e. - glViewport(0, 0, 800, 600). Finally, whenever the the window is re-sized, make a call to glViewport with the updated screen resolution. This will scale your figures.

Is this the correct way to ensure that models take the same proportion of screen-space on different resolutions? Should I be using a projection equal to the resolution as well? I found some answers saying glOrtho should use the resolution of your window while others said it should/can be different.

Thoughts?

share|improve this question

1 Answer 1

up vote 11 down vote accepted

What you have described is entirely adequate and appropriate to provide resolution independence. Anything you draw will indeed always take up the same proportion of your window.

However, if you do nothing more than this, you will have aspect ratio problems. For example, given the numbers you wrote, if you draw a circle, it will be squashed — wider than it is tall, because your horizontal scale is 800/(50+50) = 8 and your vertical scale is 600/(50+50) = 6.

There cannot be any automatic solution to this problem; you will have to choose what graphical result you want.

  • In a perspective-projection 3D game with no HUD, the usual simple solution (available in OpenGL as part of gluPerspective) is to fix the projection's field of view relative to the vertical dimension. This means that in such a game, if you resize the window horizontally, you will see more or less of the scene and the middle part of the image will not change at all.

  • If you have screen-sized graphics with a fixed aspect ratio (for example, a non-scrolling 2D map, or a decorative border), or if you otherwise cannot change the layout, then you have to do something like having black bars (or other filler) on the sides to fill the unused space.

  • If you have a HUD on top of a perspective projection, you can decide that each HUD element is fixed to a part of the screen (top left, bottom center, etc.) and compute its coordinates; the 'stretching' of varying the aspect ratios gets absorbed by the 'white space' between HUD elements.

As to the specific mathematics of the matter, given that you are doing resolution independence, all you need to start out with is the aspect ratio, a single number: width / height. For example, if the window is square it will be 1; if it is 800 by 600 it will be 800/600 = 4/3 = 1.333̅.

For example, suppose you want the orthographic projection you have written to gain additional space on the left and right sides if the window is widened. You can do that like this:

float aspect = width / height;
glViewport(0, 0, width, height);
glOrtho(-50.0 * aspect, 50.0 * aspect, -50.0, 50.0, 1.0, -1.0);

This guarantees that, for windows at least as wide as they are tall, anything you draw with x and y coordinates within -50 to 50 will be visible.

On the other hand, if the window is narrower than it is tall, the -50-to-50 range will be cut off. Let's say you wanted to make sure that it is always visible (so that your content is at its maximum size if the window is square, but smaller otherwise); in that case, you simply do the same thing to the height instead of the width.

float aspect = width / height;
glViewport(0, 0, width, height);
if (aspect >= 1.0)
  glOrtho(-50.0 * aspect, 50.0 * aspect, -50.0, 50.0, 1.0, -1.0);
else
  glOrtho(-50.0, 50.0, -50.0 / aspect, 50.0 / aspect, 1.0, -1.0);

Note that in the second case we divide rather than multiply. This is simply because we computed the aspect ratio as width / height rather than height / width; take the reciprocal if you find it easier to understand that way.

Again, this is not the only way to manage aspect ratio; this is just a very simple one for making sure that your content is neither squished nor cut off. Figure out what you want to happen when your window is wide, tall, or whatever; then work out the mathematics of it.

share|improve this answer
    
Thank you for the VERY insightful response. Answered my question beyond sufficiently. –  Chris Henderson Feb 25 '13 at 16:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.