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);
}