本文介绍了OpenGL的伸展形状 - 长宽比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个大小我openGL的观点(可以说..)800(宽)X600(高)。然后我得到的coords的2D对象:

  0.0,0.0
0.1,0.0
0.1,0.1
0.0,0.1
 

这一点,因为你明白应该是一个正方形(基于类推)。但在我的OpenGL视图,打印此捉襟见肘。现在,我明白为什么会这样。它基本上是因为即时工作的1,1默认矩阵。而且,由于我的800x600分辨率不必须的1纵横比,我的造型是越来越捉襟见肘。

现在即时通讯就如何解决这一问题更感兴趣。香港专业教育学院读到像glFrustum,glOrtho,glViewPort功能这是发生在投影矩阵,可以解决这些问题。事情是,即时通讯不知道如何使用它们。我基本上要为做一个正方形的时候保持上述COORDS,实际上apear作为我的观点一个正方形。

请告诉我解决这个问题的正确方法是什么?

解决方案

  glViewport(0,0,宽度,高度);
glMatrixMode(GL_PROJECTION);
浮动方面=(浮点)宽/(浮动)的高度;
glOrtho(-aspect,方面,-1,1,-1,1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
 

更新:解释发生了什么

OpenGL是一个状态机和在OpenGL-2.1及以下的情况下,维护一组变换矩阵。顶点↑v 首先被乘以的模型视图的矩阵来产生眼坐标顶点↑V',这是用于照明计算。然后点击↑V'乘上的预测的矩阵,以达到所谓的裁剪空间↑V'其中(顾名思义它)被执行的剪切操作(或者至少它们的结果被定义)。从裁剪空间的所谓的归一化设备坐标的(NDC)通过计算↑v# {X,Y,Z,W} = ↑v {X,Y,Z,W} / ↑v _W

↑v#被定义为在区间[-1 ... 1]它被映射到填充所选的视口矩形。视口不影响变换矩阵!这是唯一的转化NDC到窗口坐标它定义了。

在code以上我设置模型视图矩阵身份,即顶点进入投影,因为它们。投影本身是一个邻投影,映射的x值范围[-aspect ...方面]→[-1 ... 1]和y的值范围为[-1 ... 1]→[-1 ... 1](即没有变化ÿ )。因此,顶点获得由窗口方面转变,以适应NDC的视口值的范围。

和为什么我告诉你,OpenGL是一个状态机?因为这意味着你可以随时切换投影和变换。所以,如果你需要渲染一个小地图,不得到它放置在3D场景中挣扎。只需切换视口和投影它。一般来说,你应该将所有的渲染状态(这意味着所有的矩阵)的绘图功能。窗口的事件处理程序(除了重绘处理程序)应该在所有执行任何的OpenGL操作。

I got my openGL view at a size of (lets say..) 800(width)x600(height).Then i got a 2D object of coords:

0.0 , 0.0
0.1 , 0.0
0.1 , 0.1
0.0 , 0.1

this, as you understand is supposed to be a square (based on analogy).But on my openGL view prints this stretched. Now, i understand why this is happening. Its basically because im working on the default matrix of -1,1.And since my resolution of 800x600 doesnt have an aspect ratio of 1, my shape is getting stretched.

Now im more interested on how to fix this. Ive read about functions like glFrustum, glOrtho, glViewPort which are happening on the projection matrix and can address such issues. Thing is, im not sure on using them. What i basically want is keep the above coords when making a square and actually apear as a square on my View.

Whats the correct way of addressing this issue?

解决方案
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.

这篇关于OpenGL的伸展形状 - 长宽比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 01:59