利用VC编写MFC OpenGL向导

MFC OpenGL用户向导原程序工程,此次修正了没有中文支持的错误。

1、VC新建工程,选择“Custom AppWizard”选项,项目名称设为”MFC OpenGL“,点击OK确定进入下一步。

2、选择Standard MFC AppWizardsteps,以原有MFC Appwizard(exe)为基础,并不添加新的用户步骤,所以在How many custom steps would you like?选项选择为0.后面选择默认项,finish完成。

3.执行Build命令,集成开发环境会生成MFC OpenGL.awx,并自动拷贝到”C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Template“目录下。

编辑OpenGL向导文件。

1、在stdafx.h添加opengl头文件,并添加lib。

#include<gl\gl.h>
#include<gl\glu.h>
#include <gl\glaux.h>
#include <gl\glut.h>
//{{AFX_INSERT_LOCATION}}
// $$INSERT_LOCATION_COMMENT$$


2、编写InitOpenGL()、DestroyOpenGL()函数。

FileView文件视图,在Template Files目录下打开view.h,在publiac添加 HGLRC hglrc;CClientDC *m_pDC;BOOL InitOpenGL();

// Attributes
public:
    HGLRC hglrc;
    CClientDC *m_pDC;
// Operations
public:
    BOOL InitOpenGL();
void DestroyOpenGL();

在View.cpp添加函数实现 BOOL $$VIEW_CLASS$$::InitOpenGL( );void $$VIEW_CLASS$$::DestroyOpenGL()

/
// $$VIEW_CLASS$$ message handlers   自定义的函数一定要在此句话之后,不要放在末尾,否则指示错误文件不正确结束。
BOOL $$VIEW_CLASS$$::InitOpenGL()
{
	PIXELFORMATDESCRIPTOR pixelDesc;//在opengl中用PIXELFORMATDESCRIPTOR描述绘图曲面的象素格式
	//定义一个像素对象为pixelDesc
	//以下为该格式的成员设置
	pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);//数据结构大小
	pixelDesc.nVersion = 1;//数据结构的版本号,设为1	
	pixelDesc.dwFlags =//定义象素格式属性的一系列位标志,一般不互相排斥
		PFD_DRAW_TO_WINDOW //指缓冲区可以在窗口或者设备表面绘图
		| PFD_SUPPORT_OPENGL //缓冲区支持opengl绘图
		|PFD_DOUBLEBUFFER   //使用双缓冲区,在当前基本功能下,与PFD_SUPPOT_GDI相互排斥
		| PFD_STEREO;//缓冲区是立体的,当前基本功能不支持这个标志
	//_DONTCARE;     
	pixelDesc.iPixelType =	//像素格式的类型
		PFD_TYPE_RGBA;//RGBA类型,每个象素依次有四个基本组成:红绿蓝所占的比例,一般在0-1之间设值,
	//最后一个是alpha,代表像素的透明程度,1表示完全不透明,0表示完全透明
	pixelDesc.cColorBits = 32;//表示每个RGBA颜色缓冲区的位平面数目,(不包括alpha)这里值32位真彩色
	pixelDesc.cRedBits = 8;//表示每个RGBA颜色缓冲区的红色位平面数目
	pixelDesc.cRedShift = 16;//表示每个RGBA颜色缓冲区的红色位平面偏移量
	pixelDesc.cGreenBits = 8;//表示每个RGBA颜色缓冲区的绿色位平面数目
	pixelDesc.cGreenShift = 8;//表示每个RGBA颜色缓冲区的绿色位平面偏移量
	pixelDesc.cBlueBits = 8;//表示每个RGBA颜色缓冲区的蓝色位平面数目
	pixelDesc.cBlueShift = 0;//表示每个RGBA颜色缓冲区的蓝色位平面偏移量
	pixelDesc.cAlphaBits = 0;//表示每个RGBA颜色缓冲区的alpha平面数目,alpha平面数目不被支持
	pixelDesc.cAlphaShift = 0;//表示每个RGBA颜色缓冲区的alpha平面偏移量,alpha平面偏移量不被支持
	pixelDesc.cAccumBits = 64;//累加缓冲区的位平面总数
	pixelDesc.cAccumRedBits = 16;//累加缓冲区的红色位平面数
	pixelDesc.cAccumGreenBits = 16;//累加缓冲区的绿色位平面数
	pixelDesc.cAccumBlueBits = 16;//累加缓冲区的蓝色位平面数
	pixelDesc.cAccumAlphaBits = 0;//累加缓冲区的alpha平面数
	pixelDesc.cDepthBits = 32;//深度(z轴)缓冲区的深度值
	pixelDesc.cStencilBits = 8;//模板缓冲区的深度值
	pixelDesc.cAuxBuffers = 0;//辅助缓冲区的数目,不支持辅助缓冲区
	//pixelDesc.iLayerType = PFD_MAIN_PLANE;   早期的opengl使用,现在不使用此参数,可忽略
	pixelDesc.bReserved = 0;//定义覆盖及底层平面的编号,0-3个字节最多定义15个覆盖层平面,
	//4-7个平面最多定义15个底层平面
	//pixelDesc.dwLayerMask = 0;早期的opengl使用,现在不使用此参数,可忽略
	pixelDesc.dwVisibleMask = 0;//若像素类型为RGBA,定义底层平面的象素颜色或色彩指数
	//pixelDesc.dwDamageMask = 0;早期的opengl使用,现在不使用此参数,可忽略
	//像素格式设置完毕
	
	m_pDC = new CClientDC(this);//动态生成一个CClientDC类的指针this指针覆给CTestView类的成员变量m_PDC
	int m_GLPixelIndex = ChoosePixelFormat(m_pDC->GetSafeHdc(),&pixelDesc);	//选择像素格式
	//GetSafeHdc()得到一个设备描述表的句柄,此为得到当前设备描述表的句柄
	if(m_GLPixelIndex == 0) // Choose default
	{
		AfxMessageBox("no matched pixelformat!");
		m_GLPixelIndex = 1;
		if(DescribePixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,
			sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)//当前描述表与定义的象素格式不符
			//DescribePixelFormat提供与参数hdc参数相关的,由iPixelFormat标识的象素格式类型,
			//并由像素格式类型设置ppfd指向的PIXELFORMATDESCRIPTOR结构,参数依次为hdc,iPixelFormat,nByte,ppfd
			return FALSE;
	}		
	
	if(!SetPixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,&pixelDesc))	//设置像素格式
		return FALSE;
	
	hglrc=wglCreateContext(m_pDC->GetSafeHdc());//产生一个新的opengl绘图描述表使之适合在参数hdc给出的设备上画图	
	
	wglMakeCurrent(m_pDC->GetSafeHdc(),hglrc);
	
	light();//设置光照环境
	myinit();//设置绘图环境
	
	return TRUE;
}
void $$VIEW_CLASS$$::DestroyOpenGL()
{
wglMakeCurrent(NULL,NULL);
if(hglrc)
  wglDeleteContext(hglrc);
  hglrc=0;
}

$$VIEW_CLASS$$::~$$VIEW_CLASS$$()
{
    if(m_pDC)
       delete m_pDC;
}
3、添加light()设置光照条件和myinit()设置绘图环境函数
//View.h
// Operations
public:
	BOOL InitOpenGL();
        void DestroyOpenGL();
	void light();
	void myinit();

void $$VIEW_CLASS$$::light()
{
	// Lights properties
	float ambientProperties[]  = {0.7f, 0.7f, 0.7f, 1.0f};
	float diffuseProperties[]  = {0.8f, 0.8f, 0.8f, 1.0f};
	float specularProperties[] = {1.0f, 1.0f, 1.0f, 1.0f};	
	//	GLfloat	position[] = {1.0f, 3.0f, 1.0f, 0.0f};//光在水平坐标系中的位置
	glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties);
	glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties);
	glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties);
	//	glLightfv( GL_LIGHT0, GL_POSITION, position);//设置光源参数,v表示参数用矢量形式position被设定
	glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
	
	// back material
	float MatAmbientBack[]  = {0.0f, 0.0f, 0.0f, 0.0f};
	glMaterialfv(GL_BACK,GL_AMBIENT,MatAmbientBack);
	//	SetMaterial(m_glMat[0],false);
	
	float ambient[]  = {0.0f,0.0f,0.0f,1.0f};
	float diffuse[]  = {0.0f,0.0f,0.0f,1.0f};
	float specular[]  = {0.0f,0.0f,0.0f,1.0f};
	float emission[]  = {0.3f,0.3f,0.3f,1.0f};
	float shininess[] = {0.0f};
	
	// Change
	//	if(string == "Silver")
	{
		// Ambient
		ambient[0] = 0.19225f;
		ambient[1] = 0.19225f;
		ambient[2] = 0.19225f;
		ambient[3] = 1.0f;
		// Diffuse
		diffuse[0] = 0.50754f;
		diffuse[1] = 0.50754f;
		diffuse[2] = 0.50754f;
		diffuse[3] = 1.0f;
		// Specular
		specular[0] = 0.508273f;
		specular[1] = 0.508273f;
		specular[2] = 0.508273f;
		specular[3] = 1.0f;
		// Shininess
		shininess[0] = 51.2f;
	}
	// apply
	glMaterialfv( GL_FRONT, GL_AMBIENT,   ambient);
	glMaterialfv( GL_FRONT, GL_DIFFUSE,   diffuse);
	glMaterialfv( GL_FRONT, GL_SPECULAR,  specular);
	glMaterialfv( GL_FRONT, GL_SHININESS, shininess);
	glMaterialfv( GL_FRONT, GL_EMISSION,  emission);
	
}

void $$VIEW_CLASS$$::myinit()
{
	//置黑背景
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景 
	glEnable(GL_DEPTH_TEST); // 启用深度测试 
	glClearDepth(1.0f); // 设置深度缓存 
	glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正 
	glShadeModel(GL_SMOOTH);//选择扁平或者光滑的阴影,此处选择了光滑的阴影
	
	//glClear(GL_COLOR_BUFFER_BIT);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	//用当前设置的清除色清除指定的缓冲区   (颜色缓冲区与深度缓冲区)
	glEnable(GL_NORMALIZE);//转换后法向矢量与单位长度成比例
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity ();//设置当前矩阵的单位矩阵
}
4、添加视点、投影矩阵
// Attributes
public:
	HGLRC hglrc;
	CClientDC *m_pDC;
	GLint m_viewport[4];  
    GLfloat m_ModelMatrix[16], m_PrjMatrix[16]; 

5、添加ResizeOpenGL,
 
//view.h
void ReSizeOpenGL(GLint *viewport, GLfloat *projMatrix, int cx, int cy);
void $$VIEW_CLASS$$::ReSizeOpenGL(GLint *m_viewport, GLfloat *projMatrix, int cx, int cy)
{
//把一个指定的opengl绘图描述表设定为正在调用线程的当前绘图描述表
glViewport(0,0,cx,cy);
 //定义视区矩阵,描述窗口中可能的屏幕原点(视口左下角坐标)以及屏幕宽度和高度
//视口的宽高比应等于取景体积的宽高比,否则窗口变化时会使景物变形
//给出一个变换命令前需声明是否更改模型取景或投影矩阵
glGetIntegerv(GL_VIEWPORT,m_viewport);
glMatrixMode(GL_PROJECTION); //声明是否需要修改模型取景,投影或纹理矩阵
//GL_PROJECTION为投影矩阵,GL_MODELVIEW为取景矩阵,GL_TEXTURE为纹理矩阵,一次只能修改一个矩阵
glLoadIdentity(); //清除当前可修改矩阵,一般在指定变换矩阵前调用它
gluPerspective(//设定一个透视投影矩阵
45.0f,//y方向的视角,以度为单位
(GLfloat)cx/(GLfloat)cy,//屏幕高宽比,高宽比是x与y的比(即宽与高的比)
0.1f,//视点到近平面的距离
1000.0f);//视点到远平面的距离
 glGetFloatv(GL_PROJECTION_MATRIX,projMatrix); 
 glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
6、添加绘制场景函数
 
public:
 BOOL InitOpenGL();
 void DestroyOpenGL();
 void light();
 void myinit();
 void ReSizeOpenGL(GLint *viewport, GLfloat *projMatrix, int cx, int cy);
 void DrawScene();
 
void $$VIEW_CLASS$$::DrawScene() 
 //示例 下面添上绘图代码 
  glTranslatef(0.0f,0.0f,-3.0f);

  glRotatef(90.0f,1.0f,0.0f,0.0f);  

  //GL_QUADS每四个连续的顶点定义一个四边形  

  glBegin(GL_QUADS); //立方体顶面  

 glColor3f(1.0f,0.0f,1.0f);  
  glVertex3f(-0.5,0.5f,0.5f);  //1点  

 glColor3f(1.0f,1.0f,1.0f);  

  glVertex3f(0.5f,0.5f,0.5f);   //3点  

  glColor3f(0.0f,1.0f,1.0f);  

  glVertex3f(0.5f,0.5f,-0.5f);  //5点  
  glColor3f(0.0f,0.0f,1.0f); 
 glVertex3f(-0.5f,0.5f,-0.5f);  //7点 
 glEnd();  

}
void $$VIEW_CLASS$$::OnDraw(CDC* pDC)

{

 $$DOC_CLASS$$* pDoc = GetDocument();

 ASSERT_VALID(pDoc);

$$IF(VERBOSE)

 // TODO: add draw code for native data here

 static BOOL bBusy = FALSE;  //添加的代码

 if (bBusy)

{

 return;

 }

 bBusy=TRUE; //双缓存应用

 glClearColor(0.0f,0.0f,0.0f,1.0f);//背景色

 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清除颜色缓存和深度缓存

 glMatrixMode(GL_MODELVIEW); //设置矩阵为模型矩阵

 glLoadIdentity(); //用单位矩阵替换当前矩阵

 //绘制图形

DrawScene();

glFinish();//完成绘制

SwapBuffers(wglGetCurrentDC());//双缓存应用

>bBusy=FALSE;//结束

$$ENDIF //VERBOSE

}

使用MFC OpenGL AppWizard

使用MFC OpenGL向导创立应用程序,新建一单文档程序后,添加三行代码即可,InitOpengl/DestroyOpenGL/ReSizeOpenGL();

int CTtView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

 if (CView::OnCreate(lpCreateStruct) == -1)

 return -1;

 

 // TODO: Add your specialized creation code here

 if(!InitOpenGL())

     return 0;

 return 0;

}





void CTtView::OnDestroy() 

{

 CView::OnDestroy();

 // TODO: Add your message handler code here

 DestroyOpenGL();

 

}
void CTtView::OnSize(UINT nType, int cx, int cy) 

{

 CView::OnSize(nType, cx, cy);

 // TODO: Add your message handler code here

 ReSizeOpenGL(m_viewport,m_PrjMatrix,cx,cy);

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值