原贴地址:https://www.cnblogs.com/pinking/p/6180225.html

首先,使用的库是GLUT以及GLAUX,先下载两者,添加查找路径以及链接

 
一、单文本文件  
工程openGLMFC
1、创建单文本文件
 
 
 
 
2、添加路径、链接
方法如之前篇章所示,
链接库为opengl32.lib ;glu32.lib ;glut32.lib ;glaux.lib
 
3、头文件
在stdafx.h中加入下列语句:
  1. //openGL 所需要的头文件
  2. #include <gl/gl.h>
  3. #include <gl/glu.h>
  4. #include <gl/glut.h>
  5. #include <gl/glaux.h>
4、设置窗口风格
将窗口风格设为WS_CLIPCHILDREN和 WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。
  1. BOOL CopenGLMFCView::PreCreateWindow(CREATESTRUCT& cs)
  2. {
  3. // TODO: Modify the Window class or styles here by modifying
  4. // the CREATESTRUCT cs
  5. cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  6. return CView::PreCreateWindow(cs);
  7. }
5、变量、函数声明
初始化GL,考虑到使用设备上下文、绘图上下文,
先在openGLMFCView.h中声明需要的变量以及函数
  1. HGLRC m_hRC; //RC 绘图上下文
  2. CDC* m_pDC; //DC 设备上下文
  3. BOOL InitializeOpenGL(); //初始化 OpenGL
  4. BOOL SetupPixelFormat(); //为 DC 建立像素格式
6、创建消息响应函数
初始化需要在WM_CREATE触发
资源释放在WM_DESTROY触发
窗口大小变化时 WM_SIZE触发,需要调整绘图
由于使用opengl绘制背景,故不需要窗口自己在绘制背景了,需要改写 WM_ERASEBACKGROUND消息触发的事件
 
故,打开classWizard,在openGLMFCView类中添加上面四个消息响应函数

OnCreate   OnDestroy  OnSize  OnEraseBkground

7、初始化

将通过建立像素格式和绘制上下文来初始化OpenGL. 在InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC),然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。

  1. int CopenGLMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. if (CView::OnCreate(lpCreateStruct) == -)
  4. return -;
  5.  
  6. // TODO: Add your specialized creation code here
  7. InitializeOpenGL();
  8. return ;
  9. }
  10.  
  11. BOOL CopenGLMFCView::InitializeOpenGL()
  12. {
  13. //客户区获得DC
  14. m_pDC = new CClientDC(this);
  15. //Failure to Get DC
  16. if (m_pDC == NULL)
  17. {
  18. MessageBox(L"Error Obtaining DC");
  19. return FALSE;
  20. }
  21. //为DC建立像素格式
  22. if (!SetupPixelFormat())
  23. {
  24. return FALSE;
  25. }
  26. //创建 RC
  27. m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
  28. //Failure to Create Rendering Context
  29. if (m_hRC == )
  30. {
  31. MessageBox(L"Error Creating RC");
  32. return FALSE;
  33. }
  34. //设定OpenGL当前线程的渲染环境。
  35. //以后这个线程所有的OpenGL调用都是在这个hdc标识的设备上绘制。
  36. if (::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
  37. {
  38. MessageBox(L"Error making RC Current");
  39. return FALSE;
  40. }
  41. //背景颜色
  42. ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  43. //深度缓存 1最大,让任何都能显示出来
  44. ::glClearDepth(1.0f);
  45. //如果通过比较后深度值发生变化了,会进行更新深度缓冲区的操作
  46. ::glEnable(GL_DEPTH_TEST);
  47. return TRUE;
  48. }
  49. //建立像素格式
  50. /////////////////////////////////////////////////////////////////////////////
  51. BOOL CopenGLMFCView::SetupPixelFormat()
  52. {
  53. static PIXELFORMATDESCRIPTOR pfd =
  54. {
  55. sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
  56. , // version number
  57. PFD_DRAW_TO_WINDOW | // support window
  58. PFD_SUPPORT_OPENGL | // support OpenGL
  59. PFD_DOUBLEBUFFER, // double buffered
  60. PFD_TYPE_RGBA, // RGBA type
  61. , // 24-bit color depth
  62. , , , , , , // color bits ignored
  63. , // no alpha buffer
  64. , // shift bit ignored
  65. , // no accumulation buffer
  66. , , , , // accum bits ignored
  67. , // 16-bit z-buffer
  68. , // no stencil buffer
  69. , // no auxiliary buffer
  70. PFD_MAIN_PLANE, // main layer
  71. , // reserved
  72. , , // layer masks ignored
  73. };
  74. int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
  75. if (m_nPixelFormat == )
  76. {
  77. return FALSE;
  78. }
  79. if (::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
  80. {
  81. return FALSE;
  82. }
  83. return TRUE;
  84. }

8、绘制场景

在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3)Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。

  1. void CopenGLMFCView::OnDraw(CDC* /*pDC*/)
  2. {
  3. CopenGLMFCDoc* pDoc = GetDocument();
  4. ASSERT_VALID(pDoc);
  5. if (!pDoc)
  6. return;
  7.  
  8. // TODO: add draw code for native data here
  9.  
  10. // 清除颜色、深度缓存
  11. ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  12.  
  13. //可以添加渲染函数
  14.  
  15. // Flush掉渲染流水线
  16. ::glFinish();
  17. // 交换前后缓存区
  18. ::SwapBuffers(m_pDC->GetSafeHdc());
  19.  
  20. }

9、背景绘制修改

 

试试改变窗口的大小,你会看到很严重的闪烁,并且关闭程序后会报告内存泄露,因此我们这就来解决这两个问题吧。

发生闪烁的原因是Windows先绘制背景,然后再是OpenGL绘制,因为我们已经让OpenGL负责清空背景色,因此我们不需要Windows去清空背景了

  1. BOOL CopenGLMFCView::OnEraseBkgnd(CDC* pDC)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4.  
  5. return TRUE;//CView::OnEraseBkgnd(pDC);
  6. }

