MFC单文档程序中搭建OpenGL框架

来源:互联网 发布:安卓连接mysql 编辑:程序博客网 时间:2024/06/05 23:13

一、简介

Windows GDI是通过设备句柄(Device Context(设备描述表)以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context(着色描述表),以下简称"RC")。每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使用当前绘制环境(RC)。但是RC并不能直接完成绘图,只能与特定的DC联系起来,从而完成具体的绘图工作。一旦在一个线程中指定了一个当前RC,在此线程中其后所有的OpenGL命令都使用相同的当前RC。虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。下面我将首先产生一个OpenGL RC并使之成为当前RC。这将分为三个步骤:

1、设置窗口像素格式;

2、产生RC;

3、设置为当前RC。

用一个图表示如下所示,图中介绍了需要在各个函数中设置的信息:


二、搭建MFC中的OpenGL基本框架

本文以一个单文档程序为例。新建一个单文档名字为VCOpenGL2 其他的默认。

1、添加链接库。

打开菜单栏下的项目->属性->配置属性->链接器->输入->附加依赖项里加入OpenGL32.lib GLu32.lib GLaux.lib,如图

如果不用这种方法添加链接库的话,可以写上下列代码,也能达到同样的效果:

[cpp] view plaincopyprint?
  1. #pragma comment( lib, "opengl32.lib" )      
  2. #pragma comment( lib, "glu32.lib" )        
  3. #pragma comment( lib, "glut32.lib" )   
  4. #pragma comment( lib, "glaux.lib" )  
[cpp] view plain copy
 print?
  1. #pragma comment( lib, "opengl32.lib" )     
  2. #pragma comment( lib, "glu32.lib" )       
  3. #pragma comment( lib, "glut32.lib" )  
  4. #pragma comment( lib, "glaux.lib" )  

2、 包含头文件。

在stdafx里面添加opengl的头文件(当然也可以在其他文件中添加,比如绘图一般都是在视图中的,可以在xxxView.cpp文件中包含头文件)。如下代码所示:

#include <GL\glaux.h>#include <GL\glut.h>

有几点说明:

2.1、包含glut.h的同时就把gl.h和glu.h都包括了。因为打开glut.h你可以看到如下图所示的,已经包含了gl.h和glu.h。

2.2、关于这OpenGL中的这几个库的介绍,看一看我的另一篇文章,地址如下:

http://blog.csdn.net/zhangkaihang/article/details/7459629

3、设置窗口显示风格。

窗口创建之前我们必须设置窗口风格包含

WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域),

从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。代码如下:

CMyVIew中的PreCreateWindow中添加
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

4、设置窗口像素格式

首先向VCOpenGL2View类中添加几个保护的成员变量和公共的成员函数。如下:

[cpp] view plaincopyprint?
  1. HGLRC m_hRC;    //Rendering Context着色描述表   
  2. CClientDC* m_pDC;        //Device Context设备描述表   
  3. BOOL InitializeOpenGL();    //初始化 OpenGL   
  4. BOOL SetupPixelFormat();    //设置像素格式   
  5. void RenderScene();         //绘制场景  
[cpp] view plain copy
 print?
  1. HGLRC m_hRC;    //Rendering Context着色描述表  
  2. CClientDC* m_pDC;        //Device Context设备描述表  
  3. BOOL InitializeOpenGL();    //初始化 OpenGL  
  4. BOOL SetupPixelFormat();    //设置像素格式  
  5. void RenderScene();         //绘制场景  

 别忘了在VCOpenGL2View的构造函数中设置 m_hRC = NULL; m_pDC = NULL;

产生一个RC的第一步是定义窗口的像素格式。像素格式决定窗口着所显示的图形在内存中是如何表示的。由像素格式控制的参数包括:颜色深度、缓冲模式和所支持的绘画接口。在下面将在SetupPixelFormat()函数中对这些参数的设置。代码如下:

