1. Win32控制台方式
建立Win32 控制台程序,在头文件中加入
#include <windows.h> #include <wingdi.h> #include <GL/gl.h> #include <GL/glu.h > #include <GL/glaux.h>
2. MFC方式
(1)采用VC AppWizard向导创建空的MFC(EXE)工程框架,整个过程总共6步,值得指出的是一般情况下在向导的第1步选择创建工程的模式都为单文档,以下的步骤中假设创建的工程名为First.
(2)设置所创建工程的Link属性。打开工程/设置/连接,在对象/库模块中加入opengl32.lib glu32.lib glaux.lib.
(3)在视图类(View)的头文件(Firstview.h)中加上:
#include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h>
(4)在视图类的实现文件Firstview.cpp中处理成员函数PreCreatWindow(),加上如下代码:
cs.style |=WS_CLIPISBLINGS|WS_CLIPCHILDREN|CS_OWNDC;
用来设置OpenGL绘图窗口的风格
(5)在视图类的实现文件Firstview.cpp中处理成员函数OnCreate,来创建OpenGL的绘图设备
OpenGL绘图的机制是:先用OpenGL的绘图上下文Rendering Context(简称为RC)把图画好,再把所绘结果通过SwapBuffers()函数传给Window的绘图上下文DeviceContext(简称为DC)。要注意的是,程序运行过程中,可以有多个DC,但只能有一个RC。因此当一个DC画完图后,要立即释放RC,以便其他的DC也使用。在后面的代码中将有详细解释。
int CFirstView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; InitializeOpenGL(); return 0; } void CFirstView::InitializeOpenGL() { m_pDC=new CClientDC(this); // 创建OpenGL设备描述表 ASSERT(m_pDC!=NULL); If(!SetupPixelFormat()) // 设置象素格式 return; m_hRC=::wglCreateContext(m_pDC->m_hDC); // 创建OpenGL渲染描述表 ::wglMakeCurrent(m_pDC->m_hDC,m_hRC); // 将RC与DC关联起来 } BOOL CFirstView::SetupPixelFormat() { static PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 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 m_PixelFormat; if({m_PixelFormat=ChoosePixelFormat(m_pDC->m_hDC,&pfd)==0) { MessageBox(“OpenGL的像素选择格式失败“); return FALSE; } if(SetPixelFormat(m_pDC->m_hDC,m_PixelFormat,&pfd))==FALSE) { MessageBox(“OpenGL的像素格式的设置失败“); return FALSE; } return TRUE; }
或
int CFirstView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; gl_Init(); return 0; } void CFirstView::gl_Init() { //下面的结构说明绘图设备的像素格式 PIXELFORMATDESCRIPTOR pfd={ sizeof(PIXELFORMATDESCRIPTOR), //数据结构大小 1, //数据结构版本号 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, //缓冲区可以在窗口上绘图,支持OpenGL绘图 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, //忽略层,可见性和损毁掩膜 }; //得到当前正在使用的绘图设备句柄 m_hDC=GetDC()->GetSafeHdc(); //根据当前绘图设备的特性,为之选择一个与pfd所指定的格式相匹配 //的像素格式,存于nPixelFormat中 int nPixelFormat=::ChoosePixelFormat(m_hDC,&pfd); //将当前绘图设备的像素格式设为nPixelFormat ::SetPixelFormat(m_hDC,nPixelFormat,&pfd); //根据当前绘图设备,创建一个像素格式与之匹配的OpenGL的图形操作设备表 m_hRC=::wglCreateContext(m_hDC); /*指定OpenGL的图形操作设备表是m_hRC,并且建立它与当前绘图设备 m_hDC间的连接,下列函数执行后,所有绘图命令的结果都出现在设 备m_hDC上*/ ::wglMakeCurrent(m_hDC,m_hRC); }
(6)在文件Firstview.cpp中处理OnDestroy(),在程序退出时处理该函数,以释放在程序启动时所申请的OpenGL变量(包括RC,DC等)。
void CFirstView::OnDestroy() { CView::OnDestroy(); ::wglMakeCurrent(m_pDC->m_hDC,NULL); // 释放与m_hDC 对应的 RC ::wglDeleteContext(m_hRC); if(m_pDC) delete m_pDC; // 删除当前 View 拥有的 DC }
(7)在文件Firstview.cpp中处理OnEraseBkgnd()
BOOL CFirstView::OnEraseBkgnd(CDC* pDC) { // return CView::OnEraseBkgnd(pDC); return TRUE; }
(8)在文件Firstview.cpp中处理OnDraw ()
void CFirstView::OnDraw(CDC* pDC) { CVaseModelDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); wglMakeCurrent(m_pDC->m_hDC,m_hRC); // 使RC与当前DC 相对应 myDrawScene(); //具体的绘图函数,在RC中绘制 SwapBuffers(m_pDC->m_hDC); //把RC中所绘传的到当前的DC上,从而在屏幕上显示 wglMakeCurrent(m_pDC->m_hDC,NULL); // 释放与m_hDC 对应的 RC }
(9)在文件Firstview.cpp中处理RenderScene()
BOOL CFirstView::myDrawScene() { glClearColor(0.0f, 0.0f, 0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(1.0f,1.0f,0.0f); glEnd(); glBegin(GL_LINES); glColor3f(0.0f,1.0f,0.0f); glVertex3f(0.0,0.0,0.0); glVertex3f(1.0,-1.0,0.0); glEnd(); glFlush (); return TRUE; }
(10)在文件Firstview.cpp中处理OnSize(),该函数响应窗口缩放事件,因此所显示图形可以跟随窗口的缩放而等比缩放。
void CVaseModelView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); glViewport(0,0,cx,cy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(cx<=cy) glOrtho(-1.50*cx/cy,1.50*cx/cy,-1.50,1.50,-10.0,10.0); else glOrtho(-1.50,1.50,-1.50*cy/cx,1.50*cy/cx,-10.0,10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); myDrawScene(); }
注:定义 HDC m_hDC;或CDC* m_hDC;