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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值