OpenGL stretched shapes - aspect ratio

风格不统一 提交于 2019-11-27 11:59:06
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float)width / (float)height;
glOrtho(-aspect, aspect, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Update: Explanation what happens

OpenGL is a state machine and in the case of OpenGL-2.1 and below maintains a set of transformation matrices. A vertex ↑v first gets multiplied with the modelview matrix to yield a eye coordinate vertex ↑v', which is used for lighting calculations. Then ↑v' is multiplied by the projection matrix to reach the so called clip space ↑v'', where (the name suggests it) the clipping operations are performed (or at least their outcome is defined). From clip space the so called Normalized Device Coordinates (NDC) are reached by calculating ↑v#{x,y,z,w} = ↑v{x,y,z,w}/↑v_w

↑v# is defined to be in the range [-1 … 1] which is mapped to fill the selected viewport rect. The viewport does not influence the transformation matrices! It's only the transformation from NDC to window coordinates it defines.

In the code above I set the modelview matrix to identity, i.e. the vertices go into projection as they are. The projection itself is a ortho projection, that maps the x value range [-aspect … aspect] → [-1 … 1] and y value range [-1 … 1] → [-1 … 1] (i.e. no change for y). So vertices get transformed by the window aspect to fit into the NDC to viewport value range.

And why did I tell you that OpenGL is a state machine? Because it means that you can switch projections and transformations anytime. So if you need to render a minimap, don't struggle with getting it placed in the 3D scene. Just switch the viewport and projection for it. In general you should set all rendering state (that means all the matrices) in the drawing function. Window event handlers (except the redraw handler) should perform no OpenGL operations at all.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!