首先,创建一个MFC Dialog类,实现OpenGL的绘制,具体见之前的一篇博文《MFC中使用OpenGL》。
之后,使用MFC的鼠标事件函数来实现OpenGL中的视角变换,方法如下:
Step-1:
在 ***Dlg.h 中继续加入如下控制视角的变量:
double PI;
double tFovy; // 在gluPerspective中使用(在OnMouseWheel中使用)
CPoint prePt, nowPt; // 在OnMouseMove中使用
double tEyeX, tEyeY, tEyeZ; // 在gluLookAt中使用的3个向量
double tCenterX, tCenterY, tCenterZ;
double tUpX, tUpY, tUpZ;
double tVerticalAng, tHorizonAng, tRadius, tAngInc; // 水平方向、垂直方向的角、半径
并加入下述重载函数声明:
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); // 重载OnMouseWheel函数
afx_msg void OnMouseMove(UINT nFlags, CPoint point); // 重载OnMouseMove函数
Step-2:
在 ***Dlg.cpp 中加入如下修改:
在 BEGIN_MESSAGE_MAP() ... END_MESSAGE_MAP() 中加入:
ON_WM_MOUSEWHEEL()
ON_WM_MOUSEMOVE()
在 OnInitDialog() 中加入参数的初始化设置:
// 通过鼠标操作调整openGL视角的设置
PI = 3.1415926535897;
tAngInc = PI / 90; // 每次触发鼠标事件变换的角度值
tFovy = 45.0;
prePt.SetPoint(-1, -1); // 初始化prePt & nowPt(在OnMouseMove中使用)
nowPt.SetPoint(-1, -1);
tVerticalAng = 0.;
tHorizonAng = PI / 2;
tRadius = 400.0;
tEyeX = tRadius * cos(tVerticalAng) * cos(tHorizonAng);
tEyeY = tRadius * sin(tVerticalAng);
tEyeZ = tRadius * cos(tVerticalAng) * sin(tHorizonAng);
tCenterX = 0.;
tCenterY = 0.;
tCenterZ = 0.;
tUpX = 0.;
tUpY = 1.0;
tUpZ = 0.;
Step-3:
之后重载两个鼠标操作函数:
afx_msg BOOL CMy3dVcrProjDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) {
int tWheelCount = zDelta / 120;
if(tWheelCount > 0) {
tFovy += 1.0;
} else if(tWheelCount < 0) {
tFovy -= 1.0;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // 此处尤其不可少glLoadIdentity()
gluPerspective(tFovy, 1, 0.1, 1000.0); // 注意zNear,zFar的取值
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return TRUE;
}
// 在界面显示屏幕上通过鼠标操作变换绘制视角
afx_msg void C***Dlg::OnMouseMove(UINT nFlags, CPoint point) {
if(nFlags & MK_LBUTTON == TRUE) {
//MessageBox("mouse move function triggered!", "attentino", MB_OK);
nowPt.x = point.x;
nowPt.y = point.y;
if(prePt.x!=-1 && prePt.y!=-1 && nowPt.x!=-1 && nowPt.y!=-1) {
double tDx = nowPt.x - prePt.x;
double tDy = nowPt.y - prePt.y;
double tDis = sqrt(tDx*tDx+tDy*tDy);
if(tDx > 0.) {
tHorizonAng += tAngInc * tDx / tDis;
if(tHorizonAng < 0.) { tHorizonAng += 2*PI; }
if(tHorizonAng > 2*PI) { tHorizonAng -= 2*PI; }
} else if(tDx < 0.) {
tHorizonAng += tAngInc * tDx / tDis;
if(tHorizonAng < 0.) { tHorizonAng += 2*PI; }
if(tHorizonAng > 2*PI) { tHorizonAng -= 2*PI; }
}
if(tDy > 0.) {
tVerticalAng = tVerticalAng + tAngInc * tDy / tDis;
if(tVerticalAng > PI/2) { tVerticalAng = PI/2; }
} else if(tDy < 0.) {
tVerticalAng = tVerticalAng + tAngInc * tDy / tDis;
if(tVerticalAng < -PI/2) { tVerticalAng = -PI/2; }