这两个函数涉及到变换矩阵mvp中的 v p 两个矩阵
gluLookAt() 设置视图矩阵与当前矩阵相乘
gluPerspective() 设置投影矩阵与当前矩阵相乘
1.gluLookAt()
视点转换函数原型
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
该函数定义一个视图矩阵,并与当前矩阵相乘。
第一组eyex, eyey,eyez 相机在世界坐标的位置
第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置
第三组upx,upy,upz 相机向上的方向在世界坐标中的方向
你把相机想象成为你自己的脑袋:
第一组数据就是脑袋的位置
第二组数据就是眼睛看的物体的位置
第三组就是头顶朝向的方向(因为你可以歪着头看同一个物体)。
在osg中与虚基类osgGA::CameraManipulator中的成员变量
osg::Vec3d _homeEye;
osg::Vec3d _homeCenter;
osg::Vec3d _homeUp;
一一对应 。
void OrbitManipulator::setTransformation( const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up )
{
Vec3d lv( center - eye );
Vec3d f( lv );
f.normalize();
Vec3d s( f^up ); //^ 叉乘 cross product
s.normalize();
Vec3d u( s^f );
u.normalize();
osg::Matrixd rotation_matrix( s[0], u[0], -f[0], 0.0f,
s[1], u[1], -f[1], 0.0f,gluPerspective
s[2], u[2], -f[2], 0.0f,
0.0f, 0.0f, 0.0f, 1.0f );
_center = center;
_distance = lv.length();
_rotation = rotation_matrix.getRotate().inverse();
// fix current rotation
if( getVerticalAxisFixed() )
fixVerticalAxis( _center, _rotation, true );
}
2.gluPerspective()透视投影矩阵
设置投影矩阵,即平头截体。
函数原型
void gluPerspective(
GLdouble fovy, //角度
GLdouble aspect,//视景体的宽高比
GLdouble zNear,//近平面距离 沿z轴方向的两裁面之间的距离的近处
GLdouble zFar //远平面距离 沿z轴方向的两裁面之间的距离的远处
)
这个gluPerspective的实现是通过将当前矩阵与你通过这个函数指定的参数而建立的矩阵相乘来实现的,而在OpenGL中,矩阵的相乘都是连乘的,也就是说,你调用这个函数会与其他的变化矩阵的函数效果相叠加从而影响原矩阵(当然有时候确实需要这样做),所以,在调用这个函数之前,通常需要先调用glLoadidentity来把当前矩阵单位化,从而使各种变换效果不会叠加,比如旋转就只旋转,透视就只透视,通过调用glLoadidentity就不会既旋转又透视了。
参考:https://baike.baidu.com/item/gluLookAt/3708533?fr=aladdin