转自:http://blog.csdn.net/longxiaoshi/article/details/8238933

12-11-29 14:55 1198人阅读 评论(6) 收藏 举报
 分类:
opengl(4) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

这里,我主要是利用opengl在一个picture控件中绘图,绘制的是一个静态图片,如果想实现动画,可以利用ontimer函数实现。编译器为vs2010。

1、首先创建一个基于对话框的MFC程序,我这里命名为MFC_Dlg。

2、配置opengl环境

首先添加链接库,在菜单栏 项目->属性->配置属性->链接器->输入->附加依赖项,添加glut32.lib,glaux.lib。如图:

然后,在stdafx.h里面添加opengl的头文件,如下:

  1. ////////////opengl头文件/////////////////////
  2. #include "gl\GLUT.H"
  3. #include "gl\GLAUX.H"
  4. #include <stdio.h>
  5. #include <math.h>

3、为对话框添加一个picture控件,ID为IDC_PIC。

4、添加消息相应函数

这里主要是为了在窗口销毁时释放DC和RC资源,为对话框添加了WM_DESTORY消息的相应函数。

5、在对话框头文件中添加相应的成员函数以及数据成员,如下:

  1. public:
  2. HGLRC m_hRC;                    //着色描述表
  3. CDC *m_pDC;                     //设备描述表
  4. BOOL InitOpengl();              //初始化opengl
  5. BOOL SetupPixelFormat();        //设置图片控件的像素格式
  6. void RenderScene();             //绘制图像

6、初始化opengl

在对话框的OnInitDialog()中调用了InitOpengl()对opengl进行初始化

  1. // TODO: 在此添加额外的初始化代码
  2. InitOpengl();       //初始化opengl
  3. return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

对应的InitOpengl()代码如下:

  1. BOOL CMFC_DlgDlg::InitOpengl()
  2. {
  3. //获取图片控件DC
  4. m_pDC=new CClientDC(GetDlgItem(IDC_PIC));
  5. if(m_pDC==NULL)
  6. return FALSE;
  7. //设置图片控件像素
  8. if (!SetupPixelFormat())
  9. return FALSE;
  10. //创建兼容RC
  11. m_hRC=wglCreateContext(m_pDC->GetSafeHdc());
  12. if (m_hRC==0)
  13. {
  14. return FALSE;
  15. }
  16. //激活RC
  17. if (wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE)
  18. {
  19. return FALSE;
  20. }
  21. //设置投影模式
  22. GLdouble aspect_ratio;
  23. GLsizei width,height;
  24. CRect rect;
  25. CWnd *pWnd=NULL;
  26. pWnd=GetDlgItem(IDC_PIC);
  27. pWnd->GetClientRect(rect);
  28. width=rect.right-rect.left;
  29. height=rect.bottom-rect.top;
  30. glViewport(0,0,width,height);
  31. aspect_ratio=(GLdouble)width/(GLdouble)height;
  32. glMatrixMode(GL_PROJECTION);
  33. glLoadIdentity();
  34. gluPerspective(45.0f,aspect_ratio,0.1,200.0);
  35. glMatrixMode(GL_MODELVIEW);
  36. glLoadIdentity();
  37. glClearColor(0.0f,0.0f,0.0f,0.0f);
  38. glClearDepth(1.0f);
  39. glEnable(GL_DEPTH_TEST);
  40. return TRUE;
  41. }

7、在上述函数中调用了像素初始化函数SetupPixelFormat()对picture控件的像素进行初始化,其代码如下:

  1. BOOL CMFC_DlgDlg::SetupPixelFormat()
  2. {
  3. static PIXELFORMATDESCRIPTOR pfd=
  4. {
  5. sizeof(PIXELFORMATDESCRIPTOR),
  6. 1,
  7. PFD_DRAW_TO_WINDOW|
  8. PFD_SUPPORT_OPENGL|
  9. PFD_DOUBLEBUFFER,
  10. PFD_TYPE_RGBA,
  11. 24,
  12. 0,0,0,0,0,0,
  13. 0,
  14. 0,
  15. 0,
  16. 0,0,0,0,
  17. 16,
  18. 0,
  19. 0,
  20. PFD_MAIN_PLANE,
  21. 0,
  22. 0,0,0
  23. };
  24. int m_nPixelFormat=ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);//在窗口找查找该像素格式
  25. if (m_nPixelFormat==0)
  26. {
  27. return FALSE;
  28. }
  29. if (SetPixelFormat(m_pDC->GetSafeHdc(),m_nPixelFormat,&pfd)==FALSE)//设置picture控件的像素格式
  30. {
  31. return FALSE;
  32. }
  33. return TRUE;
  34. }

8、通过上面两步,就完成了初始化,下面开始绘图。为了保证图形在重绘时仍然存在,在对话框的OnPaint()函数中通过调用RenderScene()实现绘图操作,将代码添加到else块中

  1. else
  2. {
  3. RenderScene();                          //向缓冲区绘图
  4. SwapBuffers(m_pDC->GetSafeHdc());        //交换缓冲区
  5. CDialogEx::OnPaint();
  6. }

其中,RenderScene()代码如下:

  1. void CMFC_DlgDlg::RenderScene()
  2. {
  3. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  4. glLoadIdentity();
  5. glTranslatef(0.0f,0.0f,-5.0f);
  6. glBegin(GL_TRIANGLES);
  7. glColor3f(1.0f,0.0f,0.0f);
  8. glVertex3f(0.0f,1.0f,1.0f);
  9. glColor3f(0.0f,1.0f,0.0f);
  10. glVertex3f(-1.5f,-1.0f,0.0f);
  11. glColor3f(0.0f,0.0f,1.0f);
  12. glVertex3f(1.5f,-1.0f,0.0f);
  13. glEnd();
  14. }