[cpp] view plaincopyprint?
  1. BOOL CVCOpenGL2View::SetupPixelFormat(void)  
  2. {  
  3.  static PIXELFORMATDESCRIPTOR pfd =   
  4.                             {  
  5.                                 sizeof(PIXELFORMATDESCRIPTOR),  // pfd结构的大小    
  6.                                 1,                              // 版本号    
  7.                                 PFD_DRAW_TO_WINDOW |            // 支持在窗口中绘图    
  8.                                 PFD_SUPPORT_OPENGL |            // 支持 OpenGL    
  9.                                 PFD_DOUBLEBUFFER,               // 双缓存模式    
  10.                                 PFD_TYPE_RGBA,                  // RGBA 颜色模式    
  11.                                 24,                             // 24 位颜色深度    
  12.                                 0, 0, 0, 0, 0, 0,               // 忽略颜色位    
  13.                                 0,                              // 没有非透明度缓存    
  14.                                 0,                              // 忽略移位位    
  15.                                 0,                              // 无累计缓存    
  16.                                 0, 0, 0, 0,                     // 忽略累计位    
  17.                                 32,                             // 32 位深度缓存        
  18.                                 0,                              // 无模板缓存    
  19.                                 0,                              // 无辅助缓存    
  20.                                 PFD_MAIN_PLANE,                 // 主层    
  21.                                 0,                              // 保留    
  22.                                 0, 0, 0                         // 忽略层,可见性和损毁掩模   
  23.   
  24.                             };  
  25.     int pixelFormat;  
  26.     // 为设备描述表得到最匹配的像素格式    
  27.     if((pixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0)  
  28.     {  
  29.         MessageBox( _T("ChoosePixelFormat failed") );  
  30.         return FALSE;  
  31.     }  
  32.     // 设置最匹配的像素格式为当前的像素格式    
  33.     if(SetPixelFormat(m_pDC->GetSafeHdc(), pixelFormat, &pfd) == FALSE)  
  34.     {  
  35.         MessageBox( _T("SetPixelFormat failed") );  
  36.         return FALSE;  
  37.     }  
  38.     return TRUE;  
  39. }  
[cpp] view plain copy
 print?
  1. BOOL CVCOpenGL2View::SetupPixelFormat(void)  
  2. {  
  3.  static PIXELFORMATDESCRIPTOR pfd =   
  4.                             {  
  5.                                 sizeof(PIXELFORMATDESCRIPTOR),  // pfd结构的大小   
  6.                                 1,                              // 版本号   
  7.                                 PFD_DRAW_TO_WINDOW |            // 支持在窗口中绘图   
  8.                                 PFD_SUPPORT_OPENGL |            // 支持 OpenGL   
  9.                                 PFD_DOUBLEBUFFER,               // 双缓存模式   
  10.                                 PFD_TYPE_RGBA,                  // RGBA 颜色模式   
  11.                                 24,                             // 24 位颜色深度   
  12.                                 0, 0, 0, 0, 0, 0,               // 忽略颜色位   
  13.                                 0,                              // 没有非透明度缓存   
  14.                                 0,                              // 忽略移位位   
  15.                                 0,                              // 无累计缓存   
  16.                                 0, 0, 0, 0,                     // 忽略累计位   
  17.                                 32,                             // 32 位深度缓存       
  18.                                 0,                              // 无模板缓存   
  19.                                 0,                              // 无辅助缓存   
  20.                                 PFD_MAIN_PLANE,                 // 主层   
  21.                                 0,                              // 保留   
  22.                                 0, 0, 0                         // 忽略层,可见性和损毁掩模   
  23.   
  24.                             };  
  25.     int pixelFormat;  
  26.     // 为设备描述表得到最匹配的像素格式   
  27.     if((pixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0)  
  28.     {  
  29.         MessageBox( _T("ChoosePixelFormat failed") );  
  30.         return FALSE;  
  31.     }  
  32.     // 设置最匹配的像素格式为当前的像素格式   
  33.     if(SetPixelFormat(m_pDC->GetSafeHdc(), pixelFormat, &pfd) == FALSE)  
  34.     {  
  35.         MessageBox( _T("SetPixelFormat failed") );  
  36.         return FALSE;  
  37.     }  
  38.     return TRUE;  
  39. }  


5、产生RC,设置为当前RC。  

现在像素格式已经设定,我们下一步工作是产生绘制环境(RC)并使之成为当前绘制环境,即编写InitializeOpenGL()函数。代码如下:

[cpp] view plaincopyprint?
  1. BOOL CVCOpenGL2View::InitializeOpenGL(void)  
  2. {  
  3.     PIXELFORMATDESCRIPTOR pfd;  
  4.     int n;  
  5.     m_pDC=new CClientDC(this);  
  6.     ASSERT(m_pDC != NULL);  
  7.     // 设置当前的绘图像素格式   
  8.     if(!SetupPixelFormat())  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.   
  13.     n=::GetPixelFormat(m_pDC->GetSafeHdc());  
  14.     ::DescribePixelFormat(m_pDC->GetSafeHdc(), n,sizeof(pfd),&pfd);  
  15.      // 创建绘图描述表   
  16.     m_hRC=wglCreateContext(m_pDC->GetSafeHdc());  
  17.     if(m_hRC == NULL)  
  18.     {  
  19.         return FALSE;  
  20.     }  
  21.     // 使绘图描述表为当前调用现程的当前绘图描述表   
  22.     if( wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC) == FALSE)  
  23.     {  
  24.         return FALSE;  
  25.     }  
  26.     glClearDepth(1.0f);  
  27.     glEnable(GL_DEPTH_TEST);  
  28.     return TRUE;  
  29. }  
[cpp] view plain copy
 print?
  1. BOOL CVCOpenGL2View::InitializeOpenGL(void)  
  2. {  
  3.     PIXELFORMATDESCRIPTOR pfd;  
  4.     int n;  
  5.     m_pDC=new CClientDC(this);  
  6.     ASSERT(m_pDC != NULL);  
  7.     // 设置当前的绘图像素格式  
  8.     if(!SetupPixelFormat())  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.   
  13.     n=::GetPixelFormat(m_pDC->GetSafeHdc());  
  14.     ::DescribePixelFormat(m_pDC->GetSafeHdc(), n,sizeof(pfd),&pfd);  
  15.      // 创建绘图描述表  
  16.     m_hRC=wglCreateContext(m_pDC->GetSafeHdc());  
  17.     if(m_hRC == NULL)  
  18.     {  
  19.         return FALSE;  
  20.     }  
  21.     // 使绘图描述表为当前调用现程的当前绘图描述表  
  22.     if( wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC) == FALSE)  
  23.     {  
  24.         return FALSE;  
  25.     }  
  26.     glClearDepth(1.0f);  
  27.     glEnable(GL_DEPTH_TEST);  
  28.     return TRUE;  
  29. }  