内存泄露的原因是我们在InitializeOpenGL()中使用了new运算符来为CClientDC对象分配内存,因此需要显示delete掉。

  1. void CopenGLMFCView::OnDestroy()
  2. {
  3. CView::OnDestroy();
  4.  
  5. // TODO: Add your message handler code here
  6. if (::wglMakeCurrent(, ) == FALSE)
  7. {
  8. MessageBox(L"Could not make RC non-current");
  9. }
  10.  
  11. //Delete the rendering context
  12. if (::wglDeleteContext(m_hRC) == FALSE)
  13. {
  14. MessageBox(L"Could not delete RC");
  15. }
  16. //Delete the DC
  17. if (m_pDC)
  18. {
  19. delete m_pDC;
  20. }
  21. //Set it to NULL
  22. m_pDC = NULL;
  23. }
10、大小调整
在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。
  1. void CopenGLMFCView::OnSize(UINT nType, int cx, int cy)
  2. {
  3. CView::OnSize(nType, cx, cy);
  4.  
  5. // TODO: Add your message handler code here
  6. GLdouble aspect_ratio; // width/height ratio
  7.  
  8. if ( >= cx || >= cy)
  9. {
  10. return;
  11. }
  12. // select the full client area
  13. ::glViewport(, , cx, cy);
  14. // compute the aspect ratio
  15. // this will keep all dimension scales equal
  16. aspect_ratio = (GLdouble)cx / (GLdouble)cy;
  17. // select the projection matrix and clear it
  18. ::glMatrixMode(GL_PROJECTION);
  19. ::glLoadIdentity();
  20. // select the viewing volume
  21. ::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);
  22.  
  23. // switch back to the modelview matrix and clear it
  24. ::glMatrixMode(GL_MODELVIEW);
  25. ::glLoadIdentity();
  26. }

二、基于对话框

 
工程:openGLMFCDialog
1-3步骤同上
4、变量函数声明
在openGLMFCDialogDlg.h文件中,声明如上。
其余步骤同上,不同点在于,需要将OnDraw里面的写到
OnPaint函数里面,其中IsIconic()是判断是否为最小化,可以放到else里面即可。
得到结果
-----------------------------------------------------------------------------------------------------------------
原贴地址:https://www.cnblogs.com/pinking/p/6180225.html

