OpenGL 视口变形

Posted

技术标签:

【中文标题】OpenGL 视口变形【英文标题】:OpenGL viewport distortion 【发布时间】:2015-09-06 07:51:39 【问题描述】:

我还是 OpenGL 的初学者。我正在尝试使用着色器在 1280 x 720 的屏幕上绘制一个完美的正方形。

我正在使用 OpenGL 核心配置文件,版本 3.3。 当我试图在 1280 x 720 中画一个正方形时,我被困住了

经过一段时间的搜索,我意识到尺寸被视口大小扭曲了,在将视口大小更改为 720 x 720 后,我得到了这个。

在旧版 OpenGL 中,他们有一个 solution 来解决这个问题,但现在它在核心配置文件中已被弃用。

问题:如何仅使用核心配置文件 OpenGL 3.3 在 1280 x 720 屏幕尺寸中绘制一个完美的正方形?

【问题讨论】:

你需要做同样的事情。应用正交投影变换。在你的情况下,只是在着色器中。 @NicoSchertler 着色器有这样的功能吗?还是我必须自己计算? shader没有内部解决这个问题,购买可以使用外部库,比如glm。 glm.g-truc.net/0.9.7/index.html 对于正交投影,根据兼容模式的描述创建矩阵:opengl.org/sdk/docs/man2/xhtml/glOrtho.xml 【参考方案1】:

应用投影变换是解决此问题的最标准方法。您可以在几乎所有展示如何将 OpenGL 与着色器一起使用的教程中找到有关如何执行此操作的详细信息。总之,您通常在顶点着色器中将投影矩阵作为统一变量,并将其应用于输入位置:

uniform mat4 ProjMat;
in vec4 InPosition;
...
    gl_Position = ProjMat * InPosition;

在您的 C++ 代码中,您计算​​矩阵以应用必要的缩放,并使用 glUniformMatrix4fv() 进行设置。

另一种选择是保持视口为正方形。虽然视口通常设置为与窗口的大小相匹配,但情况并非必须如此。例如,视口可以超出窗口的大小。

要使用这种方法,您将在代码中设置视口以响应窗口(重新)大小事件。加上wh窗口的宽高:

if (w > h) 
    glViewport(0, (h - w) / 2, w, w);
 else 
    glViewport((w - h) / 2, 0, h, h);

这会将两个窗口尺寸中较大的一个作为视口大小,并将视口扩展到另一个维度的窗口之外,以生成方形视口。

【讨论】:

【参考方案2】:

(2.0/width, 2.0/height) 缩放所有内容。如果您有一个相机矩阵,只需将其与此缩放相乘​​即可。

使用该变换,您可以将位置作为像素输入,原点位于屏幕中间。

【讨论】:

以上是关于OpenGL 视口变形的主要内容,如果未能解决你的问题,请参考以下文章

openGL如何在改变窗口大小时,使自己的图形不被拉伸

opengl:设置视口和 glortho 时遇到问题

OpenGL 3/GLFW 空白视口

OpenGL编程 基础篇世界窗口和视口

在 C++.NET 中使用 OpenGL 并在视口上绘画

OpenGL:使用 FBO 和视口偏移问题渲染到纹理