别忘了再OnCreate()函数中调用 InitializeOpenGL()函数。如下所示:


[cpp] view plaincopyprint?
  1. int CVCOpenGL2View::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  2. {  
  3.     if (CView::OnCreate(lpCreateStruct) == -1)  
  4.         return -1;  
  5.   
  6.     // TODO:  在此添加您专用的创建代码   
  7.     if ( InitializeOpenGL())  
  8.     {  
  9.         return 0;  
  10.     }  
  11.   
  12.     return 0;  
  13. }  
[cpp] view plain copy
 print?
  1. int CVCOpenGL2View::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  2. {  
  3.     if (CView::OnCreate(lpCreateStruct) == -1)  
  4.         return -1;  
  5.   
  6.     // TODO:  在此添加您专用的创建代码  
  7.     if ( InitializeOpenGL())  
  8.     {  
  9.         return 0;  
  10.     }  
  11.   
  12.     return 0;  
  13. }  


6、设置视口

在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。代码如下:

[cpp] view plaincopyprint?
  1. void CVCOpenGL2View::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CView::OnSize(nType, cx, cy);  
  4.   
  5.     // TODO: 在此处添加消息处理程序代码   
  6.     m_wide = cx;    //m_wide为在CVCOpenGL2View类中添加的表示视口宽度的成员变量   
  7.     m_heigth = cy;  //m_height为在CVCOpenGL2View类中添加的表示视口高度的成员变量   
  8.     //避免除数为0   
  9.     if(m_heigth==0)  
  10.     {  
  11.         m_heigth=1;  
  12.     }  
  13.     //设置视口与窗口的大小   
  14.     glViewport(0,0,m_wide,m_heigth);  
  15. }  
