基于OpenGL显示平台功能开发-MFC框架篇

来源:互联网 发布:网络协议各层的功能 编辑:程序博客网 时间:2024/05/16 14:56

基于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[3];      ...   }
    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) == -1)            return -1;            m_pDC = new CClientDC(this);            InitializeOpenGL(m_pDC);            Init();            return 0;        }        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(0,0,cx,cy);        }        void CMyOpenGLProjectView ::OnDestroy()        {            CView::OnDestroy();            wglMakeCurrent(0,0);            wglDeleteContext( m_hRC);            if (m_hPalette)            DeleteObject(m_hPalette);            if ( m_pDC )            {                delete m_pDC;            }        }        void CMyOpenGLProjectView ::Init()        {            camPos[0]    = 0.0f;            camPos[1]    = 0.0f;            camPos[2]    = 1500.0f;            m_fViewAngle = 45.0f;       // 初始化相机视角45°            glClearColor(0.5,0.5,0.5,1.0);  //单一背景颜色默认值            glClearDepth(1.0F);            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结构的大小             1,                                // 版本号             PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图             PFD_SUPPORT_OPENGL |              // 支持 OpenGL             PFD_DOUBLEBUFFER,                 // 双缓存模式             PFD_TYPE_RGBA,                    // RGBA 颜色模式             24,                               // 24 位颜色深度             0, 0, 0, 0, 0, 0,                 // 忽略颜色位             0,                                // 没有非透明度缓存             0,                                // 忽略移位位             0,                                // 无累加缓存             0, 0, 0, 0,                       // 忽略累加位             32,                               // 32 位深度缓存                 0,                                // 无模板缓存             0,                                // 无辅助缓存             PFD_MAIN_PLANE,                   // 主层             0,                                // 保留             0, 0, 0                           // 忽略层,可见性和损毁掩模         };          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[256];        } logicalPalette = { 0x300, 256 };        BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};        BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};        BYTE blues[] = {0, 85, 170, 255};        for (int colorNum=0; colorNum<256; ++colorNum)        {            logicalPalette.aEntries[colorNum].peRed =                reds[colorNum & 0x07];            logicalPalette.aEntries[colorNum].peGreen =                greens[(colorNum >> 0x03) & 0x07];            logicalPalette.aEntries[colorNum].peBlue =                blues[(colorNum >> 0x06) & 0x03];            logicalPalette.aEntries[colorNum].peFlags = 0;        }        m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);    }    void CMyOpenGLProjectView::Projection()    {        glMatrixMode(GL_PROJECTION);        glLoadIdentity();        gluPerspective(m_fViewAngle, m_width/m_height, 1.0F, 1000000.0F);        glMatrixMode(GL_MODELVIEW);        glLoadIdentity();        gluLookAt(camPos[0],camPos[1],camPos[2],0,0,0,0,1,0);    }    void CMyOpenGLProjectView::RunScene()    {        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );        Projection();    // 实施投影变换,透视投影        SwapBuffers(m_pDC->GetSafeHdc());    }

`
3. 至此,一个简单的MFC下OpenGL绘图环境基本已搭建完成,运行程序,效果如下所示。
这里写图片描述

绘制旋转的三角形

为了使场景的显示看的丰富,下面就在场景中绘制一个简单的带颜色的三角形,并使三角形能绕着轴旋转。

绘制三角形的代码如下:

void CMyOpenGLProjectView::RunScene(){    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );    Projection();    // 实施投影变换,透视投影    // 绘制场景    glPushMatrix();    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());}

运行程序,效果如下所示。
这里写图片描述

添加旋转操作
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模型旋转

0 0