MFC下的OpenGL

序:因为要做个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;
        }
}

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

posted on 2011-04-02 23:25  影语者  阅读(603)  评论(0编辑  收藏  举报

导航