Resize window, prevent stretching

Started by
3 comments, last by ProjectinMatrix 12 years, 6 months ago
Hi guys

I have an OpenGL enabled window up and running. I'm running into a slight problem. When the window is resized the content stretches. I recalculate the projection matrix correctly, the issue is how the window coordinates stay 1 at the edges. This makes reszing super obdious when making the window wider. I think i can solve this by scaling the modelview matrix when the window is resized, if that is the case i can figure x and y out, but what do i scale z by, if anything at all?

Is there a batter way to do this? All i want is for my character model (and everything else) to stay the same size once the window has been resized...

Thanks in advance for any help!
Advertisement
Are you using orthographic projection?
If you're using perspective projection as in "normal 3D" it's usually not a good idea to keep the models at the same size in pixels, but rather keep them the same size relative to the window. Otherwise you will at best get a lot of distortion at the edges of your viewport when the window is larger.

EDIT: Perhaps I'm misunderstanding.. how do you set up your projection matrix?
If the model gets stretched in one direction, just set the correct aspect ratio for the width/height relation when constructing the projection matrix. How to do that depends on which method you use to construct it.
Thanks for the reply, i am using perspective projection. The below code is what i'm using to reset the projection.



void OpenGLResetProjection() {
RECT window = { 0 };
GetWindowRect(hwnd, &window);
glViewport(0, 0, window.right - window.left, window.bottom - window.top);

float fov = 62.0f;
float aspect = (float)GetSystemMetrics(SM_CXSCREEN) / (float)GetSystemMetrics(SM_CYSCREEN);

float top = openGLNear * float(tanf(fov * 3.14159265f / 360.0f));
float bottom = -1.0f * top;
float left = bottom * aspect;
float right = -1.0f * left;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(left, right, bottom, top, openGLNear, openGLFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}



Initially after reading your post i assumed the issue was with this line:
float aspect = (float)GetSystemMetrics(SM_CXSCREEN) / (float)GetSystemMetrics(SM_CYSCREEN);
So i changed it to:
float aspect = (float)(window.right - window.left) / (float)(window.bottom - window.top);
But the issue still happens. This is the normal sized window, and here is a resized version not scaling right...

I know it's hard to help with just a code snippet, so here is the full window code: http://pastebin.com/6j2QpZxn

[size="5"]EDIT:
I think i found the solution on the OpenGL FAQ: http://www.opengl.or...sformations.htm

There is a section on resizing:
[font="monospace"]
float cx, halfWidth = windowWidth*0.5f;
float aspect = (float)windowWidth/(float)windowHeight;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* cx is the eye space center of the zNear plane in X */
glFrustum(cx-halfWidth*aspect, cx+halfWidth*aspect, bottom, top, zNear, zFar);
[/font][font="monospace"]But i don't get how to find cx....[/font]
A minor detail is you probably want GetClientRect instead of GetWindowRect, as the window rect includes borders.

As for the values, you probably want cotangent instead of tangent. Try setting your matrix up like in gluPerspective, http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml.

EDIT: cx should be zero if you want the center of the frustum in the center of the viewport.
Erik,
Thanks for the suggestions and the catch.
So it turns out i was dumb. I was testing my scene with Vertex2f which defaults the z value to 0. Also i was using 1 for both the near and far planes. Problem now solved!
Thanks for the help!

Edit:
The above pastebin link is broken. This is the final version.

This topic is closed to new replies.

Advertisement