首先你要明白一点,gluLookAt函数并不是真正的在场景生成之后再让你从某一点上LookAt!这个函数的前缀glu已经说明这是一个在gl族函数基础上的函数。他的作用其实是将当前矩阵乘上根据参数计算出来的一个矩阵,产生模拟的LookAt效果。
最简单的例子就是如果你这样调用:
gluLookAt( 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
gluLookAt( 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
其结果等于
gluLookAt( 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
所以其实这个函数的作用并不大,他的作用相当于一连串的glTranslate,glRotate,glScale函数并不是我们真正意义上的LookAt。
现在回到你上面的问题,如果你能够想通我上面的那些,就不难理解为什么要这么做了。
这个问题其实每个作OpenGL程序的程序员都会遇到,比如旋转一个茶壶,如何保证任意时刻的旋转都是基于当前视平面的?如果你简单的用两个glRotate或者在一个方向上用rotate然后再旋转视角(这种方法等价于第一种方法,因为对于OpenGL来说,你用LookAt旋转视点和相反方向Rotate相同的角度,是等价的)是没有用的,这样的话你的茶壶总有一个方向的旋转是绕茶壶的某个方向而不是当前视平面的。这很明白,先绕X轴转n角度再绕Y轴转m角度和倒过来先绕Y轴再绕X轴的几何意义是不一样的,但在如果使用这种方法,得到的结果却是一样的。
所以我对你描述的那个算法的猜测是,他计算当前的视点(真正的视点)和目标点形成的矢量,将这个矢量看成-Z,垂直于这个矢量的平面为XY平面(不知道他的XY坐标方向是怎么确定的),在这个坐标系里面做变换。这个牵涉到很复杂的数学计算,想想头都大。
我用的方法比较简单一些,我没有用LookAt,只是记录当前的变换矩阵,用户输入在某一个方向上旋转后,将旋转矩阵乘上当前矩阵。Render的时候用这个矩阵乘当前的变换阵就可以了。