基于MFC的OpenGL程序<转>的更多相关文章

  1. 1、基于MFC的OpenGL程序

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

  2. 基于MFC的Opengl实现动画

    对于了解MFC程序设计的来说,就太简单了.像我这种的,还是有必要记下来. OnCreate设置定时:SetTimer(1, 10, NULL);//设置#1定时器 key point void COp ...

  3. 基于MFC和opencv的FFT

    在网上折腾了一阵子,终于把这个程序写好了,程序是基于MFC的,图像显示的部分和获取图像的像素点是用到了opencv的一些函数,不过FFT算法没有用opencv的(呵呵,老师不让),网上的二维的FFT程 ...

  4. 基于MFC的实时可视化项目中视图刷新消息的严谨使用

    在实时可视项目中,视图的实时刷新显示对软件的体验感来说非常重要,当算法的效率达到实时,比如一秒40帧,如果实时显示帧率更不上,则体验感将大大折扣,让用户感觉你的算法并没有40帧,当然最关键的是解决显示 ...

  5. MFC下OpenGL入门(可以用)

    MFC下OpenGL入门 源文件 1, 建一工程文件,我这里命名为first,现在first工程里面我们没有添加任何东西,所有的东西都是MFC自动帮我们创建的. 2, 添加链接库.这一步很关键.打开菜 ...

  6. 基于MFC的socket编程(异步非阻塞通信)

       对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清, ...

  7. 用MFC实现OpenGL编程

    一.OpenGL简介 众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI公司)在他们的图形工作站上开发高质量图像的接口.但最近几年它成为一个非常优秀的开放式 ...

  8. VS2012下基于Glut 矩阵变换示例程序2:

    在VS2012下基于Glut 矩阵变换示例程序:中我们在绘制甜圈或者圆柱时使用矩阵对相应的坐标进行变换后自己绘制甜圈或者圆柱.我们也可以使用glLoadMatrixf.glLoadMatrixd载入变 ...

  9. 【OpenGL】详解第一个OpenGL程序

    写在前面 OpenGL能做的事情太多了!很多程序也看起来很复杂.很多人感觉OpenGL晦涩难懂,原因大多是被OpenGL里面各种语句搞得头大,一会gen一下,一会bind一下,一会又active一下. ...

随机推荐

  1. MySQL并发复制系列一:binlog组提交 (转载)

    http://blog.csdn.net/woqutechteam/article/details/51178803 MySQL  Binary log在MySQL 5.1版本后推出主要用于主备复制的 ...

  2. GO中DEFER的理解--DEFER执行的原理

    在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是return之后添加一个函数调用.因此,defer通常用来释放函数内 ...

  3. json--处理框架

    1.Android 中的Json解析工具fastjson .序列化.反序列化 2.Android Gson的使用总结 可以处理含有内部类的类,或包含集合内部类的类: 3.Android-JSONToo ...

  4. [UE4]AWP组合

    AWP狙击枪可以由主枪和镜头模型组合而成. 一.主枪 二.镜头组合

  5. RabbitMQ用户角色及权限控制(转)

    转载至:https://blog.csdn.net/awhip9/article/details/72123257 2017年05月15日 10:39:26 awhip9 阅读数:3538   ### ...

  6. xml布局解析报错的可能原因

    xml布局解析报如下的错11-15 16:55:21.425 17633-17633/com.hongfans.mobileconnect I/LogUtils_info: [CrashHandler ...

  7. MySQL操作mysqldump命令详解

    --all-databases , -A导出全部数据库. --all-tablespaces , -Y导出全部表空间. --no-tablespaces , -y不导出任何表空间信息. --add-d ...

  8. mysql视图 触发器 事物 函数 存储过程

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  9. raid1与raid5

    raid 1 就是两个磁盘同时读同时写, 当其中一个坏了 不影响使用, 直接更换一个,这样磁盘的容量只有一个盘的raid 5 就是 N-1个磁盘的容量,当其中任何一个磁盘坏,不影响使用,更换一个就可以 ...

  10. Android忘记锁屏密码如何进入手机?

    Android忘记锁屏密码如何进入手机?     1.关闭手机 2.进入recovery模式(即恢复模式,记住不是挖煤模式.进入恢复模式不同手机有不同方法,三星的话安主页键,关机键和音量+(或-键), ...