apo*_*iat 10 opengl 2d aspect-ratio
我的openGL视图大小为(比方说)800(宽度)x600(高度).然后我得到了一个二维对象:
0.0 , 0.0
0.1 , 0.0
0.1 , 0.1
0.0 , 0.1
Run Code Online (Sandbox Code Playgroud)
这个,正如你所理解的那样应该是一个正方形(基于类比).但是在我的openGL视图中打印出这个拉伸.现在,我理解为什么会这样.它基本上是因为我正在使用-1,1的默认矩阵.由于我800x600的分辨率没有1的宽高比,我的形状变得紧张.
现在我对如何解决这个问题更感兴趣.我已经阅读过像glFrustum,glOrtho,glViewPort这样的函数,它们正在投影矩阵上发生,可以解决这些问题.事实是,我不确定使用它们.我基本上想要的是在制作正方形时保持上述坐标,并且在我的视图上实际上是一个正方形.
什么是解决这个问题的正确方法?
dat*_*olf 23
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();
Run Code Online (Sandbox Code Playgroud)
OpenGL是一个状态机,在OpenGL-2.1及以下的情况下维护一组转换矩阵.首先将顶点↑v与模型视图矩阵相乘以产生眼睛坐标顶点↑v',其用于照明计算.然后↑v'乘以投影矩阵以达到所谓的剪辑空间 ↑v'',其中(名称暗示它)执行剪切操作(或者至少定义它们的结果).通过计算↑v# {x,y,z,w} = ↑v {x,y,z,w}/↑v _w ,从剪辑空间到达所谓的标准化设备坐标(NDC)
↑v#定义在[-1 ... 1]范围内,映射为填充选定的视口rect.视口不会影响转换矩阵!它只是从NDC到它定义的窗口坐标的转换.
在上面的代码中,我将模型视图矩阵设置为identity,即顶点按原样进入投影.投影本身是一个正投影,它映射x值范围[-aspect ... aspect]→[-1 ... 1]和y值范围[-1 ... 1]→[-1 ... 1](即y没有变化) ).因此,顶点会被窗口方面转换为适合NDC的视口值范围.
为什么我告诉你OpenGL是状态机?因为这意味着您可以随时切换投影和变换.因此,如果您需要渲染小地图,请不要将其置于3D场景中.只需切换视口和投影即可.通常,您应该在绘图函数中设置所有渲染状态(即所有矩阵).窗口事件处理程序(重绘处理程序除外)根本不应执行任何OpenGL操作.