以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- Win32 下的 OpenGL 编程必须步骤 (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=87519) |
-- 作者:葛靖青001 -- 发布时间:11/7/2010 11:51:00 AM -- Win32 下的 OpenGL 编程必须步骤 【转自互联网】 一、 前言 人生在于折腾,继续折腾吧。 OpenGL 编程的红宝书《 OpenGL Programming Guide 》在举例子的时候为了平台无关,使用的都是 GLUT 来管理窗口,个人感觉不爽 -_-! 要是针对 Windows 平台,个人倾向使用 Win32(MFC 也行 ) ,要是跨平台,我还会 Qt 嘛, Qt 对 OpenGL 也有很好的支持的,为啥还折腾个新的窗口管理组件?虽然说 GLUT 比较简单,但是还是不喜欢扭曲的适应之,何况我去看了下 GLUT 这个东西,最新的版本都是 2001 年发布的了,什么古董级的家伙啊,更加不想用了,还是在 Windows 平台上学习 OpenGL 吧。刚开始这样想的就这样做了,结果比我想象的稍微复杂一些,原来不光是熟悉 Win32 API 就能随便搞掂的,当时还看到有人专门为此写了篇论文 -_-!( 不知道学历 ) 吓到我了,没有那么高的学术研究价值吧?后来又看到 3 个研究生都开始为此写论文了(这还真是研究院中的人写的),感叹不已。。。。。。。。。。
二、 提要
三、 Win32 下 OpenGL 编程需要的操作步骤
下面会用到的全局变量: // GLOBALS //////////////////////////////////////////////// HWND ghWnd ; // 窗口句柄 HINSTANCE ghInstance ; // 程序实例句柄 HDC ghDC ; // GDI 设备环境句柄 HGLRC ghRC ; // 渲染环境句柄
1. 头文件 // OpenGL 需要的头文件 #include <GL/gl.h> #include <GL/glu.h> 需要注意的就是,必须先包含 Windows.h ,然后才能包含 gl.h 和 glu.h 。因为 gl.h 与 glu.h 中可能包含 Windows.h 中定义的宏。
2. 链接库 // 定义程序链接时所需要调用的OpenGL 程序库, 简化工程配置 #pragma comment ( lib , "opengl32.lib" ) #pragma comment ( lib , "glu32.lib" )
3. 像素格式 (Pixel Format) 设置 int ChoosePixelFormat(
,
BOOL SetPixelFormat(
,
,
这是 Win32 下的 OpenGL 编程必做的事情之一,为 DC 设置像素的格式。 // 设置像素格式 PIXELFORMATDESCRIPTOR pfd ; int iFormat ;
ghDC = GetDC ( ghWnd );
ZeroMemory ( & pfd , sizeof ( pfd ) ); pfd . nSize = sizeof ( pfd ); pfd . nVersion = 1; // 版本,一般设为 pfd . dwFlags = PFD_DRAW_TO_WINDOW | // 一组表明象素缓冲特性的标志位 PFD_SUPPORT_OPENGL ; pfd . iPixelType = PFD_TYPE_RGBA ; // 明象素数据类型是RGBA 还是颜色索引; pfd . cColorBits = 32; // 每个颜色缓冲区中颜色位平面的数目,对颜色索引方式是缓冲区大小 pfd . iLayerType = PFD_MAIN_PLANE ; // 被忽略,为了一致性而包含的
iFormat = ChoosePixelFormat ( ghDC , & pfd ); // 选择一个像素格式
SetPixelFormat ( ghDC , iFormat , & pfd ); // 设置到DC 中
这样的函数完成了像素格式的设置,事实上还可以进行更多的操作,比如设置缓冲区等,下面的代码就是一个设置双重缓冲区的代码。 PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof( pfd ); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; int iFormat = ChoosePixelFormat( hDC, &pfd ); SetPixelFormat( hDC, iFormat, &pfd );
具体的每个参数的意义,最好还是去查查 MSDN 啦,查看 PIXELFORMATDESCRIPTOR 结构的解释就行。
4. 渲染器环境 (Render Context) 创建 函数原型: HGLRC wglCreateContext(
BOOL wglMakeCurrent(
,
调用方式如下: ghRC = wglCreateContext ( ghDC ); // 创建渲染环境 wglMakeCurrent ( ghDC , ghRC ); // 使之成为当前渲染环境
5. 实际绘制
6. 释放资源 需要调用的函数原型: BOOL wglDeleteContext(
// 取消OpenGL ,在程序结束前调用,释放渲染环境,设备环境以及最终窗口句柄。 void DisableOpenGL () { wglMakeCurrent ( NULL , NULL ); wglDeleteContext ( ghRC ); ReleaseDC ( ghWnd , ghDC ); }
上述流程基本就是一个完整的 Win32 OpenGL 程序所需要的了。。。。。。实际上在参考 5 中,有较为详细的论述,但是事实上,你也可以作为论文发表,见参考 3.
四、 真正的 OpenGL 相关内容 基本流程分两部分,初始化和实际绘制: //OpenGL 初始化开始 void SceneInit ( int w , int h ) { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景
glMatrixMode ( GL_PROJECTION ); glLoadIdentity (); glOrtho (0.0, 1.0, 0.0, 1.0, -1.0, 1.0); }
// 这里进行所有的绘图工作 void SceneShow ( GLvoid ) { glClear ( GL_COLOR_BUFFER_BIT );
glColor3f (1.0, 1.0, 1.0); glBegin ( GL_POLYGON ); glVertex3f (0.25, 0.25, 0.0); glVertex3f (0.75, 0.25, 0.0); glVertex3f (0.75, 0.75, 0.0); glVertex3f (0.25, 0.75, 0.0); glEnd (); glFlush (); }
显示效果非常简陋,就是黑色背景窗口中一个白色的矩形。 OpenGLGL 的每个函数意义不在此文中描述,本文的主要目的是讲述 win32 中 OpenGL 编程需要的操作。
然后就是将所有的部分串起来了,上述都是代码的片段。 全部源代码见我的放在 Google Code 上的 blog-sample-code 中 2009-9-27\Win32OpenGLTemplate 目录。取回方式见本文最后的说明。
2. 动画演示:一个旋转的矩形
全部的改动如下: // 激活创建OpenGL 窗口 void EnableOpenGL () { PIXELFORMATDESCRIPTOR pfd ; int iFormat ;
ghDC = GetDC ( ghWnd );
ZeroMemory ( & pfd , sizeof ( pfd ) ); pfd . nSize = sizeof ( pfd ); pfd . nVersion = 1; // 版本,一般设为
// 一组表明象素缓冲特性的标志位 pfd . dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ; pfd . iPixelType = PFD_TYPE_RGBA ; // 明象素数据类型是RGBA 还是颜色索引; pfd . cColorBits = 32; // 每个颜色缓冲区中颜色位平面的数目,对颜色索引方式是缓冲区大小 pfd . cDepthBits = 16; pfd . iLayerType = PFD_MAIN_PLANE ; // 被忽略,为了一致性而包含的
iFormat = ChoosePixelFormat ( ghDC , & pfd ); // 选择一个像素格式
SetPixelFormat ( ghDC , iFormat , & pfd ); // 设置到DC 中
ghRC = wglCreateContext ( ghDC ); // 创建绘图描述表 wglMakeCurrent ( ghDC , ghRC ); // 使之成为当前绘图描述表 }
//OpenGL 初始化开始 void SceneInit ( int w , int h ) { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景 glColor3f (1.0f, 1.0f, 1.0f);
glShadeModel ( GL_FLAT ); glMatrixMode ( GL_PROJECTION ); glLoadIdentity (); glOrtho (-50.0f, 50.0f, -50.0f, 50.0f, -1.0f, 1.0f); }
// 这里进行所有的绘图工作 void SceneShow ( GLvoid ) { // 旋转角度 static float fSpin = 0.0f; fSpin += 2.0f; if ( fSpin > 360.0f) { fSpin -= 360.0f; }
glClear ( GL_COLOR_BUFFER_BIT );
glPushMatrix (); // 旋转矩形的主要函数 glRotatef ( fSpin , 0.0f, 0.0f, 1.0f); glRectf (-25.0, -25.0, 25.0, 25.0); glPopMatrix ();
// 交换缓冲区 SwapBuffers ( ghDC ); }
全部源代码见我的放在 Google Code 上的 blog-sample-code 中 2009-9-28\RotateRect \ 目录。取回方式见本文最后的说明。 |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
62.500ms |