且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

MFC中OpenGL旋转的问题

更新时间:2021-07-05 00:31:09

 要求用户不干涉的情况下让物体***旋转,这如果用win32的sdk直接来实现的话,就像Nehe的教程上那样是比较容易做的,可以在空闲事件的情况下调用绘图部分代码;

    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))    // Is There A Message Waiting?
        {
        
                TranslateMessage(&msg);                // Translate The Message
                DispatchMessage(&msg);                // Dispatch The Message
        }
        else                                        // If There Are No Messages
        {
            DrawGLScene();
        }
但MFC中我不了解到底该怎么弄才好,起先也是想放到空闲事件处理程序中去调用绘图代码,就写了如下代码: 
BOOL COpenGLDemoApp::OnIdle(LONG lCount) 
{
    // TODO: Add your specialized code here and/or call the base class
    CFrameWnd*   pw=(CFrameWnd*)AfxGetMainWnd();  
    ((COpenGLDemoView*)pw->GetActiveView())->DrawGLScene();
    return CWinApp::OnIdle(lCount);
}

可发现效果不对劲,必须要用户的鼠标在上面滑动才会旋转,和要求完全不符合呀。于是我就换了个想法,试着用了一个定时器,让它定时刷新重绘,从而产生出旋转的效果,代码如下:

int COpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    // TODO: Add your specialized creation code here
    HWND hWnd = this->GetSafeHwnd();    
    HDC hDC = ::GetDC(hWnd);

    if(this->SetWindowPixelFormat(hDC)==FALSE)
    {//设置像素格式
        return 0;
    }
    if(this->CreateViewGLContext(hDC)==FALSE)
    {//创建RC并选为所用
        return 0;
    }
    if(!this->InitGL())
    {//初始化openGL
        return 0;
    }
    this->SetTimer(1,10,NULL); 
    return 0;
}
void COpenGLDemoView::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    this->DrawGLScene();
}
void COpenGLDemoView::OnTimer(UINT nIDEvent) 
{
    // TODO: Add your message handler code here and/or call default
    //控制旋转角度
    rTri+=1.2f;
    if(rTri>=360.0f)
    {
        rTri-=360.0f;
    }
    rQuads-=1.15f;
    if(rQuads<=-360.0f)
    {
        rQuads+=360.0f;
    }

    InvalidateRect(NULL,FALSE);//角度更新了,通知其重绘
    CView::OnTimer(nIDEvent);
}
int COpenGLDemoView::DrawGLScene()                                   
{// Here's Where We Do All The Drawing
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
    glShadeModel(GL_SMOOTH);
    glLoadIdentity();                                    // Reset The Current Modelview Matrix
    glTranslatef(-1.5f,0.0f,-6.0f);//物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中
    glRotatef(rTri,0.0f,1.0f,0.0f);
    glBegin(GL_TRIANGLES);                            // 绘制三角形
        glColor3f(1.0f,0.0f,0.0f);
        glVertex3f( 0.0f, 1.0f, 0.0f);                    // 上顶点
        glColor3f(0.0f,1.0f,0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);                    // 左下
        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);                    // 右下
    glEnd();                                // 三角形绘制结束
    glShadeModel(GL_FLAT);
    glLoadIdentity();
    glTranslatef(1.5f,0.0f,-6.0f);
    glRotatef(rQuads,1.0f,0.0f,0.0f);
    glBegin(GL_QUADS);                            //  绘制正方形
        glColor3f(1.0f,0.0f,0.0f);
        glVertex3f(-1.0f, 1.0f, 0.0f);                    // 左上
        glColor3f(1.0,1.0f,1.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);                    // 右下

        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);                    // 左下
        glColor3f(0.0f,1.0f,0.0f);
        glVertex3f( 1.0f, 1.0f, 0.0f);                    // 右上
    glEnd();                                // 正方形绘制结束
    glFlush();
    rTri+=1.2f;
    if(rTri>=360.0f)
    {
        rTri-=360.0f;
    }
    rQuads-=1.15f;
    if(rQuads<=-360.0f)
    {
        rQuads+=360.0f;
    }
    HWND hWnd = this->GetSafeHwnd();    
    HDC hDC = ::GetDC(hWnd);
    SwapBuffers(hDC);
    return TRUE;                                        // Everything Went OK
}
      这下旋转的效果是有的,但由于是强制其重绘,所以画面刷新不过来,即使我用了双缓冲,画面还是闪烁得很。这个问题困惑了我一晚上,到底应该怎么弄呢?


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/07/29/835632.html,如需转载请自行联系原作者