`
webcenterol
  • 浏览: 910120 次
文章分类
社区版块
存档分类
最新评论

Win32 OpenGL编程(2) 寻找缺失的OpenGL函数

 
阅读更多

Win32 OpenGL 编程 (2) 寻找缺失的 OpenGL 函数

write by 九天雁翎 (JTianLing) -- blog.csdn.net/vagrxie

讨论新闻组及文件

一、 提要

以前在《 Win32 OpenGL 编程( 1 Win32 下的 OpenGL 编程必须步骤 》一文中提供了一个较为完整的 Win32 下编写 OpenGL 程序的框架,但是仅仅提到的是此 Win32 框架所需要的一些东西,事实上由于 MS 为了维护自家的 DirectX ,所以很早就放弃了对 OpenGL 的支持,在 Windows XP 平台上实现的 OpenGL 还是 1.1 ( 新版的 Windows 看资料好像会好一点,但是事实上 OpenGL 最新版已经是 3.2 ) 。本文讲述的就是使用本机显卡支持的最新的 OpenGL 所需要的东西,顺便还讲了一下 GLUT ,这样基本形成一个较为完整的 Win32 下的 OpenGL 变成学习环境。由于工作很简单,所以本文会很短,最长的可能就是提要 ^^

另外,事实上参考资料 4 中的文章已经较为详细的介绍了本文所要讲的大部分内容,大家可以直接去看,写作此文的目的主要还是希望此系列完整,在后面的文章中已经有个完整可用的编程环境。顺面补上 glew glut 简单的安装使用说明。

二、 寻找缺失的 OpenGL 函数

OpenGL 是由显卡直接支持并实现的,当时在设计的时候考虑到显卡厂商可能会比操作系统 / 开发软件制造商先行一步提供新的扩展,所以有提供获取新的扩展的方法,在 Windows 下就是利用 wglGetProcAddress 函数:

PROC wglGetProcAddress(

LPCSTR lpszProc // name of the extension function

);

此函数与 GetProcAddress 功能类似,实现也类似,无非就是从动态库中通过名字直接获取到函数的地址。

FARPROC WINAPI GetProcAddress(

__in HMODULE hModule ,

__in LPCSTR lpProcName

);

因为 wglGetProcAddress 很明确的知道该从哪个 Dll 获取函数,所以省略了第一参数模块名,仅仅通过函数名就能获取到对应的函数地址,使用方法也是类似,通过函数名获取到函数地址后,通过强制转换的方式使用。此方法虽然可行,但是用到大量函数的时候比较麻烦。事实上,此方法提供的时候是作为一种补充的手段,是在显卡生厂商走在操作系统和开发工具提供商前面时的一种暂时应付手段,但是,很不幸的是, Windows 是在落后太多了。。。。。。。。

三、 Windows 下使用 OpenGL 的救星

MS 当年作为 OpenGL 的发起人之一,仅仅对 OpenGL 支持到 1.1 ,然后就退出了 OpenGL 组织,自己发展 DirectX 系统去了,我们要在 Windows 上使用 OpenGL 光靠 MS 的话,那么 OpenGL 1.1 后的所有函数都得通过上述手段来完成,那简直是让人吐血的事情 -_-!

以前似乎有关官方( SGI )的 OpenGL SDK 下载,但是现在没有那么好了, OpenGL 的官方网站已经明确说明,不再提供 SDK 下载,叫咱们自己到其他网站上找去 -_-! OpenGL.org 上的 OpenGL SDK 中的 Library 为我们提供了几个开源项目,其中有两个就是与扩展有关的。

GLee is a free cross-platform extension loading library that takes the burden off your application. GLee makes it easy to check for OpenGL extension and core version availability, automatically setting up the entry points with no effort on your part.

GLEW is an open-source cross-platform extension loading library with thread-safe support for multiple rendering contexts and automatic code generation capability. GLEW provides easy-to-use and efficient methods for checking OpenGL extensions and core functionality.

我选择了 GLEW ,这个有线程安全支持的项目,大家各取所需吧。不是开源社区的努力,要在 Windows 下使用 OpenGL 还真是让人吐血了 -_-! 说是救星也不为过。

1. glew 的安装

上面的链接地址有下载, glew 有提供 Windows 的二进制版本,使用上可以直接在工程中包含头文件,库,然后在程序的运行目录包含动态库,因为考虑到别人不一定下载了 glew ,按道理来说不论是源代码分发还是可执行文件的分发最好都是利用此方式使用。但是作为学习来说,要在每个工程中都做这么多额外的工作比较让人受不了,所以推荐讲头文件放在 windows SDK include/GL 目录下(可以通过找到 gl/gl.h 的位置找到), lib 放在 windows SDK lib 目录下,动态库放到 windows/system32 这个系统目录下,那么以后的 OpenGL 工程就不需要额外的配置了,以后文章的工程都是在这个环境下建立的。。。。要运行程序要编译代码请首先搭建好环境。。。。。真是方便了我一个,辛苦了大家了 ^^-_-!

2. glew 的使用

以后在使用 OpenGL 的时候,都请通过下述代码

#include <GL/glew.h>

#include <GL/wglew.h>

包含必要的头文件

通过

#pragma comment ( lib , "glew32.lib" )

#pragma comment ( lib , "glew32s.lib" )

然后,在初始化 OpenGL 的时候,不要忘了将 glew 初始化,可以这样:

GLenum err = glewInit ();

if (err != GLEW_OK )

{

exit (-2);

}

这样就能使用缺失的函数,就像它们原来就被操作系统支持那样,而不用自己通过 wglGetProcAddress 去获取了,说是能像原来就被操作系统支持的那样使用其实不完成正确,起码在 VS 中,由于都是通过强转后的函数指针使用, VS VA 都不能正确的解析其函数原型,使得代码编写时智能提醒函数原型的功能不能正常使用,这也算是个小瑕疵吧。。。。。。。。。

四、 为了红宝书《 OpenGL Programming Guide 》安装 glut

事实上,在《 Win32 OpenGL 编程( 1 Win32 下的 OpenGL 编程必须步骤 》中我就提到了不想使用 glut 的窗口管理系统,但是想完整的学习 OpenGL Programming Guide 要完全避过 glut 好像比较难,就算不想使用其窗口管理系统,但是一些简单易用的快捷函数要是不用,那就太麻烦了。。。。。我想画个立方体都得先去想办法才行 -_-! 茶壶那就更。。。。。无语了。这里将 glut 的安装使用顺面也讲一下吧。

glut http://www.opengl.org/resources/libraries/glut/ 上有介绍,下载页是: http://www.opengl.org/resources/libraries/glut/glut_downloads.php

也有 Windows 的二进制版本下载,安装方法同 glew, 拷贝头文件,库,动态库到相应的位置,使用方法嘛。。。见红宝书 -_-! 呵呵,其实 glut 包含了平台相关的头文件和 gl.h,glu.h ,所以在使用的时候包含 glut.h 一个文件就行了。

包含了 glut 后,基本上 Win32 OpenGL 的工程可以以下面的代码开始了:

#include <GL/glew.h>

#include <GL/wglew.h>

#include <GL/glut.h>

#pragma comment ( lib , "opengl32.lib" )

#pragma comment ( lib , "glu32.lib" )

#pragma comment ( lib , "glew32.lib" )

#pragma comment ( lib , "glew32s.lib" )

#pragma comment ( lib , "glut32.lib" )

这些都是必须的。(事实上由于glut32.lib会自动的包含OpenGL核心所需的库,包含glut32.lib时可以省略opengl32.lib和glu32.lib)

五、 完整的示例

这里提供一个使用了 glew glut 的完整示例,这个示例在上述两个库都安装完成工程配置完成的时候才能正确运行,也可以用此示例来检验安装,完整的示例从 OpenGL 编程指南》(《 OpenGL Programming Guide 》) 的示例代码 mvarray.c 改过来的。其中的宏 GL_VERSION_1_3 是由 glew 定义用来表示支持 OpenGL1.3 版本,其中的函数 glMultiDrawElementsEXT 就是 Windows 本身不支持,用了 glew 后才能使用的 OpenGL 扩展接口(首先要显卡支持啊)。 glut 的使用那就更不用说了。完整的示例在博客示例代码的 2009-9-29/TestOpenGL 目录下可以找到,下载方式见本文最后的说明。

/*

* Copyright (c) 1993-2003, Silicon Graphics, Inc.

* All Rights Reserved

*

* Permission to use, copy, modify, and distribute this software for any

* purpose and without fee is hereby granted, provided that the above

* copyright notice appear in all copies and that both the copyright

* notice and this permission notice appear in supporting documentation,

* and that the name of Silicon Graphics, Inc. not be used in

* advertising or publicity pertaining to distribution of the software

* without specific, written prior permission.

*

* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND

* WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,

* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR

* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON

* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,

* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,

* OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF

* PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD

* PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF

* THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF

* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE

* OR PERFORMANCE OF THIS SOFTWARE.

*

* US Government Users Restricted Rights

* Use, duplication, or disclosure by the Government is subject to

* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph

* (c)(1)(ii) of the Rights in Technical Data and Computer Software

* clause at DFARS 252.227-7013 and/or in similar or successor clauses

* in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights

* reserved under the copyright laws of the United States.

*

* Contractor/manufacturer is:

* Silicon Graphics, Inc.

* 1500 Crittenden Lane

* Mountain View, CA 94043

* United State of America

*

* OpenGL(R) is a registered trademark of Silicon Graphics, Inc.

*/

/*

* mvarray.c

* This program demonstrates multiple vertex arrays,

* specifically the OpenGL routine glMultiDrawElements().

*/

#include <GL/glew.h>

#include <GL/wglew.h>

#include <GL/glut.h>

#include <stdio.h>

#pragma comment ( lib , "opengl32.lib" )

#pragma comment ( lib , "glu32.lib" )

#pragma comment ( lib , "glew32.lib" )

#pragma comment ( lib , "glew32s.lib" )

#pragma comment ( lib , "glut32.lib" )

#ifdef GL_VERSION_1_3

void setupPointer (void )

{

static GLint vertices [] = {25, 25,

75, 75,

100, 125,

150, 75,

200, 175,

250, 150,

300, 125,

100, 200,

150, 250,

200, 225,

250, 300,

300, 250};

glEnableClientState (GL_VERTEX_ARRAY );

glVertexPointer (2, GL_INT , 0, vertices );

}

void init (void )

{

GLenum err = glewInit ();

if (err != GLEW_OK )

{

exit (-2);

}

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_SMOOTH );

setupPointer ();

}

void display (void )

{

static GLubyte oneIndices [] = {0, 1, 2, 3, 4, 5, 6};

static const GLubyte twoIndices [] = {1, 7, 8, 9, 10, 11};

static GLsizei count [] = {7, 6};

static const GLvoid * indices [2] = {oneIndices , twoIndices };

glClear (GL_COLOR_BUFFER_BIT );

glColor3f (1.0, 1.0, 1.0);

glMultiDrawElementsEXT (GL_LINE_STRIP , count , GL_UNSIGNED_BYTE ,

indices , 2);

// 上面的一句相当于下面的两句

//glDrawElements(GL_LINE_STRIP, count[0], GL_UNSIGNED_BYTE, oneIndices);

//glDrawElements(GL_LINE_STRIP, count[1], GL_UNSIGNED_BYTE, twoIndices);

glFlush ();

}

void reshape (int w , int h )

{

glViewport (0, 0, (GLsizei ) w , (GLsizei ) h );

glMatrixMode (GL_PROJECTION );

glLoadIdentity ();

gluOrtho2D (0.0, (GLdouble ) w , 0.0, (GLdouble ) h );

}

void keyboard (unsigned char key , int x , int y )

{

switch (key ) {

case 27:

exit (0);

break ;

}

}

int main (int argc , char ** argv )

{

glutInit (&argc , argv );

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB );

glutInitWindowSize (350, 350);

glutInitWindowPosition (100, 100);

glutCreateWindow (argv [0]);

init ();

glutDisplayFunc (display );

glutReshapeFunc (reshape );

glutKeyboardFunc (keyboard );

glutMainLoop ();

return 0;

}

#else

int main(int argc, char** argv)

{

fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0./n");

fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,/n");

fprintf (stderr, "you may be able to modify this program to make it run./n");

return 0;

}

#endif

六、 参考资料

1. OpenGL Reference Manual 》, OpenGL 参考手册

2. OpenGL 编程指南》(《 OpenGL Programming Guide 》), Dave Shreiner Mason Woo Jackie Neider Tom Davis 著,徐波译,机械工业出版社

3. MSDN ,事实上我收回 MSDN 上有完整的 OpenGL 参考的话,应该是说 MSDN 上有 OpenGL1.1 前版本的较完整资料。

4. 如何使用 OpenGL 扩展 》,曹添著 已经包含了本文的大部分内容

七、 最后说明

本文中所有代码(如果有的话)都能用 Mercurial Google Code 中下载。

文章以博文发表的日期分目录存放,下载地址为:

http://code.google.com/p/jtianling/source/checkout?repo=blog-sample-code

Mercurial 使用方法见《 分布式的,新一代版本控制系统 Mercurial 的介绍及简要入门

write by 九天雁翎 (JTianLing) -- blog.csdn.net/vagrxie

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics