VS 2012环境下使用MFC进行OpenGL编程

VS 2012下使用MFC+OpenGL基本步骤

引子:以前一直惧怕MFC感觉它是一个非常复杂的东西,更不用说去用它来和OpenGL结合了,以前是一直羡慕别人用MFC创建一个窗口进行OpenGL绘图,当初有萌生自己创建一个MFC使用OpenGL的想法,但是由于各种原因一直没成功,最近我又研究了一下,有了一下这些拙见。之前研究一些东西时候,当初明白了,后来再去用就又要重新学习,一直觉得自己差一个做笔记的习惯,或者在电脑上建立一个文档,但是过一段时间就不知道丢哪里去了,所以我要养成写blog的习惯,把自己的拙见都放到这里,不管简单复杂吧,只为能给自己能有一些收获,当然如果机缘巧合有人来到这里看到我的blog并且获得了帮助,那应该是件非常快乐的事^_^

废话说多了,下面进入我第一篇blog的正题。

 

一、环境:

IDE:VS 2012

工具:OpenGL

二、详细步骤:

1.      创建MFC项目

a.      FILE||New||Project (这里||表示菜单的下一级),如下图:


b.      点击OK后,进入向导界面,其他都默认,只是把Application Type中的Project style修改为MFC standard。如下图,其他默认,OK确认创建。


c.      创建完成界面如下:

2.      导入OpenGL头文件和Lib文件

a.      在stdafx.h中添加语句 #include <GL/GLAUX.H>,如下图:

//OpenGL
#include <GL/GLAUX.H>



b.在项目中添加OpenGL的lib库文件,右键项目||Properties,如下图,之后左边以此展开Configuration Properties || Linker || Input || Additional Dependencies || <Edit>,之后弹出的窗口中输入:opengl32.lib,glu32.lib,glaux.lib三个库文件名,当然每个文件名之间应该是换行,不是逗号。如下图。

opengl32.lib
glu32.lib
glaux.lib





3.添加相应的几个函数,其实就是事件函数:OnCreate(窗口创建时调用),Ondestroy(窗口关闭调用),OnInitialUpdate(窗口被创建后运行一次的函数),OnSize(窗口改变时调用)等等一系列函数。

a在Class View(类视图)中查看类,如下图:



b.选中CMFC_OpenGLView类,之后按下Alt+Enter组合键或者右键该类选Properties,会看到这个类的属性栏如图,之后选事件选项卡,这里我们目前需要的事件函数只有上面提到的几个,分别对应VM_CREATE,VM_SIZE,VM_DESTROY,重复三次,将这三个函数添加到工程中。




c.  OnInitialUpdate的添加,这个是一个虚构函数,想知道具体的,可以Google一下,这里只是介绍一下如何创建,在类视图中右键CMFC_OpenGLView类 || Class Wizard,在虚函数标签中选择,该函数之后添加,如图:



4.添加OpenGL所需要的其他部分代码

a. 首先为COpenGL_MFCView类添加m_hRC、m_pDC成员变量

//file: COpenGL_MFCView.h
class COpenGL_MFCView : public CView
{
	//---add members
private:
	HGLRC m_hRC;
	CClientDC* m_pDC;
......
}

b. 接着修改相应的事件响应函数,主要涉及三个函数OnCreate(),OnSize(),OnDestroy(),代码如下:

//File: COpenGL_MFCView.cpp


int COpenGL_MFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here

	// 创建DC
	m_pDC = new CClientDC(this);
	ASSERT(m_pDC != NULL);
	// 选择像素格式
	if(!bSetDCPixelFormat()) return -1;
	// 创建渲染环境, 并使它成为当前渲染环境
	m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
	wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
	return 0;
}


void COpenGL_MFCView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	// 设置视口
	glViewport(0, 0, cx, cy);
	// 设置投影矩阵(透视投影)
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat)cx/(GLfloat)cy, 1.0, 1000.0);
	// 设置模型视图矩阵
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}


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

	// TODO: Add your message handler code here
	// 释放资源
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(m_hRC);
	delete m_pDC;
}

