MFC下的OpenGL

序:因为要做个2d地图编辑器,决定采用MFC,但是GDI不是很熟,google下终于完成基本MFC下的OpenGL

1.首先建个MFC单文档

2.加入外部库:opengl32.lib glu32.lib    在XXView.cpp加入头文件 gl.h, glu.h

3.在XXView.h加入如下代码:  

1 protected:
2   CDC    *m_pDC;
3   HGLRC  m_hRC;
4 protected:
5   BOOL InitOpenGL();             # 初始化opengl
6   BOOL SetPixelFormat();       # 设置像素格式
7   void   RenderScene();          # 绘制

 

4.首先重载OnCreate消息

01 int CXXView::OnCreate(LPCREATESTRUCT lpCreateStrcut)
02 {
03   if (CView::OnCreate(lpCreateStruct) == -1)
04     return -1;
05   
06   // 初始化OpenGL
07   InitOpenGL();
08    
09   return 0;
10 }

 

5.现在完成初始化OpenGL的代码

01 BOOL CXXView::InitializeOpenGL()
02 {
03         // 创建设备上下文
04     m_pDC = new CClientDC(this);
05     if (m_pDC == NULL)
06     {
07         MessageBox("错误: 无法创建设备上下文");
08         return FALSE;
09     }
10   
11         // 设置像素格式
12     if (!SetPixelFormat())
13         return FALSE;
14   
15         // 创建绘制环境
16     m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
17     if (m_hRC == NULL)
18     {
19         MessageBox("错误: 无法创建绘制环境");
20         return FALSE;
21     }
22   
23     if (wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
24     {
25         MessageBox("错误: 无法作为当前RC");
26         return FALSE;
27     }
28   
29     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
30     glClearDepth(1.0f);
31     glEnable(GL_DEPTH_TEST);
32   
33     return TRUE;
34 }

 

6. 如上5中提到的设置像素格式

01 BOOL CXXView::SetPixelFormat()
02 {
03     //定义窗口的像素格式
04     PIXELFORMATDESCRIPTOR pfd=
05     {
06         sizeof(PIXELFORMATDESCRIPTOR),
07         1,
08         PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
09         PFD_DOUBLEBUFFER|PFD_TYPE_RGBA,
10         24,
11         0,0,0,0,0,0,
12         0,
13         0,
14         0,
15         0,0,0,0,
16         16,
17         0,
18         0,
19         PFD_MAIN_PLANE,
20         0,
21         0,0,0
22     };
23   
24     int m_nPixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
25     if (m_nPixelFormat == 0)
26     {
27         return FALSE;
28     }
29   
30     if (SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
31     {
32         return FALSE;
33     }
34   
35     return TRUE;
36 }

 

7.当然是视图,并且包括窗口改变时重新设置视图

01 void CXXView::OnSize(UINT nType, int cx, int cy)
02 {
03     CView::OnSize(nType, cx, cy);
04   
05     // TODO: 在此处添加消息处理程序代码
06     if ( 0 >= cx || 0 >= cy)
07         return;
08   
09     glViewport(0, 0, cx, cy);
10     GLdouble aspect_ratio = (GLdouble)cx / (GLdouble)cy;
11       
12     glMatrixMode(GL_PROJECTION);
13     glLoadIdentity();
14     gluPerspective(45.0f, aspect_ratio, 0.01f, 200.0f);
15     glMatrixMode(GL_MODELVIEW);
16     glLoadIdentity();
17 }

 

8.既然基本都完成,我们在哪里绘制我们图像呢?--》OnDraw

01 void CXXView::OnDraw(CDC* pDC)
02 {
03     CMfcOpenglDoc* pDoc = GetDocument();
04     ASSERT_VALID(pDoc);
05     if (!pDoc)
06         return;
07   
08     // TODO: 在此处为本机数据添加绘制代码
09     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
10     // 我们绘制图像的代码就放在这里
11         RenderScene();
12     glFinish();
13     SwapBuffers(pDC->GetSafeHdc());
14 }

 

9.开始绘制图像,这里就绘制一个方块

01 void CXXView::RenderScene( GLvoid )
02 {
03     glLoadIdentity();  
04     glTranslatef(0.0f, 0.0f, -6.0f);
05     glBegin(GL_TRIANGLES);                    
06     glBegin(GL_QUADS);                            //  绘制正方形
07        glColor3f(255.0f,0.0f,0.0f);
08        glVertex3f(-1.0f, 1.0f, 0.0f);                    // 左上
09        glColor3f(0.0f,255.0f,0.0f);
10        glVertex3f( 1.0f, 1.0f, 0.0f);                    // 右上
11        glColor3f(0.0f,0.0f,255.0f);
12        lVertex3f( 1.0f,-1.0f, 0.0f);                      // 左下
13        glColor3f(255.255f,255.0f,255.0f);
14        glVertex3f(-1.0f,-1.0f, 0.0f);                    // 右下
15     glEnd();                              
16 }

 

10.退出程序的时候记得要销毁创建的DC, RC

01 void CXXView::OnDestroy()
02 {
03     CView::OnDestroy();
04   
05     // TODO: 在此处添加消息处理程序代码
06     if(wglGetCurrentContext()!=NULL)
07         wglMakeCurrent(0, 0);
08     if(m_hRC != NULL)
09         wglDeleteContext(m_hRC);
10     if (m_pDC)
11         {
12         delete m_pDC;
13             m_pDC = NULL;
14         }
15 }

 

如果没有问题,你将看到如下的结果:

分类: MFC, OpenGL