我正在尝试使用C++和openGL创建3D操作程序。我对openGL比较陌生,因此我经常必须查找文档以找到合适的功能来完成我想要的事情。我以为我对正交投影和透视投影有了很好的了解(因为glOrtho创建了一个正交投影,其中不同的z值看起来并不相同,而glFrustum创建了一个透视投影,其中更接近的z值看起来更大)。但是,当我在程序中换出glOrthoglFrustum时,看不出任何区别。我在下面复制了一个显示效果的小程序。作为引用,我将openGL与freeglut一起使用。

#include "GL/freeglut.h"
void initFunc()
{
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1, 1, -1, 1, -1, 1);

}

void displayFunc()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);

    glColor3f(1.0f, 1.0f, 0.0f);
    glLineWidth(1.0f);
    glutWireTeapot(0.3);

    glTranslatef(0, -0.5, -0.5);
    glutWireTeapot(0.3);

    glutSwapBuffers();
}

int main(int argc, char ** argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(0, 0);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutCreateWindow("Teapot Perspective");

    initFunc();

    glutDisplayFunc(displayFunc);

    glutMainLoop();
}

我在绘制两个茶壶,它们在y和z轴上都略有偏移。据我了解,glOrtho应该使两个茶壶具有相同的位置,只是y偏移,而glFrustum应该使其中一个比另一个大。但是,它们都使茶壶完全相同。

我在这里想念什么吗?我还需要采取其他步骤来正确设置透视投影吗?还是我误解了glFrustum的工作原理?我也尝试过使用gluPerspective而不是glFrustum,但我似乎找不到合适的值来使用。我尝试使用FOV为90,纵横比为1以及各种z值的方法,但它们要么不产生茶壶,要么变形的茶壶无法识别。此外,gluPerspective似乎具有与带有相应参数的glFrustum调用不同的行为。我不确定这里缺少什么。

最佳答案

在正交投影中,因为w分量为1(对于笛卡尔输入坐标),所以 View 空间中的坐标线性映射到剪辑空间坐标,并且剪辑空间坐标等于规范化的设备坐标。
左,右,下,上,近和远的值定义一个框。盒子体积内的所有几何图形在视口(viewport)上都是“可见的”。

glOrtho 定义的正交投影矩阵为:

r = right, l = left, b = bottom, t = top, n = near, f = far

x:  2/(r-l)         0               0               0
y:  0               2/(t-b)         0               0
z:  0               0               -2/(f-n)        0
t:  -(r+l)/(r-l)    -(t+b)/(t-b)    -(f+n)/(f-n)    1

在“透视投影”中,投影矩阵描述了从针孔相机看到的世界3D点到视口(viewport)的2D点的映射。
摄像机视锥中的眼睛空间坐标(截断的金字塔)映射到立方体(规范化的设备坐标)。

c++ - glFrustum没有创建透视图-LMLPHP

透视投影矩阵可以由平截头体( glFrustum )定义。
距离leftrightbottomtop,是从 View 中心到视锥面侧面(在近平面上)的距离。 nearfar指定到平截头体上的近平面和远平面的距离。
r = right, l = left, b = bottom, t = top, n = near, f = far

x:  2*n/(r-l)      0              0                0
y:  0              2*n/(t-b)      0                0
z:  (r+l)/(r-l)    (t+b)/(t-b)    -(f+n)/(f-n)    -1
t:  0              0              -2*f*n/(f-n)     0

您提出这样的规范:
glFrustum(-1, 1, -1, 1, -1, 1);

不能定义适当的平截头体,因为近平面的值为负,远平面的值为正。

如果要检查OpenGL错误(通过 glGetError ),则将收到INVALID_OPERATION错误。

OpenGL 4.6 API Compatibility Profile Specification; 12.1. FIXED-FUNCTION VERTEX TRANSFORMATIONS; page 501:
>

09-30 22:51