代码改变世界

如何在windows配置高级OpenGL的环境

2010-12-01 16:09  bingcaihuang  阅读(813)  评论(0编辑  收藏  举报

关于如何配置高级OpenGL环境,下文是从网上扒拉下来的。

一、   提要
以前在《 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