[cpp] view plain copy
 print?
  1. void CVCOpenGL2View::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CView::OnSize(nType, cx, cy);  
  4.   
  5.     // TODO: 在此处添加消息处理程序代码  
  6.     m_wide = cx;    //m_wide为在CVCOpenGL2View类中添加的表示视口宽度的成员变量  
  7.     m_heigth = cy;  //m_height为在CVCOpenGL2View类中添加的表示视口高度的成员变量  
  8.     //避免除数为0  
  9.     if(m_heigth==0)  
  10.     {  
  11.         m_heigth=1;  
  12.     }  
  13.     //设置视口与窗口的大小  
  14.     glViewport(0,0,m_wide,m_heigth);  
  15. }  

7、绘制场景(用OpenGL绘图相关的代码都在这里哦!!)

本文以一个三维正方体为例,代码如下:

[cpp] view plaincopyprint?
  1. void CVCOpenGL2View::RenderScene(void)  
  2. {  
  3.     //设置清屏颜色为黑色   
  4.     glClearColor(0.0f,0.0f,0.0f,0.0f);  
  5.     //清除颜色缓冲区和深度缓冲区   
  6.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  7. /* 
  8.     //建立正交变换下的剪切体 
  9.     if(w<h) 
  10.     { 
  11.         glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,-nRange,nRange); 
  12.     } 
  13.     else 
  14.     { 
  15.         glOrtho(-nRange*w/h,nRange*w/h,-nRange,nRange,-nRange,nRange); 
  16.     } 
  17. */  
  18.     //透视投影变换   
  19.     glMatrixMode(GL_PROJECTION);  
  20.     glLoadIdentity();  
  21.     gluPerspective(m_tFovy, (double)m_wide/(double)m_heigth,m_zNear,m_zFar);  
  22.     //视角变换   
  23.     glMatrixMode(GL_MODELVIEW);  
  24.     glLoadIdentity();  
  25.     gluLookAt(10,10,10,0,0,0,0,1,0);  
  26.     //矩阵堆栈函数,和glPopMatrix()相对应   
  27.     glPushMatrix();  
  28.   
  29.     glBegin( GL_LINES );  
  30.     glColor3d(1.0, 0.0, 0.0);   // X轴 红色   
  31.     glVertex3d(0.0, 0.0, 0.0);   
  32.     glVertex3d(2.0, 0.0, 0.0);  
  33.     glColor3d(0.0, 1.0, 0.0);   // Y轴 绿色   
  34.     glVertex3d(0.0, 0.0, 0.0);  
  35.     glVertex3d(0.0, 2.0, 0.0);  
  36.     glColor3d(0.0, 0.0, 1.0);   // Z轴 蓝色   
  37.     glVertex3d(0.0, 0.0, 0.0);   
  38.     glVertex3d(0.0, 0.0, 2.0);  
  39.     glEnd();  
  40.   
  41.     glColor3f(1.0, 1.0, 1.0);  
  42.       glutWireCube(0.5);  
  43.   
  44.     glPopMatrix();  
  45.     glFinish();  
  46.     SwapBuffers(wglGetCurrentDC());  
  47. }  
[cpp] view plain copy
 print?
  1. void CVCOpenGL2View::RenderScene(void)  
  2. {  
  3.     //设置清屏颜色为黑色  
  4.     glClearColor(0.0f,0.0f,0.0f,0.0f);  
  5.     //清除颜色缓冲区和深度缓冲区  
  6.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  7. /* 
  8.     //建立正交变换下的剪切体 
  9.     if(w<h) 
  10.     { 
  11.         glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,-nRange,nRange); 
  12.     } 
  13.     else 
  14.     { 
  15.         glOrtho(-nRange*w/h,nRange*w/h,-nRange,nRange,-nRange,nRange); 
  16.     } 
  17. */  
  18.     //透视投影变换  
  19.     glMatrixMode(GL_PROJECTION);  
  20.     glLoadIdentity();  
  21.     gluPerspective(m_tFovy, (double)m_wide/(double)m_heigth,m_zNear,m_zFar);  
  22.     //视角变换  
  23.     glMatrixMode(GL_MODELVIEW);  
  24.     glLoadIdentity();  
  25.     gluLookAt(10,10,10,0,0,0,0,1,0);  
  26.     //矩阵堆栈函数,和glPopMatrix()相对应  
  27.     glPushMatrix();  
  28.   
  29.     glBegin( GL_LINES );  
  30.     glColor3d(1.0, 0.0, 0.0);   // X轴 红色  
  31.     glVertex3d(0.0, 0.0, 0.0);   
  32.     glVertex3d(2.0, 0.0, 0.0);  
  33.     glColor3d(0.0, 1.0, 0.0);   // Y轴 绿色  
  34.     glVertex3d(0.0, 0.0, 0.0);  
  35.     glVertex3d(0.0, 2.0, 0.0);  
  36.     glColor3d(0.0, 0.0, 1.0);   // Z轴 蓝色  
  37.     glVertex3d(0.0, 0.0, 0.0);   
  38.     glVertex3d(0.0, 0.0, 2.0);  
  39.     glEnd();  
  40.   
  41.     glColor3f(1.0, 1.0, 1.0);  
  42.       glutWireCube(0.5);  
  43.   
  44.     glPopMatrix();  
  45.     glFinish();  
  46.     SwapBuffers(wglGetCurrentDC());  
  47. }  
别忘了,在OnDraw()函数中调用哦!!!!!如下:

[cpp] view plaincopyprint?
  1. void CVCOpenGL2View::OnDraw(CDC* /*pDC*/)  
  2. {  
  3.     CVCOpenGL2Doc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.     // TODO: 在此处为本机数据添加绘制代码   
  8.   
  9.     RenderScene();  
  10. }  
[cpp] view plain copy
 print?
  1. void CVCOpenGL2View::OnDraw(CDC* /*pDC*/)  
  2. {  
  3.     CVCOpenGL2Doc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.     // TODO: 在此处为本机数据添加绘制代码  
  8.   
  9.     RenderScene();  
  10. }  

8、一些收尾工作。

8.1 为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd()里做一些操作,避免windows自己的窗口刷新闪烁。OnEraseBkgnd()函数需要重写。如下:

[cpp] view plaincopyprint?
  1. BOOL CVCOpenGL2View::OnEraseBkgnd(CDC* pDC)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值   
  4.     return TRUE;  
  5.   
  6. //  return CView::OnEraseBkgnd(pDC);   
  7. }  
[cpp] view plain copy
 print?
  1. BOOL CVCOpenGL2View::OnEraseBkgnd(CDC* pDC)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值  
  4.     return TRUE;  
  5.   
  6. //  return CView::OnEraseBkgnd(pDC);  
  7. }  
8.2 为了避免内存泄露,OnDestroy()函数中加一些代码,如下:

[cpp] view plaincopyprint?
  1. void CVCOpenGL2View::OnDestroy()  
  2. {  
  3.     CView::OnDestroy();  
  4.   
  5.     // TODO: 在此处添加消息处理程序代码   
  6.   
  7.     m_hRC = ::wglGetCurrentContext();  
  8.       if(::wglMakeCurrent (0,0) == FALSE)  
  9.       {  
  10.            MessageBox(_T("Could not make RC non-current"));  
  11.       }  
  12.   
  13.     if(m_hRC)  
  14.     {  
  15.         if(::wglDeleteContext(m_hRC)==FALSE)  
  16.         {  
  17.             MessageBox(_T("Could not delete RC"));  
  18.         }  
  19.     }  
  20.   
  21.     if(m_pDC)  
  22.     {  
  23.         delete m_pDC;  
  24.     }  
  25.     m_pDC = NULL;  
  26. }  
[cpp] view plain copy
 print?
  1. void CVCOpenGL2View::OnDestroy()  
  2. {  
  3.     CView::OnDestroy();  
  4.   
  5.     // TODO: 在此处添加消息处理程序代码  
  6.   
  7.     m_hRC = ::wglGetCurrentContext();  
  8.       if(::wglMakeCurrent (0,0) == FALSE)  
  9.       {  
  10.            MessageBox(_T("Could not make RC non-current"));  
  11.       }  
  12.   
  13.     if(m_hRC)  
  14.     {  
  15.         if(::wglDeleteContext(m_hRC)==FALSE)  
  16.         {  
  17.             MessageBox(_T("Could not delete RC"));  
  18.         }  
  19.     }  
  20.   
  21.     if(m_pDC)  
  22.     {  
  23.         delete m_pDC;  
  24.     }  
  25.     m_pDC = NULL;  
  26. }  

至此一个单文档的框架就弄好了。下面贴出所画的立方体,如下图:




 

在VC6.0中

