当大家都用上Windows7甚至Windows8的时候,我还是在用着Windows XP,大概比较习惯经典怀旧吧~~
言归正传,这也带来了一些麻烦,譬如搭建WindowsVS2010时,就必须要升级到SP3
1. 升级Windows XP SP3
可以在官网直接下载,也可以直接下载一个安装
过程漫长,最好可以在中间备份一下自己的系统,以防万一
2. 缺少的OpenGL函数(此段没有兴趣的可以直接跳过)
实际上MS虽然作为第一代OpenGL标准的发起者,但是为了维护自家开发的DirectX,在XP上的只支持到OpenGL1.1,而现在的OpenGL标准已经到了4.0以上。
因此就给我们搭建环境造成了很大的麻烦~
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是在落后太多了。。。。。。。。
3. 安装和使用Glew
3.1 glew的安装
glew有提供Windows的二进制版本,使用上可以直接在工程中包含头文件,库,然后在程序的运行目录包含动态库,因为考虑到别人不一定下载了glew,按道理来说不论是源代码分发还是可执行文件的分发最好都是利用此方式使用。但是作为学习来说,要在每个工程中都做这么多额外的工作比较让人受不了,所以推荐讲头文件放在windows SDK的include/GL目录下(可以通过找到gl/gl.h的位置找到),lib放在windows SDK的lib目录下,动态库放到windows/system32这个系统目录下,那么以后的OpenGL工程就不需要额外的配置了,以后文章的工程都是在这个环境下建立的。。。。要运行程序要编译代码请首先搭建好环境。。。。。真是方便了我一个,辛苦了大家了^^-_-!
3. 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都不能正确的解析其函数原型,使得代码编写时智能提醒函数原型的功能不能正常使用,这也算是个小瑕疵吧。。。。。。。。。
4. Glut的安装和下载
事实上,在《 Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤》中我就提到了不想使用glut的窗口管理系统,但是想完整的学习《OpenGL Programming Guide》要完全避过glut好像比较难,就算不想使用其窗口管理系统,但是一些简单易用的快捷函数要是不用,那就太麻烦了。。。。。我想画个立方体都得先去想办法才行-_-!茶壶那就更。。。。。无语了。这里将glut的安装使用顺面也讲一下吧。
以我的安装目录为例:
(1)“d:\Program Files\Microsoft Visual Studio\VC98\include\GL文件夹”。把解压得到的glut.h放到这个GL文件夹里。没有GL文件夹可以自己建一个,一般都有的。
(2)“d:\Program Files\Microsoft Visual Studio\VC98\lib文件夹”。把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹,即lib文件夹。
(3)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)这是非常重要的动态链接库设置!
包含了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)
5. 完整的示例
这里提供一个使用了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 ADVISEDOF
* 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 whichis not in OpenGL Version 1.0.\n");
fprintf (stderr, "If your implementation of OpenGL Version1.0 has the right extensions,\n");
fprintf (stderr, "you may be able to modify this program tomake it run.\n");
return 0;
}
#endif
6. 参考资料
如何在windows配置高级OpenGL的环境