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

14 篇文章 1 订阅
11 篇文章 0 订阅
首先,创建一个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; }
            }

            tEyeX = tRadius * cos(tVerticalAng) * cos(tHorizonAng);
            tEyeY = tRadius * sin(tVerticalAng);
            tEyeZ = tRadius * cos(tVerticalAng) * sin(tHorizonAng);
        }
        prePt.x = nowPt.x;
        prePt.y = nowPt.y;
    }
}


注意,为了达到改变视角的效果,需要把OpenGL视角的设置移动到 RenderScene() 函数中:

void C***Dlg::RenderScene() {

    glMatrixMode(GL_PROJECTION);                            // 设置modelview 和 projection
    glLoadIdentity();                                       // 此处尤其不能少glLoadIdentity()
    gluPerspective(tFovy, 1, 0.1, 1000.0);                  // 注意zNear,zFar的取值
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(tEyeX, tEyeY, tEyeZ, tCenterX, tCenterY, tCenterZ, tUpX, tUpY, tUpZ);

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 1.0, 1.0);
    glutWireCube(50.0);
   
    SwapBuffers(hrenderDC);                                    // 使用glFlush()没有显示?
}

    之后就可以在MFC中通过鼠标操作改变OpenGL的绘制视角。
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值