序:因为要做个2d地图编辑器,决定采用MFC,但是GDI不是很熟,google下终于完成基本MFC下的OpenGL
1.首先建个MFC单文档
2.加入外部库:opengl32.lib glu32.lib 在XXView.cpp加入头文件 gl.h, glu.h
3.在XXView.h加入如下代码:
protected: CDC *m_pDC; HGLRC m_hRC; protected: BOOL InitOpenGL(); # 初始化opengl BOOL SetPixelFormat(); # 设置像素格式 void RenderScene(); # 绘制
4.首先重载OnCreate消息
int CXXView::OnCreate(LPCREATESTRUCT lpCreateStrcut) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // 初始化OpenGL InitOpenGL(); return 0; }
5.现在完成初始化OpenGL的代码
BOOL CXXView::InitializeOpenGL() { // 创建设备上下文 m_pDC = new CClientDC(this); if (m_pDC == NULL) { MessageBox("错误: 无法创建设备上下文"); return FALSE; } // 设置像素格式 if (!SetPixelFormat()) return FALSE; // 创建绘制环境 m_hRC = wglCreateContext(m_pDC->GetSafeHdc()); if (m_hRC == NULL) { MessageBox("错误: 无法创建绘制环境"); return FALSE; } if (wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE) { MessageBox("错误: 无法作为当前RC"); return FALSE; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); return TRUE; }
6. 如上5中提到的设置像素格式
BOOL CXXView::SetPixelFormat() { //定义窗口的像素格式 PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER|PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0, 0, 0, 0,0,0,0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; int m_nPixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd); if (m_nPixelFormat == 0) { return FALSE; } if (SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE) { return FALSE; } return TRUE; }
7.当然是视图,并且包括窗口改变时重新设置视图
void CXXView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 if ( 0 >= cx || 0 >= cy) return; glViewport(0, 0, cx, cy); GLdouble aspect_ratio = (GLdouble)cx / (GLdouble)cy; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, aspect_ratio, 0.01f, 200.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
8.既然基本都完成,我们在哪里绘制我们图像呢?--》OnDraw
void CXXView::OnDraw(CDC* pDC) { CMfcOpenglDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 我们绘制图像的代码就放在这里 RenderScene(); glFinish(); SwapBuffers(pDC->GetSafeHdc()); }
9.开始绘制图像,这里就绘制一个方块
void CXXView::RenderScene( GLvoid ) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -6.0f); glBegin(GL_TRIANGLES); glBegin(GL_QUADS); // 绘制正方形 glColor3f(255.0f,0.0f,0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); // 左上 glColor3f(0.0f,255.0f,0.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // 右上 glColor3f(0.0f,0.0f,255.0f); lVertex3f( 1.0f,-1.0f, 0.0f); // 左下 glColor3f(255.255f,255.0f,255.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // 右下 glEnd(); }
10.退出程序的时候记得要销毁创建的DC, RC
void CXXView::OnDestroy() { CView::OnDestroy(); // TODO: 在此处添加消息处理程序代码 if(wglGetCurrentContext()!=NULL) wglMakeCurrent(0, 0); if(m_hRC != NULL) wglDeleteContext(m_hRC); if (m_pDC) { delete m_pDC; m_pDC = NULL; } }
如果没有问题,你将看到如下的结果: