基于单文档的OpenGL图形程序的基本框架
1、 理论基础
a、在单文档的创建过程中,设置好显示的像素格式,并按OpenGL得要求设置窗口的属性和风格
b、在窗口的绘制过程中,首先获得Windows设备描述表DC,然后将其与事先设置好的OpenGL绘制
表述表RC联系起来;
c、调用OpenGL命令进行图形绘制;
d、退出OpenGL图形窗口时,释放OpenGL绘制描述表RC和Windows设备描述表DC。
2、编程步骤
a、启动vc6.0,选择NEW菜单,在NEW对话框中选择Project标签,选择"MFC AppWizard(exe)",
新建一个基于对话框的工程。名称为MySDOpenGL。
b、利用MFC ClassWizard为CMySDOpenGLView类添加消息WM_CREATE、WM_DESTROY、WM_SIZE、
WM_TIMER得响应函数.
c.在CMySDOpenGLView.h中加入源代码.
////////////////////////////////////////////////
//添加成员函数与成员变量
BOOL InitializeOpenGL(CDC *pDC);
void SetLogicalPalette(void);
BOOL SetupPixelFormat(void);
BOOL RenderScene();
HGLRC m_hRC; //OpenGL绘制描述表
HPALETTE m_hPalette; //OpenGL调色板
CDC* m_pDC; //OpenGL设备描述表
///////////////////////////////////////////////////
d、在文件CMySDOpenGLView.cpp中加入如下代码
BOOL CMySDOpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
////////////////////////////////////////////////////
//设置窗口类型
cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
/////////////////////////////////////////////////////
return CView::PreCreateWindow(cs);
}
void CMySDOpenGLView::OnDraw(CDC* pDC)
{
CMySDOpenGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
////////////////////////////////////////////////////
RenderScene(); //渲染场景
///////////////////////////////////////////////////
}
int CMySDOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
////////////////////////////////////////////////////////
//初始化调色板和渲染上下文、定时器
m_pDC = new CClientDC(this);
SetTimer(1,20,NULL);
InitializeOpenGL(m_pDC);
///////////////////////////////////////////////////////
return 0;
}
void CMySDOpenGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
///////////////////////////////////////////////////////
//删除调色板和渲染上下文
::wglMakeCurrent(0,0);
::wglDeleteContext(m_hRC);
if(m_hPalette)
DeleteObject(m_hPalette);
if(m_pDC)
delete m_pDC;
KillTimer(1);
}
void CMySDOpenGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//////////////////////////////////////////////////////
//添加窗口缩放时的变换函数
glViewport(0,0,cx,cy);
//////////////////////////////////////////////////////
}
void CMySDOpenGLView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
///////////////////////////////////////////////////////////
//添加定时器响应函数和场景更新函数
Invalidate(FALSE);
///////////////////////////////////////////////////////////
CView::OnTimer(nIDEvent);
}
///////////////////////////////////////////////////////////
//场景绘制与渲染
///////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::RenderScene()
{
// glClearColor(1.0,0.0,0.0,1.0);
// glClear(GL_COLOR_BUFFER_BIT);
::SwapBuffers(m_pDC->GetSafeHdc()); //交换缓冲区
return TRUE;
}
/////////////////////////////////////////////////////////////
//设置像素格式
////////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::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, //忽略累加位
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 CMySDOpenGLView::SetLogicalPalette()
{
struct
{
WORD Vertion;
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);
}
////////////////////////////////////////////////////////
// 初始化openGL场景
////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::InitializeOpenGL(CDC *pDC)
{
m_pDC = pDC;
SetupPixelFormat();
//生成绘制描述表
m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
//设置当前绘制描述表
::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
return TRUE;
}
e、在文件StdAfx.h中加入如下源代码。
//////////////////////////////////////////////////////////////////////////
//包含有关OpenGL 函数的头文件
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <GL/glut.h>
//////////////////////////////////////////////////////////////////////////
最后运行编译。