c. 添加上面调用的初始化OpenGl场景的函数,这里涉及为类添加函数的方法,大致是,在类视图中右键需要添加函数的类 || Add || Add Function ,会弹出添加向导,代码和图如下所示:


//File: COpenGL_MFCView.cpp
// 为一个特定的设备环境选择像素格式
bool COpenGL_MFCView::bSetDCPixelFormat(void)
{
	// 设置像素格式
	static PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR), // 结构的大小
		1, // 结构的版本
		PFD_DRAW_TO_WINDOW | // 在窗口(而不是位图)中绘图
		PFD_SUPPORT_OPENGL | // 支持在窗口中进行OpenGL调用
		PFD_DOUBLEBUFFER, // 双缓冲模式
		PFD_TYPE_RGBA, // RGBA颜色模式
		32, // 需要32位颜色
		0, 0, 0, 0, 0, 0, // 不用于选择模式
		0, 0, // 不用于选择模式
		0, 0, 0, 0, 0, // 不用于选择模式
		16, // 深度缓冲区的大小
		0, // 在此不使用
		0, // 在此不使用
		0, // 在此不使用
		0, // 在此不使用
		0, 0, 0 // 在此不使用
	};
	// 选择一种与pfd所描述的最匹配的像素格式
	int nPixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
	if(0 == nPixelFormat) return false;
	// 为设备环境设置像素格式
	return SetPixelFormat(m_pDC->GetSafeHdc(), nPixelFormat, &pfd);
}


d. 使用上一步中的方法添加另一个OpenGL绘制场景的函数,这里的是绘制一个简单的坐标系,其实这里的代码就是和通常的OpenGL代码中的display一样了,代码如下:

//File: COpenGL_MFCView.cpp
//绘制坐标轴
void COpenGL_MFCView::drawUnitAxes(void)
{
	const GLfloat max = (GLfloat)1.0f;//INT_MAX;
	// 实线部分
	glBegin(GL_LINES);
	// x
	glColor3f(1.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(max, 0.0, 0.0);
	// y
	glColor3f(0.0, 1.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, max, 0.0);
	// z
	glColor3f(0.0, 0.0, 1.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, max);
	glEnd();
	// 虚线部分
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(3, 0xAAAA);
	glBegin(GL_LINES);
	// x
	glColor3f(1.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(-max, 0.0, 0.0);
	// y
	glColor3f(0.0, 1.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, -max, 0.0);
	// z
	glColor3f(0.0, 0.0, 1.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, -max);
	glEnd();
	glDisable(GL_LINE_STIPPLE);
}


e. 最后再OnDraw()函数中调用上面函数即可,修改OnDraw函数如下:

//File: COpenGL_MFCView.cpp
// COpenGL_MFCView drawing

void COpenGL_MFCView::OnDraw(CDC* /*pDC*/)
{
	COpenGL_MFCDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: add draw code for native data here

	// 清除颜色
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// 绘制场景
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	{
		// 绘制坐标系
		drawUnitAxes();
	}
	glPopMatrix();
	// 交换缓冲区
	SwapBuffers(wglGetCurrentDC());
}

f. 修改前面添加的OnInitialUpdate函数

第一次写blog有点紧张,差点忘记了在之前添加的OnInitialUpdate函数 ^_^其实就是清理一个OpenGL的初始场景,OpenGL的初始工作都可以在这个函数做,这个函数只在窗口被创建的时候仅仅调用一次。代码如下

//File: COpenGL_MFCView.cpp
void COpenGL_MFCView::OnInitialUpdate()
{
	CView::OnInitialUpdate();
	// 设置背景色
	glClearColor(0.0, 0.0, 0.0, 1.0);
	// TODO: Add your specialized code here and/or call the base class
}



三 、 至此,基本流程已经全部完成,现在可以编译运行一下看看效果了^_^

效果图如下:



第一篇blog完成~~~请多多指教。



本教程工程下载地址:http://download.csdn.net/detail/bbppbb/7235611

阅读更多

没有更多推荐了,返回首页