基于单文档的OpenGL图形程序的基本框架
1、 理论基础
a、在单文档的创建过程中,设置好显示的像素格式,并按OpenGL得要求设置窗口的属性和风格
b、在窗口的绘制过程中,首先获得Windows设备描述表DC,然后将其与事先设置好的OpenGL绘制

表述表RC联系起来;
c、调用OpenGL命令进行图形绘制;
d、退出OpenGL图形窗口时,释放OpenGL绘制描述表RC和Windows设备描述表DC。

2、编程步骤
a、启动vc6.0,选择NEW菜单,在NEW对话框中选择Project标签,选择"MFC AppWizard(exe)",

新建一个基于对话框的工程。名称为MySDOpenGL。
b、利用MFC ClassWizard为CMySDOpenGLView类添加消息WM_CREATE、WM_DESTROY、WM_SIZE、

WM_TIMER得响应函数.
c.在CMySDOpenGLView.h中加入源代码.
////////////////////////////////////////////////
//添加成员函数与成员变量
BOOL InitializeOpenGL(CDC *pDC);
void SetLogicalPalette(void);
BOOL SetupPixelFormat(void);
BOOL RenderScene();

HGLRC m_hRC; //OpenGL绘制描述表
HPALETTE m_hPalette; //OpenGL调色板
CDC* m_pDC; //OpenGL设备描述表
///////////////////////////////////////////////////
d、在文件CMySDOpenGLView.cpp中加入如下代码
BOOL CMySDOpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
////////////////////////////////////////////////////
//设置窗口类型
cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
/////////////////////////////////////////////////////
return CView::PreCreateWindow(cs);
}


void CMySDOpenGLView::OnDraw(CDC* pDC)
{
CMySDOpenGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
////////////////////////////////////////////////////
RenderScene(); //渲染场景
///////////////////////////////////////////////////
}


int CMySDOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
 
// TODO: Add your specialized creation code here
////////////////////////////////////////////////////////
//初始化调色板和渲染上下文、定时器
m_pDC = new CClientDC(this);
SetTimer(1,20,NULL);
InitializeOpenGL(m_pDC);
///////////////////////////////////////////////////////
return 0;
}

void CMySDOpenGLView::OnDestroy() 
{
CView::OnDestroy();

// TODO: Add your message handler code here
///////////////////////////////////////////////////////
//删除调色板和渲染上下文
::wglMakeCurrent(0,0);
::wglDeleteContext(m_hRC);
if(m_hPalette)
DeleteObject(m_hPalette);
if(m_pDC)
delete m_pDC;
KillTimer(1);
 
}


void CMySDOpenGLView::OnSize(UINT nType, int cx, int cy) 
{
 CView::OnSize(nType, cx, cy);
 
// TODO: Add your message handler code here
//////////////////////////////////////////////////////
//添加窗口缩放时的变换函数
glViewport(0,0,cx,cy);
//////////////////////////////////////////////////////

}



void CMySDOpenGLView::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
///////////////////////////////////////////////////////////
//添加定时器响应函数和场景更新函数
Invalidate(FALSE);
///////////////////////////////////////////////////////////
CView::OnTimer(nIDEvent);
}

//////////////////////////////////////////////////////////
//场景绘制与渲染

///////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::RenderScene()
{
// glClearColor(1.0,0.0,0.0,1.0);
// glClear(GL_COLOR_BUFFER_BIT);



 ::SwapBuffers(m_pDC->GetSafeHdc()); //交换缓冲区
 return TRUE;

}


/////////////////////////////////////////////////////////////
//设置像素格式
////////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::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, //忽略累加位
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 CMySDOpenGLView::SetLogicalPalette()
{
struct 
{
WORD Vertion;
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);
}

////////////////////////////////////////////////////////
// 初始化openGL场景
////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::InitializeOpenGL(CDC *pDC)
{
 m_pDC = pDC;
 SetupPixelFormat();
 //生成绘制描述表
 m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
//设置当前绘制描述表
 ::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
 return TRUE;

}



e、在文件StdAfx.h中加入如下源代码。

//////////////////////////////////////////////////////////////////////////
//包含有关OpenGL 函数的头文件
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>  
 #include <GL/glut.h>

//////////////////////////////////////////////////////////////////////////

最后运行编译。
0 0