天天看點

基于OpenGL顯示平台功能開發-MFC架構篇基于OpenGL顯示平台功能開發-MFC架構篇

基于OpenGL顯示平台功能開發-MFC架構篇

簡介

關于OpenGL MFC應用程式架構的搭建,大家可以在網上找到很多相關的曆程。而且按照曆程的步驟,基本上可以很順利地搭建出來。為了更能充分的幫助讀者了解MFC下OpenGL環境搭建的過程。本篇主要對其步驟進行了一個詳細的介紹,在下一篇文章中會對其在建立中涉及到的理論知識及相應的OpenGL API函數接口做一個具體的分析介紹。

環境搭建步驟(單文檔)

  1. 選擇一個編譯環境(如VC2010),安裝GLUT工具包
    1. 下載下傳glut庫,下載下傳位址http://openglsource.com/download/download.htm,下載下傳glut-3.7.6-bin.zip
    2. 解壓下載下傳包,得到5個檔案(glut.dll,glut.h,glut.lib,glut32.dll,glut32.lib)

      1)把glut.h複制到D:\Program Files\Microsoft\Visual Studio10.0\VC\include\gl檔案夾中,如果沒有gl這個檔案夾則可以自己建立一個。(D是你安裝VS的盤的目錄)

      2)把glut.lib和glut32.lib放到靜态函數庫所在檔案夾(即與include并排的lib檔案夾下)。

      3)把解壓得到的glut.dll和glut32.dll放到作業系統目錄下面的system32檔案夾内。(典型的位置為:C:\Windows\System32)

  2. OpenGL在VC2010 下的配置
    1. 建立MFC單文檔應用程式,名稱命名為MyOpenGLProject,應用程式類型選擇單個文檔,其他預設,一直下一步,點選完成。
    2. 右擊工程名->屬性,彈出屬性頁,點選連結器->附加依賴項,添加glut.lib;glut32.lib,中間以分号隔開
    3. 在stdafx.h中添加#include< gl/glut.h>,此時opengl相關的檔案配置已基本完成。
    4. 接着在MyOpenGLProjectView.h頭檔案中添加如下成員及消息函數:
      class CMyOpenGLProjectView : public CView
         {
          ...
          public: 
                virtual void OnDraw(CDC* pDC);
      
          public:
                afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);
                afx_msg void OnSize(UINT nType, int cx, int cy);
                afx_msg BOOL OnEraseBkgnd(CDC* pDC);
                afx_msg void OnDestroy();
      
          protected:
                 void Init();
                 BOOL  InitializeOpenGL(CDC* pDC);
                 void SetLogicalPalette();
                 BOOL SetupPixelFormat();
                 void  RunScene();                // 繪圖工作再此完成
                 void  Projection(); // 實施投影變換
          private:
                  HGLRC            m_hRC;        // OpenGL繪制描述表
                  HPALETTE         m_hPalette;   // OpenGL調色闆
                  CDC*             m_pDC;        // OpenGL裝置描述表
                  GLfloat          m_width;        // 螢幕長度
                  GLfloat          m_height;       // 螢幕寬度
                  GLfloat          m_fViewAngle;   // 視角,初始45
                  GLfloat          camPos[]; 
           ...
         }
                 
    5. 在MyOpenGLProject.cpp源檔案中添加如下實作:
