OpenGL 的初始化其实挺麻烦的,特别是那么多的大写字母,所以记在这以后用时直接抄
说明:以下参考书:向世明 编著的《OpenGL 编程与实例》,电子工业出版社 1999 年9月。
比较老的一本书,呵呵,借不到更新的了,不过里面讲的还不错,起码跟着走还能运行出想要的效果
(一)创建新的 VC++ 工程:
选择 MFC AppWizard(exe),这里我命名为 studyOpengl
第一步:Single document
第二步:None
第三步:None 并选择 ActiveX controls
第四步:Use 3D Controls
第五步和第六步:缺省设置
(二)添加头文件:共两个
在 studyOpenglView.h 里添加下面两个头文件
#include "gl\gl.h"
#include "gl\glu.h"
(三)添加 lib :共两个
打开菜单 Project(工程) -> Setting(设置),在弹出的对话框的右边选择 Link 标签,然后在下面的
Object\Libaray Modules(对象\库模块) 中添加 OpenGl32.lib 和 glu32.lib ,注意多个 lib 之间以空格分开,
这两个 lib 文件分别帮助程序利用链接器访问动态链接库函数 opengl32.dll 和 glu32.dll,这两个 动态链接库可以
在电脑里系统盘的 WINDOWS 系统文件夹下的 system32 文件夹下找到。
(四)编辑 MainFrm.cpp 文件:
打开 MainFrm.cpp 文件,编辑里面的 PreCreateWindow() 函数,如下:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
// 增加下面两行,设置窗口大小
cs.cx = 300;
cs.cy = 335;
return TRUE;
}
下面开始设置与 opengl 有关的环境
(五)设置像素格式:
在 Source Files 里打开 studyOpenglView.cpp 文件。然后在工具条中点击 WizardBar Action 方向朝下的三角形图标,选择 Add Windows Message Hander 选项,在弹出的对话框中增加 Windows 消息 WM_CREATE,选择 Add and Edit 按钮生成消息响应函数 OnCreate()。
再选择上面的三角形图标选择 Add Member Function 选项,编辑弹出的对话框,可如下:void protected Init(),在相应栏里写上即可。
按上述方法增加保护成员函数 bool bSetupPixelFormat() 用于设置像素格式。
再打开 studyOpenglView.h 头文件,声明两个公有成员如下:
CClientDC * m_pDC;
CRect m_oldRect;
再打开 studyOpenglView.cpp 文件,在构造函数里对上面声明的成员变量进行初始化,如下:
CStudyOpenGLView::CStudyOpenGLView()
{
// TODO: add construction code here
m_pDC = NULL;
}
再选择成员函数列表中的 bSetupPixelFormat(),编辑该函数如下:
bool CStudyOpenGLView::bSetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
int pixelformat;
if((pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd)) == 0)
{
MessageBox("选择象素格式失败");
return false;
}
if((SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)) == false)
{
MessageBox("设置象素格式失败");
return false;
}
return true;
}
再选择成员函数 Init() , 编辑如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
}
到这里就完成了像素格式的设置,下面将创建着色描述表相关的
(六)创建着色描述表并设置:
在上面的 Init() 函数后面追加代码,最后 Init() 函数如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
n =::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
}
(七)创建 结束时的删除着色描述表:
按前面的方法增加 Windows 消息 WM_DESTROY 选择 Add and Edit 生成响应函数 OnDestroy(),如下:
void CStudyOpenGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL,NULL);
if(hrc)
::wglDeleteContext(hrc);
if(m_pDC)
delete m_pDC;
CView::OnDestroy();
}
然后在前面生成的 OnCreate() 函数里添加代码,如下:
int CStudyOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
Init();
return 0;
}
(八)设定OpenGL 风格:
选择成员函数 PreCreateWindow() ,编辑如下:
BOOL CStudyOpenGLView::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);
}
(九)建立 OpenGL 视点:
1:再编辑 Init() 函数,编辑后的 Init() 如下:
void CStudyOpenGLView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if(!bSetupPixelFormat()) return ;
n =::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
GetClientRect(&m_oldRect);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
2:添加 Windows 消息:
用前面的方法增加消息 WM_SIZE 并生成响应函数 OnSize(),编辑如下:
void CStudyOpenGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(cy > 0)
{
if((m_oldRect.right > cx) || (m_oldRect.bottom > cy))
{
RedrawWindow();
}
m_oldRect.right = cx;
m_oldRect.bottom = cy;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,0.0,7.0);
glViewport(0,0,cx,cy);
}
}
该函数用于当窗口尺寸大小改变时重新绘制
3:建立用户绘制函数 DrawScene():
增加保护成员函数 DrawScene(),该函数具体绘制 OpenGL 图形。
编辑 OnDraw() 函数如下:
void CStudyOpenGLView::OnDraw(CDC* pDC)
{
CStudyOpenGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawScene();
}
到这里则所有工作都已经做完,只需要在 DrawScene() 函数里调用绘制图形的各种函数绘制图形即可,例如:
void CStudyOpenGLView::DrawScene()
{
// 设置背景颜色
glClearColor(0.0f , 0.0f , 0.0f , 1.0f);
// 清除颜色缓存和深度缓存
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// 设置绘制物理的颜色,前景颜色
glColor3f(1.0f,0.0f,0.0f);
GLfloat fPointSize[2];
// 得到点的可表现的象素范围大小
glGetFloatv(GL_POINT_SIZE_RANGE , fPointSize);
// 设置点的象素尺寸
glPointSize(fPointSize[1]/2.0f);
// 绘制 5 个点
glBegin(GL_POINTS);
glVertex2f(0.0f,0.0f);
glVertex2f(0.5f , 0.5f);
glVertex2f(-0.5f , 0.5f);
glVertex2f(0.5f , -0.5f);
glVertex2f(-0.5f , -0.5f);
glEnd();
glFinish();
}
最后运行程序即可以看到效果图形,五个特别大的点。。。
需要注意下的是 最后的 glFinish() 函数,目前理解好象是输出缓冲图形,不加有时看不到该看到的效果,类似于一些语言里的 flush() 函数吧