这里为了简单,只画了一个三角形。

9、释放资源

在写程序,如果忘记释放DC和RC,将会导致内存泄露,随着程序运行次数的增多,内存占有量越来越大。这里在WM_DESTORY的消息响应函数中释放资源,

  1. void CMFC_DlgDlg::OnDestroy()
  2. {
  3. CDialogEx::OnDestroy();
  4. // TODO: 在此处添加消息处理程序代码
  5. if (wglMakeCurrent(NULL,NULL)==FALSE)       //释放RC
  6. {
  7. MessageBox("无法释放RC");
  8. }
  9. if (wglDeleteContext(m_hRC)==FALSE)         //删除RC
  10. {
  11. MessageBox("无法删除RC");
  12. }
  13. if (m_pDC)
  14. {
  15. delete m_pDC;
  16. }
  17. m_pDC=NULL;
  18. }

运行效果如下:

到此,整个框架就建立起来了,其他的绘图操作都可以在RenderScene()中实现。如果想实现动画效果,只需要设置一个定时器,并在WM_TIMER消息响应函数中改变图形位置并调用RenderScene()即可,并且在OnDestroy中killtimer。

我也是初学者,有什么不对,大家请指正!

基于对话框的Opengl框架的更多相关文章

  1. VC基于单文档OpenGL框架

    本文是在VC6.0的环境下,运用MFC实现的OpenGL最基本框架,需要简单了解MFC编程(会在VC6.0里创建MFC单文档应用程序就行),甚至不必了解OpenGL的知识.以下是具体的步骤. 1.创建 ...

  2. 1、基于MFC的OpenGL程序

    首先,使用的库是GLUT以及GLAUX,先下载两者,添加查找路径以及链接   一.单文本文件   工程openGLMFC 1.创建单文本文件   2.添加路径.链接 方法如之前篇章所示, 链接库为op ...

  3. 【游戏开发】基于VS2017的OpenGL开发环境搭建

    一.简介 最近,马三买了两本有关于“计算机图形学”的书籍,准备在工作之余鼓捣鼓捣图形学和OpenGL编程,提升自己的价值(奔着学完能涨一波工资去的).俗话说得好,“工欲善其事,必先利其器”.想学习图形 ...

  4. 基于MFC的OpenGL程序<转>

    原贴地址:https://www.cnblogs.com/pinking/p/6180225.html 首先,使用的库是GLUT以及GLAUX,先下载两者,添加查找路径以及链接   一.单文本文件   ...

  5. VS2013 MFC基于对话框编程

    前言一直利用Qt库做Ui设计,但针对于一些MFC项目,掌握一些必要的MFC开发技巧还是很有必要的.这篇博客里就将自己所学的一些MFC浅显知识记录一下,方便今后的学习.博客里只记录关键步骤. 一.新建M ...

  6. VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程

    首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...

  7. VS中基于对话框的MFC利用换肤改变边框颜色及格式

    第一版本: http://ishare.iask.sina.com.cn/f/13836420.html?from=like 2. http://www.cnblogs.com/phinecos/ar ...

  8. 基于LoadRunner构建接口测试框架

    基于LoadRunner构建接口测试框架 http://www.docin.com/p-775544153.html

  9. 基于对话框的MFC应用程序基本结构

    新建一个基于对话框的MFC应用程序,假设命名为 Test:则该应用程序在刚创建的时候,有4个非常重要的文件和3个类: 4个非常重要的文件 1.Test.h 2.Test.cpp (应用程序类头文件) ...

随机推荐

  1. 一个免费的API-手机号码归属地接口

    手机号码归属地接口:根据手机号码或手机号码的前7位,查询手机号码归属地信息,包括省份 .城市.区号.邮编.运营商和卡类型. 接口文档:https://www.juhe.cn/docs/api/id/1 ...

  2. jquery方法

    $.inArray(被判断的量,ArrayName);  如果存在返回索引值,如果不存在返回-1 $.unique() 数组去重   根据去重前后的长度,判断是否有重复 $.each(被遍历的数组,f ...

  3. npm安装package.json

    npm安装package.json时,直接转到当前项目目录下,用命令npm install 或npm install --save-dev安装即可,自动将package.json中的模块安装到node ...

  4. swoole新手教程01-环境搭建及扩展安装

    写在前面的废话 <swoole源代码分析>已经写了13章,整个swoole的核心架构基本都分析的差点儿相同了.于是心里一直以来想整理swoole的文档并写一份教程的想法就再度浮了出来. 实 ...

  5. UML类图简明教程

    作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells Github:https://github.co ...

  6. android开发系列之ContentObserver

    在这篇博客里面我想要分享一下自己最近在项目里面遇到一个比较好的数据同步解决方案,首先让我们先来看看该方案的应用场景:我们在客户端本地利用数据库缓存了一些数据,当我们检测到数据库里面的数据发生变化的时候 ...

  7. XFire Web Service客户端开发

    一.项目创建: 创建一个Maven的web工程 Maven包导入pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0&qu ...

  8. python学习(一)运行第一个python脚本

    当然这里指的是在linux或者unix下,像写bash脚本那样 #!/usr/bin/python print('The Bright Side ' + 'of Life...') 反正我建议就算一开 ...

  9. 模拟struts2

    利用到的技术:dom4j和xpath 自己写一个Filter 在doFilter中拦截请求 // 2.1 得到请求资源路径            String uri = request.getReq ...

  10. 在linux系统中I/O 调度的选择 (转)

    I/O 调度算法再各个进程竞争磁盘I/O的时候担当了裁判的角色.他要求请求的次序和时机做最优化的处理,以求得尽可能最好的整体I/O性能. 在linux下面列出4种调度算法 CFQ (Completel ...