序:因为要做个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;
}
}
如果没有问题,你将看到如下的结果: