我正在尝试使用C++和openGL创建3D操作程序。我对openGL比较陌生,因此我经常必须查找文档以找到合适的功能来完成我想要的事情。我以为我对正交投影和透视投影有了很好的了解(因为glOrtho
创建了一个正交投影,其中不同的z值看起来并不相同,而glFrustum
创建了一个透视投影,其中更接近的z值看起来更大)。但是,当我在程序中换出glOrtho
和glFrustum
时,看不出任何区别。我在下面复制了一个显示效果的小程序。作为引用,我将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点的映射。
摄像机视锥中的眼睛空间坐标(截断的金字塔)映射到立方体(规范化的设备坐标)。
透视投影矩阵可以由平截头体(
glFrustum
)定义。距离
left
,right
,bottom
和top
,是从 View 中心到视锥面侧面(在近平面上)的距离。 near
和far
指定到平截头体上的近平面和远平面的距离。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:
>