天天看点

基于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模型旋转