目錄
第1章配置
配置就是將OpenGL的頭文件(*.h)、庫文件(*.lib)、動態庫文件(*.dll)復制到相應的目錄內。
如下圖所示,有三個文件夾和三個批處理文件。
圖1.1
文件夾bin用來存放*.dll文件,如:glut32.dll。注意:32位的dll文件存放在x86子目錄內;64位的dll文件存放在x64子目錄內。
文件夾inc用來存放*.h文件,如:glew.h。
文件夾lib用來存放*.lib文件,如:glut32.lib。注意:32位的lib文件存放在x86子目錄內;64位的lib文件存放在x64子目錄內。
注意:本文不考慮安騰處理器(Itanium)。
運行setup.bat,將把bin、inc、lib內的文件復制到相應的目錄內。其內容如下所示:
if defined ProgramFiles(x86) goto x64 call x86 goto :eof :x64 call x64 |
setup.bat的工作為判斷環境變量ProgramFiles(x86)是否已被定義。如果該環境變量已被定義,說明操作系統是64位的,將運行x64.bat;如果該環境變量未被定義,說明操作系統是32位的,將運行x86.bat。
x86.bat的內容如下
rem copy *.dll xcopy .\bin\x86\*.dll %windir%\System32 /Y /R
:vc6 set vcPath="%ProgramFiles%\Microsoft Visual Studio\VC98" if not exist %vcPath% goto vc2002 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2002 set vcPath="%ProgramFiles%\Microsoft Visual Studio .NET\Vc7\PlatformSDK" if not exist %vcPath% goto vc2003 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2003 set vcPath="%ProgramFiles%\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK" if not exist %vcPath% goto vc2005 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2005 set vcPath="%ProgramFiles%\Microsoft Visual Studio 8\VC\PlatformSDK" if not exist %vcPath% goto vc2008 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2008 set vcPath="%ProgramFiles%\Microsoft SDKs\Windows\v6.0A" if not exist %vcPath% goto vc2010 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2010 set vcPath="%ProgramFiles%\Microsoft SDKs\Windows\v7.0A" if not exist %vcPath% goto vc2012 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R xcopy .\lib\x64\*.lib %vcPath%\Lib\x64 /Y /R
:vc2012 set vcPath="%ProgramFiles%\Microsoft SDKs\Windows\v7.1A" if not exist %vcPath% goto vc2013 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2013 set vcPath="%ProgramFiles%\Windows Kits\8.0\Include\um\GL" if not exist %vcPath% goto vc2015 xcopy .\inc\*.h %vcPath% /Y /R xcopy .\lib\x86\*.lib "%ProgramFiles%\Windows Kits\8.0\Lib\win8\um\x86" /Y /R xcopy .\lib\x64\*.lib "%ProgramFiles%\Windows Kits\8.0\Lib\win8\um\x64" /Y /R
:vc2015 set vcPath="%ProgramFiles%\Windows Kits\8.1\Include\um\GL" if not exist %vcPath% goto vc20XX xcopy .\inc\*.h %vcPath% /Y /R xcopy .\lib\x86\*.lib "%ProgramFiles%\Windows Kits\8.1\Lib\winv6.3\um\x86" /Y /R xcopy .\lib\x64\*.lib "%ProgramFiles%\Windows Kits\8.1\Lib\winv6.3\um\x64" /Y /R
:vc20XX |
x64.bat的內容如下
rem copy *.dll xcopy .\bin\x86\*.dll %windir%\SysWOW64 /Y /R xcopy .\bin\x64\*.dll %windir%\System32 /Y /R
:vc6 set vcPath="%ProgramFiles(x86)%\Microsoft Visual Studio\VC98" if not exist %vcPath% goto vc2002 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2002 set vcPath="%ProgramFiles(x86)%\Microsoft Visual Studio .NET\Vc7\PlatformSDK" if not exist %vcPath% goto vc2003 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2003 set vcPath="%ProgramFiles(x86)%\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK" if not exist %vcPath% goto vc2005 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2005 set vcPath="%ProgramFiles(x86)%\Microsoft Visual Studio 8\VC\PlatformSDK" if not exist %vcPath% goto vc2008 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2008 set vcPath="%ProgramFiles%\Microsoft SDKs\Windows\v6.0A" if not exist %vcPath% goto vc2010 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R xcopy .\lib\x64\*.lib %vcPath%\Lib\x64 /Y /R
:vc2010 set vcPath="%ProgramFiles(x86)%\Microsoft SDKs\Windows\v7.0A" if not exist %vcPath% goto vc2012 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R xcopy .\lib\x64\*.lib %vcPath%\Lib\x64 /Y /R
:vc2012 set vcPath="%ProgramFiles(x86)%\Microsoft SDKs\Windows\v7.1A" if not exist %vcPath% goto vc2013 xcopy .\inc\*.h %vcPath%\Include\GL /Y /R xcopy .\lib\x86\*.lib %vcPath%\Lib /Y /R
:vc2013 set vcPath="%ProgramFiles(x86)%\Windows Kits\8.0\Include\um\GL" if not exist %vcPath% goto vc2015 xcopy .\inc\*.h %vcPath% /Y /R xcopy .\lib\x86\*.lib "%ProgramFiles(x86)%\Windows Kits\8.0\Lib\win8\um\x86" /Y /R xcopy .\lib\x64\*.lib "%ProgramFiles(x86)%\Windows Kits\8.0\Lib\win8\um\x64" /Y /R
:vc2015 set vcPath="%ProgramFiles(x86)%\Windows Kits\8.1\Include\um\GL" if not exist %vcPath% goto vc20XX xcopy .\inc\*.h %vcPath% /Y /R xcopy .\lib\x86\*.lib "%ProgramFiles(x86)%\Windows Kits\8.1\Lib\winv6.3\um\x86" /Y /R xcopy .\lib\x64\*.lib "%ProgramFiles(x86)%\Windows Kits\8.1\Lib\winv6.3\um\x64" /Y /R
:vc20XX |
注意:x64.bat 中vc2008是比較特殊的:它的目標目錄是%ProgramFiles%,而不是%ProgramFiles(x86)%;
第2章核心文件
2.1 核心文件
核心文件有6個,如下表所示:
頭文件 |
庫文件 |
動態庫文件 |
gl.h |
opengl32.lib |
opengl32.dll |
glu.h |
glu32.lib |
glu32.dll |
以gl開頭的OpenGL函數,一般都被封裝在opengl32.dll內。編程時,需要包含gl.h,編譯時需要鏈接opengl32.lib。
以glu開頭的OpenGL函數,一般都被封裝在glu32.dll內。編程時,需要包含glu.h,編譯時需要鏈接glu32.lib。
vc6至vc2015自帶gl.h、glu.h、opengl32.lib、glu32.lib這四個文件。其中的lib文件還分為x86、x64、IA64(Itanium)三個版本。
Windows系統自帶opengl32.dll和glu32.dll。這兩個文件的使用,下文會進行說明。
注意:VC++自帶的*.h、*.lib,其版本為1.1;Windows自帶的*.dll,其版本從1.1到4.X(應該與顯卡驅動有關)。要使用OpenGL 1.2 至 4.X 新增的函數,需要另行處理,詳見下文。
2.2 編譯時使用核心文件
編譯時核心文件的使用請參考如下面代碼:
#include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.lib") |
即包含頭文件gl.h和glu.h,鏈接時使用opengl32.lib和glu32.lib。
注意:網上下載的壓縮包內有時能夠發現這些文件:opengl.lib、opengl.dll、glu.lib、glu.dll,它們與opengl32.lib、opengl32.dll、glu32.lib、glu32.dll的區別為:前者是SGI實現的OpenGL,后者是微軟實現的OpenGL。
2.3 運行時使用核心文件
編譯生成的.exe文件,在運行時需要opengl32.dll和glu32.dll這兩個文件。
這兩個文件Windows系統自帶。32位操作系統下,它們位於%windir%\System32目錄下,即一般位於C:\Windows\System32。64位操作系統下,32位程序與64位程序所需要的opengl32.dll、glu32.dll分為兩套:64位的dll文件位於%windir%\System32;32位的dll文件位於%windir%\SysWOW64。
2.4 依賴關系
opengl32.dll和glu32.dll在運行時是相互依賴的,即opengl32.dll導入了glu32.dll內部的一些函數,glu32.dll也導入了opengl32.dll內部的一些函數。如下圖所示:
圖2.1
第3章 AUX
首先需要說明的是:AUX是OpenGL 1.0使用的輔助庫,它已經過時。新編寫的OpenGL程序里最好不要再使用它。
3.1 AUX的作用
直接使用gl和glu編寫OpenGL程序,是一件比較繁瑣的工作。以NeHe OpenGL教程第一課的代碼為例,什么都沒有繪制的代碼量就將近四百行了。
AUX輔助庫的作用就是為了簡化OpenGL的編碼。
3.2 相關文件
AUX相關文件有兩個:glaux.h、glaux.lib。其中glaux.lib是靜態庫,所以運行時不再需要glaux.dll。
vc6至vc2005自帶這兩個文件,vc2008后不再自帶。vc2008~vc2015要使用AUX,可將glaux.h、glaux.lib從vc6的安裝目錄復制到vc2008~vc2015的安裝目錄下。
3.3 使用AUX
下面是使用AUX的示例代碼。它只有二十行左右,大大簡化了編碼。
#include <windows.h> #include <GL/gl.h> #pragma comment(lib,"OpenGL32.lib") #include <GL/glaux.h> #pragma comment(lib,"glaux.lib") int main(int argc, char** argv) { auxInitDisplayMode (AUX_SINGLE | AUX_RGB); auxInitPosition (0, 0, 500, 500); auxInitWindow (argv[0]); glBegin(GL_LINE_STRIP); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glEnd(); glFlush(); Sleep(10000); return 0; } |
第4章 GLUT
4.1 GLUT的作用
從OpenGL 1.1開始,出現了GLUT(OpenGL Utility Tookit)。它與AUX的作用類似,也是為了簡化OpenGL編碼。此外,由它編寫的代碼還能夠實現跨平台。
可以將GLUT看做是AUX的升級版。
4.2 相關文件
GLUT相關文件有三個:glut.h、glut32.lib、glut32.dll。
VC++和Windows系統不自帶這些文件,需要下載。網址為:
http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip
解壓后,將glut.h復制到圖1.1中的inc目錄;將glut32.lib復制到圖1.1中的lib\x86目錄;將glut32.dll復制到圖1.1中的bin\x86目錄。然后運行setup.bat,復制文件到相應的目錄內。
4.3 使用GLUT
使用GLUT非常簡單,只要包含glut.h頭文件即可,即:
#include <GL/glut.h> |
如下內容節選自glut.h
#include <windows.h> #include <GL/gl.h> #include <GL/glu.h>
#ifdef GLUT_USE_SGI_OPENGL #pragma comment (lib, "opengl.lib") #pragma comment (lib, "glu.lib") #pragma comment (lib, "glut.lib") #else #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.lib") #pragma comment (lib, "glut32.lib") #endif |
可見:
1、自動包含gl.h和glu.h;
2、自動鏈接opengl32.lib、glu32.lib、glut32.lib。
4.4 編譯GLUT
glutdlls37beta.zip里沒有64位的glut32.lib、glut32.dll。此時有兩種解決方案:一是下載64位的glut32.lib、glut32.dll;二是下載GLUT的源代碼(如:glut-3.7.6-src.zip),然后重新編譯一遍。
有了源代碼,還可以編譯生成靜態庫,這樣在運行程序時就不再需要glut32.dll了。
4.5 替代產品
GLUT也是一款較老的產品,它的源代碼早已不再更新。如果想編譯GLUT,又找不到源代碼,就可以使用一些替代產品,如:Freeglut。
Freeglut的下載地址如下:
http://sourceforge.net/projects/freeglut/files/
第5章 GLEXT
首先需要說明的是:GLEXT已經過時,可用GLEW代替它。
5.1 GLEXT的作用
上文提到:VC++自帶的*.h、*.lib,其版本為1.1;Windows自帶的*.dll,其版本從1.1到4.X。這就產生一個問題:OpenGL32.dll里可能有某些函數(如:glTexImage3D),在gl.h和OpenGL32.lib里沒有相應的聲明,導致程序無法使用這些函數。
GLEXT就是用來擴展gl.h和OpenGL32.lib的,經過擴展后就可以使用OpenGL32.dll里的高版本函數了。
5.2 相關文件
GLEXT的相關文件:glcorearb.h、glext.h、wglext.h、glext.lib、glext.dll。
glcorearb.h似乎沒有什么用處。glext.h里包含了以gl開頭的函數聲明,這些函數都是gl.h里所沒有聲明的函數,也就是從 OpenGL 1.2 開始逐步增加的函數。wglext.h里包含了以wgl開頭的函數聲明,這些函數只能在Windows平台上使用。
VC++和Windows系統不自帶這些文件,需要下載。網址為:
http://sourceforge.net/projects/glextwin32/files/
下載glext.zip,解壓后將glext.h、wglext.h復制到圖1.1中的inc目錄;將glext.lib復制到圖1.1中的lib\x86目錄;將glext.dll復制到圖1.1中的bin\x86目錄。然后運行setup.bat,復制文件到相應的目錄內。
如果想自己編譯生成glext.lib、glext.dll,可在上述網址下載glext_src.zip。
5.3 使用GLEXT
下面以使用OpenGL 1.2里的函數glTexImage3D為例,說明如何使用GLEXT。一共有兩種方法。
5.3.1 使用wglGetProcAddress
參考如下代碼:
#include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.lib") #include <GL/glext.h> #pragma comment(lib,"glext.lib")
void init(void) { PFNGLTEXIMAGE3DPROC pfn = (PFNGLTEXIMAGE3DPROC)wglGetProcAddress("glTexImage3D"); if(pfn) { (*pfn)(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight ,iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image); } } |
語句(PFNGLTEXIMAGE3DPROC)wglGetProcAddress("glTexImage3D")從OpenGL32.dll里找到函數glTexImage3D的地址,將其強制轉換為PFNGLTEXIMAGE3DPROC型的函數指針。接下來的(*pfn)(...);相當於調用glTexImage3D。
5.3.2 使用glext.dll導出函數
參考如下代碼:
#include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.lib") #define GL_GLEXT_PROTOTYPES #include <GL/glext.h> #pragma comment(lib,"glext.lib")
void init(void) { glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight, iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image); } |
首先,它多了一條語句#define GL_GLEXT_PROTOTYPES。這樣的話,glext.h里就有了函數glTexImage3D的聲明。
代碼glTexImage3D(...);會調用glext.dll的導出函數glTexImage3D。后者會在OpenGL32.dll里找到函數glTexImage3D,並執行該函數。
這種方法比使用wglGetProcAddress方便些,但是其效率估計會低一些。而且,編譯生成glext.dll時,使用的是C++編譯器,導致只有C++程序才能鏈接glext.lib。解決辦法就是下載glext_src.zip,將.cpp文件的擴展名更改為.c,然后重新編譯一遍。
第6章 GLEW
GLEW(The OpenGL Extension Wrangler Library)與GLEXT的功能相似。
6.1 相關文件
GLEW的相關文件如下:
glew.h GLEW頭文件。函數名以glew開頭
wglew.h GLEW針對Windows平台的頭文件。函數名以wglew開頭
glxew.h GLEW針對Linex平台的頭文件
glew32s.lib 靜態庫
glew32.lib 鏈接glew32.dll的庫文件
glew32.dll 動態庫文件
VC++和Windows系統不自帶這些文件,需要下載。網址為:
http://sourceforge.net/projects/glew/files
以目前的最新版1.13.0為例,有三個文件
glew-1.13.0-win32.zip Windows平台下編譯的結果文件(不含源代碼)
glew-1.13.0.zip 源代碼(Windows)
glew-1.13.0.tgz 源代碼
glew-1.13.0.zip與glew-1.13.0.tgz的區別僅僅在於:前者文本文件的行結束符為\r\n;后者文本文件的行結束符為\n(為蘋果電腦准備的?)。
解壓glew-1.13.0-win32.zip后,將相關文件復制到圖1.1中的三個目錄內。然后運行setup.bat。注意區分32位和64位的.lib和.dll文件。還要注意mx(multi context)版本的文件(*mx.lib和*mx.dll)它們用於多窗口多線程顯示。
6.2 使用GLEW
下面以使用OpenGL 1.2里的函數glTexImage3D為例,說明如何使用GLEW。參考如下代碼:
#include <GL/glew.h> #pragma comment(lib,"glew32.lib") #include <GL/glut.h>
void init(void) { ... ... ... glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight, iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image); ... ... ... }
int main(int argc, char** argv) { ... ... ... glutCreateWindow(argv[0]); glewInit(); ... ... ... return 0; } |
說明:
1、#include <GL/glew.h> 必須在 #include <GL/gl.h> 的前面;
2、#pragma comment(lib,"glew32.lib")將自動鏈接glew32.lib;
3、需要在創建窗口(glutCreateWindow)后調用函數glewInit。