OpenGL固定管线设置投影矩阵

0.前言

OpenGL如果没有设置投影矩阵,默认使用一个坐标范围在[-1.0,1.0]的正交投影。如果使用固定管线编程时要切换投影矩阵,步骤如下:

//切换当前矩阵为投影矩阵
glMatrixMode(GL_PROJECTION);
//将当前矩阵置为单位矩阵,即抛弃之前的更改
//OpenGL是状态机,会保存之前的状态
glLoadIdentity(); 
//设置投影矩阵
//如:设置为正交投影
//void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
//如:设置透视投影
//void glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar);
//或者这个透视投影
//void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);


//切换当前矩阵为模型矩阵
glMatrixMode(GL_MODELVIEW);
//将当前矩阵置为单位矩阵,即抛弃之前的更改
//OpenGL是状态机,会保存之前的状态
glLoadIdentity();
//一些view视图或者model实体的操作,如视图矩阵
//void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);

默认情况下,透视投影的观察点位于原点(0,0,0) ,并沿着z轴负方向进行观察(向显示器内部观察)。正交投影中,观察者在z轴正方向无穷远的位置,能看到视景中的任何物体。

1.正交投影设置

对于正交投影,可使用glOrtho函数:

void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) ;

创建一个正交投影矩阵,并且用这个矩阵乘以当前矩阵。
其中,近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。只有在视景体里的物体才能显示出来。如果最后两个值是(0,0),也就是near和far值相同了,视景体深度没有了,也就没法正常显示。
注意,所有的near和far值同时为正或同时为负, 值不能相同。如果没有其他变换,正交投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。

摄像机可以位于裁剪体内,所以near和far可以取两个正值或者一正一负。

如:glOrtho(-1.0,2.0,-3.0,4.0,-5.0,6.0); 创建了一个x-left=-1,x-right=2,y-bottom=-3,y-top=4,z-near=5,z-far=-6的一个裁剪体,z为一正一负说摄像机为默认值时在内部。

2.透视投影设置

对于透视投影,可使用glFrustum或者gluPerspective函数。

首先看glFrustum:

void glFrustum(GLdouble left, GLdouble Right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

创建一个透视投影的矩阵,并且用这个矩阵乘以当前矩阵。

这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的离视点的距离值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值(near/far 必须>0)。

摄像机不可以位于裁剪体内(?待研究),所以near和far都必须取正值,它的参数矩阵定义了裁剪体以及投影的类型,但是未定义摄像机的方位。OpenGL中的摄像机位于原点,并指向了Z轴的负方向。函数glFrustum只是修改了摄像机的 透镜,并非位置,为了改变位置或者朝向可以借助于模型视图矩阵相对于摄像机移动场景中的对象,或者通过变换,或者用函数gluLookAt()。因为glFrustum对参数far和near非常敏感,修改near和far则远景可能就影响很大,所以常用于观察近景。

再来看gluPerspective(glu开头的函数需要引入glu头文件或相关库):

void glPerspective(GLdouble fov, GLdouble aspect, GLdouble near, GLdouble far);

创建一个对称的透视型视景体,并且用这个矩阵乘以当前矩阵。

gluPerspective功能和glFrustum函数类似,参数不一样。参数fovy定义视野在Y-Z平面的角度,范围是[0.0, 180.0];参数aspect是投影平面宽度与高度的比率;参数Near和Far分别是近远裁剪面到视点(沿Z负轴)的距离,它们总为正值,意义和glFrustum的一样。

以上两个函数缺省时,视点都在原点,视线沿Z轴指向负方向。

使用glFrustum自定义一个gluPerspective:

//这样写
void MyPerspective( GLdouble fov, GLdouble aspectRatio, GLdouble zNear, GLdouble zFar )
{
    GLdouble rFov = fov * 3.14159265 / 180.0;
    glFrustum( -zNear * tan( rFov / 2.0 ) * aspectRatio,
              zNear * tan( rFov / 2.0 ) * aspectRatio,
              -zNear * tan( rFov / 2.0 ),
              zNear * tan( rFov / 2.0 ),
              zNear, zFar );
}

//或者这样写
void MyPerspective(double fovy, double aspect, double zNear, double zFar)
{
    double xmin, xmax, ymin, ymax;
    ymax = zNear * tan(fovy * 3.14159265 / 360.0);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;

    glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
}

3.参考

《OpenGL超级宝典》中文第五版

博客:https://blog.csdn.net/jiangdf/article/details/8460012

博客:https://www.cnblogs.com/zjzyh/p/4074583.html

博客:https://blog.csdn.net/peng6662001/article/details/7082436

博客:http://anony3721.blog.163.com/blog/static/51197420113206471827/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龚建波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值