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() 函数吧