MFC & OpenGL:通过鼠标操作变换视角

首先,创建一个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; }
       

你可能感兴趣的:(MFC,图形学,OpenGL,C/C++)