在大部分3d在游戏或模拟模型中,鼠标或键盘可以从不同的角度观察物体,这实际上是通过相机漫游来实现的。
相机漫游主要是通过函数通过设置实现gluLookat()实现计算机漫游的参数。
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 centery代表相机镜头对准的物体在世界坐标中的位置
upx upy upz 世界坐标中镜头向上的方向
例如gluLookat(0,0,10,0,0,0,0,1,0)在最后三个数字中只有y轴d数为一,说明是镜头上方向上的正常状态。这个时候如果把后三个数(0、1、0)改成(0、-1、0),说明镜头上方朝下,一般来说就是人头朝下观察事物,得到的画面会是倒置的画面。
前六个数字也很容易理解,这意味着将相机放在世界坐标(0、0、10)的位置,镜头对准原点(0、0、0)
理解了gluLooka()函数后,可以控制参数来控制相机的漫游。
以下是代码流程
float eyex, eyey, eyez;
float eyexl, eyeyl, eyezl;
float myAngle;
首先定义相关参数,初始化设置参数
eyex = 0.0f;
eyey = 0.0f;
eyez = 0.0f;
myAngle = 0.0f;
eyexl = sin(myAngle); //0
eyeyl = 0.0f;
eyezl = -cos(myAngle); //1
eyex eyey eyez控制相机的初始位置,eyexl eyeyl eyezl是相机位置的变化
在display()设置函数gluLookat()函数,
gluLookAt(eyex, eyey, eyez, eyex eyexl, eyey eyeyl, eyez eyezl, 0 , 1 , 0);
编写函数,实现摄像机在水平方向的360度旋转和前后距离的变化
相机水平旋转:
void orientMe(float angle) { eyexl = sin(myAngle); eyezl = -cos(myAngle); InvalidateRect(NULL, FALSE); }
相机前进后退:
void moveMeFlat(int direction) { eyex = eyex direction * (eyexl) * 5; eyez = eyez direction * (eyezl) * 5; InvalidateRect(NULL, FALSE); }
利用OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)实现键盘的交互作用
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
///相机旋转 if (nChar == 'Q') { myAngle -= 0.06f; orientMe(myAngle); } else if (nChar == 'E') { myAngle = 0.06f; orientMe(myAngle); }
if (nChar == 'R') //拉近视角 { moveMeFlat(1); } else if (nChar == 'T') //拉远视角 { moveMeFlat(-1); }
}