基于OpenGL显示平台功能开发-MFC框架篇
简介
关于OpenGL MFC应用程序框架的搭建,大家可以在网上找到很多相关的历程。而且按照历程的步骤,基本上可以很顺利地搭建出来。为了更能充分的帮助读者了解MFC下OpenGL环境搭建的过程。本篇主要对其步骤进行了一个详细的介绍,在下一篇文章中会对其在创建中涉及到的理论知识及相应的OpenGL API函数接口做一个具体的分析介绍。
环境搭建步骤(单文档)
- 选择一个编译环境(如VC2010),安装GLUT工具包
- 下载glut库,下载地址http://openglsource.com/download/download.htm,下载glut-3.7.6-bin.zip
- 解压下载包,得到5个文件(glut.dll,glut.h,glut.lib,glut32.dll,glut32.lib)
1)把glut.h复制到D:\Program Files\Microsoft\Visual Studio10.0\VC\include\gl文件夹中,如果没有gl这个文件夹则可以自己新建一个。(D是你安装VS的盘的目录)
2)把glut.lib和glut32.lib放到静态函数库所在文件夹(即与include并排的lib文件夹下)。
3)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)
OpenGL在VC2010 下的配置
- 新建MFC单文档应用程序,名称命名为MyOpenGLProject,应用程序类型选择单个文档,其他默认,一直下一步,点击完成。
- 右击工程名->属性,弹出属性页,点击链接器->附加依赖项,添加glut.lib;glut32.lib,中间以分号隔开
- 在stdafx.h中添加#include< gl/glut.h>,此时opengl相关的文件配置已基本完成。
接着在MyOpenGLProjectView.h头文件中添加如下成员及消息函数:
class CMyOpenGLProjectView : public CView { ... public: virtual void OnDraw(CDC* pDC); public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnDestroy(); protected: void Init(); BOOL InitializeOpenGL(CDC* pDC); void SetLogicalPalette(); BOOL SetupPixelFormat(); void RunScene(); // 绘图工作再此完成 void Projection(); // 实施投影变换 private: HGLRC m_hRC; // OpenGL绘制描述表 HPALETTE m_hPalette; // OpenGL调色板 CDC* m_pDC; // OpenGL设备描述表 GLfloat m_width; // 屏幕长度 GLfloat m_height; // 屏幕宽度 GLfloat m_fViewAngle; // 视角,初始45 GLfloat camPos[3]; ... }
在MyOpenGLProject.cpp源文件中添加如下实现:
CMyOpenGLProjectView::CMyOpenGLProjectView()
{
m_hRC = NULL;
m_hPalette = NULL;
m_pDC = NULL;
}
void CMyOpenGLProjectView::OnDraw(CDC* /*pDC*/)
{
CMyOpenGLProjectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
RunScene();
}
int CMyOpenGLProjectView ::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_pDC = new CClientDC(this);
InitializeOpenGL(m_pDC);
Init();
return 0;
}
BOOL CMyOpenGLProjectView ::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CMyOpenGLProjectView ::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
m_width = cx;
m_height = cy;
glViewport(0,0,cx,cy);
}
void CMyOpenGLProjectView ::OnDestroy()
{
CView::OnDestroy();
wglMakeCurrent(0,0);
wglDeleteContext( m_hRC);
if (m_hPalette)
DeleteObject(m_hPalette);
if ( m_pDC )
{
delete m_pDC;
}
}
void CMyOpenGLProjectView ::Init()
{
camPos[0] = 0.0f;
camPos[1] = 0.0f;
camPos[2] = 1500.0f;
m_fViewAngle = 45.0f; // 初始化相机视角45°
glClearColor(0.5,0.5,0.5,1.0); //单一背景颜色默认值
glClearDepth(1.0F);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
}
BOOL CMyOpenGLProjectView ::InitializeOpenGL(CDC *pDC)
{
m_pDC = pDC;
SetupPixelFormat();
//生成绘制描述表
m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
//重置当前绘制描述表
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
return TRUE;
}
BOOL CMyOpenGLProjectView ::SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累加缓存
0, 0, 0, 0, // 忽略累加位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
int pixelformat;
pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//选择像素格式
SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //设置像素格式
if(pfd.dwFlags & PFD_NEED_PALETTE)
SetLogicalPalette(); //设置逻辑调色板
return TRUE;
}
void CMyOpenGLProjectView ::SetLogicalPalette()
{
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
} logicalPalette = { 0x300, 256 };
BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};
BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};
BYTE blues[] = {0, 85, 170, 255};
for (int colorNum=0; colorNum<256; ++colorNum)
{
logicalPalette.aEntries[colorNum].peRed =
reds[colorNum & 0x07];
logicalPalette.aEntries[colorNum].peGreen =
greens[(colorNum >> 0x03) & 0x07];
logicalPalette.aEntries[colorNum].peBlue =
blues[(colorNum >> 0x06) & 0x03];
logicalPalette.aEntries[colorNum].peFlags = 0;
}
m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
}
void CMyOpenGLProjectView::Projection()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(m_fViewAngle, m_width/m_height, 1.0F, 1000000.0F);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camPos[0],camPos[1],camPos[2],0,0,0,0,1,0);
}
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 实施投影变换,透视投影
SwapBuffers(m_pDC->GetSafeHdc());
}
`
3. 至此,一个简单的MFC下OpenGL绘图环境基本已搭建完成,运行程序,效果如下所示。
绘制旋转的三角形
为了使场景的显示看的丰富,下面就在场景中绘制一个简单的带颜色的三角形,并使三角形能绕着轴旋转。
绘制三角形的代码如下:
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 实施投影变换,透视投影
// 绘制场景
glPushMatrix();
glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.0, 300.0, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -300.0, -300.0, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 300.0, -300.0, 0.0 );
glEnd();
glPopMatrix();
SwapBuffers(m_pDC->GetSafeHdc());
}
运行程序,效果如下所示。
添加旋转操作
1. 首先,在MyOpenGLProjectView.h文件中添加如下成员
class CMyOpenGLProjectView : public CView
{
…
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
private:
static double m_Rotatf; // 模型旋转角度变量
…
}
2. 在MyOpenGLProjectView.cpp文件中实现
double CMyOpenGLProjectView::m_Rotatf = 0.0; // 对旋转变量进行初始化赋值
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 实施投影变换,透视投影
// 绘制场景
glPushMatrix();
glRotatef(m_Rotatf,0,1,0); // 添加,绕y轴旋转
glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.0, 300.0, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -300.0, -300.0, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 300.0, -300.0, 0.0 );
glEnd();
glPopMatrix();
SwapBuffers(m_pDC->GetSafeHdc());
}
void CMyOpenGLProjectView::OnTimer(UINT_PTR nIDEvent)
{
m_Rotatf += 10.0; // 添加
RunScene();
CView::OnTimer(nIDEvent);
}
int CMyOpenGLProjectView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_pDC = new CClientDC(this);
InitializeOpenGL(m_pDC);
Init();
SetTimer(0,100,0); // 添加
return 0;
}
至此,旋转动画已添加完成,运行效果如下所示:
源代码地址链接:OpenGL MFC模型旋转