CMyOpenGLProjectView::CMyOpenGLProjectView()
        {
            m_hRC = NULL;           
            m_hPalette = NULL;  
            m_pDC = NULL;   
        }

        void CMyOpenGLProjectView::OnDraw(CDC* /*pDC*/)
        {
            CMyOpenGLProjectDoc* pDoc = GetDocument();
            ASSERT_VALID(pDoc);
            if (!pDoc)
                return;
            RunScene();
        }

        int CMyOpenGLProjectView ::OnCreate(LPCREATESTRUCT lpCreateStruct)
        {
            if (CView::OnCreate(lpCreateStruct) == -)
            return -;
            m_pDC = new CClientDC(this);
            InitializeOpenGL(m_pDC);
            Init();
            return ;
        }

        BOOL CMyOpenGLProjectView ::OnEraseBkgnd(CDC* pDC)
        {
            return TRUE;
        }

        void CMyOpenGLProjectView ::OnSize(UINT nType, int cx, int cy)
        {
            CView::OnSize(nType, cx, cy);
            m_width = cx;
            m_height = cy;
            glViewport(,,cx,cy);
        }

        void CMyOpenGLProjectView ::OnDestroy()
        {
            CView::OnDestroy();
            wglMakeCurrent(,);
            wglDeleteContext( m_hRC);
            if (m_hPalette)
            DeleteObject(m_hPalette);
            if ( m_pDC )
            {
                delete m_pDC;
            }
        }

        void CMyOpenGLProjectView ::Init()
        {
            camPos[]    = f;
            camPos[]    = f;
            camPos[]    = f;
            m_fViewAngle = f;       // 初始化相機視角45°
            glClearColor(,,,);  //單一背景顔色預設值
            glClearDepth(F);
            glShadeModel(GL_SMOOTH);
            glEnable(GL_DEPTH_TEST);
       }

       BOOL CMyOpenGLProjectView ::InitializeOpenGL(CDC *pDC)
       {
            m_pDC = pDC;
            SetupPixelFormat();
            //生成繪制描述表
            m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
            //重置目前繪制描述表
            wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
            return TRUE;
       }

        BOOL CMyOpenGLProjectView ::SetupPixelFormat()
        {
            PIXELFORMATDESCRIPTOR pfd = { 
            sizeof(PIXELFORMATDESCRIPTOR),    // pfd結構的大小 
            ,                                // 版本号 
            PFD_DRAW_TO_WINDOW |              // 支援在視窗中繪圖 
            PFD_SUPPORT_OPENGL |              // 支援 OpenGL 
            PFD_DOUBLEBUFFER,                 // 雙緩存模式 
            PFD_TYPE_RGBA,                    // RGBA 顔色模式 
            ,                               // 24 位顔色深度 
            , , , , , ,                 // 忽略顔色位 
            ,                                // 沒有非透明度緩存 
            ,                                // 忽略移位位 
            ,                                // 無累加緩存 
            , , , ,                       // 忽略累加位 
            ,                               // 32 位深度緩存     
            ,                                // 無模闆緩存 
            ,                                // 無輔助緩存 
            PFD_MAIN_PLANE,                   // 主層 
            ,                                // 保留 
            , ,                            // 忽略層,可見性和損毀掩模 
        };  
        int pixelformat;
        pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//選擇像素格式
        SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //設定像素格式
        if(pfd.dwFlags & PFD_NEED_PALETTE)
        SetLogicalPalette();    //設定邏輯調色闆
        return TRUE;
    }

    void CMyOpenGLProjectView ::SetLogicalPalette()
    {
        struct
        {
            WORD Version;
            WORD NumberOfEntries;
            PALETTEENTRY aEntries[];
        } logicalPalette = { ,  };
        BYTE reds[] = {, , , , , , , };
        BYTE greens[] = {, , , , , , , };
        BYTE blues[] = {, , , };
        for (int colorNum=; colorNum<; ++colorNum)
        {
            logicalPalette.aEntries[colorNum].peRed =
                reds[colorNum & ];
            logicalPalette.aEntries[colorNum].peGreen =
                greens[(colorNum >> ) & ];
            logicalPalette.aEntries[colorNum].peBlue =
                blues[(colorNum >> ) & ];
            logicalPalette.aEntries[colorNum].peFlags = ;
        }
        m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
    }

    void CMyOpenGLProjectView::Projection()
    {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        gluPerspective(m_fViewAngle, m_width/m_height, F, F);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(camPos[],camPos[],camPos[],,,,,,);
    }

    void CMyOpenGLProjectView::RunScene()
    {
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        Projection();    // 實施投影變換,透視投影

        SwapBuffers(m_pDC->GetSafeHdc());
    }
           

`

3. 至此,一個簡單的MFC下OpenGL繪圖環境基本已搭建完成,運作程式,效果如下所示。

基于OpenGL顯示平台功能開發-MFC架構篇基于OpenGL顯示平台功能開發-MFC架構篇

繪制旋轉的三角形

為了使場景的顯示看的豐富,下面就在場景中繪制一個簡單的帶顔色的三角形,并使三角形能繞着軸旋轉。

繪制三角形的代碼如下:

void CMyOpenGLProjectView::RunScene()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    Projection();    // 實施投影變換,透視投影

    // 繪制場景
    glPushMatrix();

    glBegin( GL_TRIANGLES );
    glColor3f( , ,  );
    glVertex3f( , ,  );
    glColor3f( , ,  );
    glVertex3f( -, -,  );
    glColor3f( , ,  );
    glVertex3f( , -,  );
    glEnd();

    glPopMatrix();

    SwapBuffers(m_pDC->GetSafeHdc());
}
           

運作程式,效果如下所示。

基于OpenGL顯示平台功能開發-MFC架構篇基于OpenGL顯示平台功能開發-MFC架構篇

添加旋轉操作

1. 首先,在MyOpenGLProjectView.h檔案中添加如下成員

class CMyOpenGLProjectView : public CView

{

public:

afx_msg void OnTimer(UINT_PTR nIDEvent);

private:

static double m_Rotatf; // 模型旋轉角度變量

}

2. 在MyOpenGLProjectView.cpp檔案中實作

double CMyOpenGLProjectView::m_Rotatf = 0.0; // 對旋轉變量進行初始化指派

void CMyOpenGLProjectView::RunScene()

{

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

Projection();    // 實施投影變換,透視投影

// 繪制場景
glPushMatrix();

glRotatef(m_Rotatf,0,1,0);      // 添加,繞y軸旋轉

glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.0, 300.0, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -300.0, -300.0, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 300.0, -300.0, 0.0 );
glEnd();

glPopMatrix();

SwapBuffers(m_pDC->GetSafeHdc());
           

}

void CMyOpenGLProjectView::OnTimer(UINT_PTR nIDEvent)

{

m_Rotatf += 10.0; // 添加

RunScene();

CView::OnTimer(nIDEvent);

}

int CMyOpenGLProjectView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

m_pDC = new CClientDC(this);
InitializeOpenGL(m_pDC);
Init();
SetTimer(0,100,0);  // 添加
return 0;
           

}

至此,旋轉動畫已添加完成,運作效果如下所示:

基于OpenGL顯示平台功能開發-MFC架構篇基于OpenGL顯示平台功能開發-MFC架構篇

源代碼位址連結:OpenGL MFC模型旋轉