天天看點

一篇好文章——《OpenGL發展曆程》

    自己使用OpenGL已經有一段時間了,當時發現了一些小問題,由于不太重要,同時也沒有使用,是以就沒有深究。但是最近看到一篇寫的不錯的文章,把我當時發現的小問題都給解決了。

    下面轉過來,同時把一些重點給畫出,友善大家解決問題。

在計算機發展初期,人們就開始從事計算機圖形的開發,但直到20世紀80年代末、90年代初,三維圖形才開始迅速發展。于是各種三維圖形工具軟體包相繼推出,如GL,RenderMan等。随着計算機技術的迅速發展,GL已經進一步發展成為OpenGL,現在OpenGL被認為是高性能圖形和互動式視景處理的标準。這些三維圖形工具軟體包有些側重于使用友善,有些側重于繪制效果或與應用軟體的連接配接,但沒有一種軟體包能在互動式三維圖形模組化能力和程式設計友善程度上與OpenGL相比拟。

OpenGL(即開放性圖形庫Open Graphics Library),是一個三維的計算機圖形和模型庫,最初是美國SGI公司為圖形工作站開發的一種功能強大的三維圖形機制(或者說是一種圖形标準)。它源于SGI公司為其圖形工作站開發的IRIS GL,在跨平台移植過程中發展成為OpenGL。SGI在1992年7月釋出1.0版,後成為工業标準,由成立于1992年的獨立财團OpenGL Architecture Review Board (ARB)控制。SGI等ARB成員以投票方式産生标準,并制成規範文檔(Specification)公布,各軟硬體廠商據此開發自己系統上的實作。隻有通過了ARB規範全部測試的實作才能稱為OpenGL。1995年12月ARB準許了1.1版本,最新版規範是 2006 年 8 月 2 日 通過的opengl2.1,是自1.0版本後的第七次版本。新版本适應以往早期的版本,也就是2.0, 1.5, 1.4, 1.3, 1.2, 1.1, or 1.0 GL不要任何改變就能在新版本下運作。

OpenGL被設計成獨立于硬體,獨立于視窗系統,在運作各種作業系統的各種計算機上都可用,并能在網絡環境下以客戶/伺服器模式工作,是專業圖形處理、科學計算等高端應用領域的标準圖形庫。它低端應用上的主要競争對手是MS-Direct3D,該圖形庫是以COM接口形式提供的,是以極為複雜,穩定性差,另外微軟公司擁有該庫版權,目前隻在Windows平台上可用。Direct3D的優勢在速度上,但現在低價顯示卡都能提供很好的OpenGL硬體加速,是以做3D圖形開發使用Direct3D已沒有特别的必要,在專業圖形處理特别是高端應用方面目前還沒有出現以Direct3D技術為基礎的例子,而遊戲等低端應用也有轉向OpenGL的趨勢。

微軟在Windows NT對OpenGL的支援始于3.51,在Windows9x中的支援始于Win95 OEM Service Release 2。Windows下常用的OpenGL庫有兩種,MS實作的和SGI實作的,MS-OpenGL調用會自動檢測是否存在顯示卡制造商提供的ICD(Installable Client DeviceDriver)驅動程式,有則調用ICD中的例程,否則使用CPU進行計算,是以能利用顯示卡的OpenGL加速能力。對開發者來說使用方法并沒有差別,隻是有ICD驅動時更快些。SGI的版本是純軟體實作,不能利用硬體加速并且SGI已經在1999年宣布停止支援,但這套圖形庫便于調試程式,仍有不少開發者使用。

1999年SGI宣布與MS合作開發Ferihant,即Windows的下一代圖形處理體系,包括DirectX與OpenGL的低級圖形處理接口和以場景圖支援為特點的進階接口,并且就此停止對其在Windows下的OpenGL實作的支援以示決心。此舉令世人矚目,大家都以為Windows圖形處理快要過上幸福生活了,然而,不久,SGI宣布中止合作,并撤回派出的科學家,Ferihant基本上夭折。SGI 稱終止合作的原因是MS不肯積極合作,光想把SGI 的技術合并進DirectX,但是真正内幕不詳。不過以SGI在圖形處理界的老大地位來說,還是有幾分可信度的,因為MS最初支援OpenGL就不積極。

OpenGL可以運作在目前各種流行作業系統之上,如Mac OS、Unix、Windows 95/98、Windows NT/2000、Linux、OPENStep、Python、BeOS等。各種流行的程式設計語言都可以調用OpenGL中的庫函數,如C、C++、Fortran、Ada、Java。OpenGL完全獨立于各種網絡協定和網絡拓撲結構。目前,Microsoft公司、SGI公司、ATT公司的Unix軟體實驗室、IBM公司、DEC公司、SUN公司、HP公司等幾家在計算機市場占主導地位的大公司都采用了OpenGL圖形标準。值得一提的是,由于Microsoft公司在Windows NT和Windows 95/98中提供OpenGL标準,使得OpenGL在微機中得到了廣泛應用。尤其是在OpenGL三維圖形加速卡和微機圖形工作站推出後,人們可以在微機上實作CAD設計、仿真模拟、三維遊戲等,進而使得應用OpenGL及其應用軟體來建立三維圖形變得更有機會、更為友善。

OpenGL作為一個性能優越的圖形應用程式設計界面(API),适用于廣泛的計算機環境。從個人計算機到工作站和超級計算機,OpenGL都能實作高性能的三維圖形功能。由于許多在計算機界具有上司地位的計算機公司紛紛采用OpenGL作為三維圖形應用程式設計界面,是以OpenGL應用程式具有廣泛的移植性。是以,OpenGL已成為目前的三維圖形開發标準,是從事三維圖形開發工作的技術人員所必須掌握的開發工具。OpenGL應用領域十分寬廣,如軍事、電視廣播、CAD/CAM/CAE、娛樂、藝術造型、醫療影像、虛拟世界等。

1.1 opengl1.1

1995年,SGI推出了更為完善的OpenGL 1.1版本。OpenGL 1.1的性能比1.0版提高甚多。其中包括改進列印機支援,在增強元檔案中包含OpenGL的調用,頂點數組的新特性,提高頂點位置、法線、顔色、色彩指數、紋理坐标、多邊形邊緣辨別的傳輸速度,引入了新的紋理特性等等。

1.2 opengl1.3

2001年8月,ARB釋出OpenGL 1.3規範,它增加了立方紋理貼圖、紋理環境、多重采樣、紋理架構壓縮等擴充指令,但是改程序度非常有限。

1.3 opengl1.4

2002年7月,ARB正式釋出OpenGL 1.4,它也隻加入了深度紋理/陰影紋理、頂點設計架構、自動紋理貼圖等簡單的功能。

1.3 opengl1.5

2003年的7月,ARB公布OpenGL 1.5規範。OpenGL 1.5内包含ARB制定的“正式擴充規格繪制語言”(OpenGL Shading Language v1.0),該語言用于着色對象、頂點着色、片斷着色等擴充功能,同時也将作為下一代OpenGL 2.0版本的核心。OpenGL 1.5的變化還增加了頂點緩沖對象(可提高透視性能)、非乘方紋理(可提高紋理記憶體的使用效率)以及陰影功能、隐蔽查詢功能等等。其主要内容包括

l 頂點Buffer Object:進行頂點配列方式可以提高透視性能

l Shadow功能:增加用來比較Shadow映射的函數

l 隐蔽查詢(QUERY):為提高Curling性能采用非同步隐蔽測試

l 非乘方紋理(Texture):提高mipmap等紋理記憶體的使用效率

l OpenGL Shading Language v.1.0:用于着色(shader)對象、頂點着色以及片斷着色技術(fragment shader )的擴充功能

1.4 opengl2.0

OpenGL 1.0推出後的相當長的一段時間裡,OpenGL唯一做的隻是增加了一些擴充指令集,這些擴充指令是一些繪圖功能,像是ClearCoat、Multisample、視訊及繪圖的整合工具(某些是通過OpenML的努力而開發出來的,它本身屬于OpenGL ARB擴充指令之一。

   OpenGL 2.0将在OpenGL 1.3基礎上進行修改擴充、但它将有下面五個方面的重大改進:①複雜的核心被徹底精簡;②完全的硬體可程式設計能力;③改進的記憶體管理機制、支援進階像素處理;④擴充至數字媒體領域,使之跨越高端圖形和多媒體範疇;⑤支援嵌入式圖形應用。

    為了在獲得強大功能的同時保持理想的相容性,OpenGL 2.0經曆以下兩個發展階段:第一個階段注重相容能力和平滑過渡,為此,OpenGL 2.0核心将在精簡後的OpenGL 1.3功能子產品的基礎上加上可完全相容的新功能共同組成,這種做法在滿足相容性的同時,還可将原有OpenGL中數量衆多、且互相糾纏不清的擴充指令進行徹底精簡。 第一階段的任務隻是為了過渡,而第二階段才是OpenGL 2.0的真正成熟期。此時,ARB将合成出一個“純OpenGL 2.0” 核心,純核心将包含更多新增加的“精簡型API函數”,這些函數具有完全的可程式設計特性、結構簡單高效、功能強大且應用靈活。除了完成這項任務外,ARB組織還得指導開發商抛棄繁瑣的OpenGL 1.X、轉用更具彈性的“純OpenGL 2.0” 。

1.5 opengl2.1

OpenGL version 2.1在 2006 年 8 月 2 日 釋出,是最初版本1.0後的第七個版本。盡管增加了版本的層析,支援高層析的程式設計shaders,但版本能夠适于早期的版本,意味着運作2.0, 1.5, 1.4, 1.3, 1.2, 1.1, or 1.0 GL的程式不用任何改變就可運作。

OpenGL2.1與目前的2.0版本相比,雖然版本号變更不如DX9到DX10那麼巨大,但它卻增加了多項實用的技術和功能,例如向後相容增強型OpenGL的先進管道規劃,其中包括:優化GPU和顯存之間并行工作時間,提高象素緩沖和對象的象素和質感快速緩沖使用率;增加标準彩色圖像質感sRGB色彩空間應用促進管理的靈活性;并增加了許多新的shader彈性調配,包括非平方矩陣支援,支援陣列流對象和碎塊點位置時,幹擾和shaders屬性不變的變量shader代碼提高可靠性。1. GLSL更新至1.2版;2. 支援非正方形的矩陣. UniformMatrix {2x3,3x2,2x4,4x2,3x4,4x3}fv ;3. 象素緩沖對象(Pixel Buffer Object).  它擴充了緩沖對象的接口.現在緩沖區對象可以支援頂點數組和象素資料了.象素緩沖對象能加速在GPU記憶體中進行的緩沖區之間的資料拷貝及其他象素操作.;4. sRGB紋理. 遵循IEC 6 1966-2-1 .标準的sRGB顔色空間的紋理格式(包括壓縮和非壓縮格式).(OpenGL 2.1 adds backwards compatible enhancements to OpenGL's advanced programmable pipeline including: Pixel Buffer Objects for fast texture and pixel copies between frame buffer and buffer objects in GPU memory; texture images specified in standard sRGB color space for enhanced application color management flexibility; and numerous additions to increase the flexibility of shader programming including non-square matrix support, support for arrays as first-class objects, a fragment position query in shaders using Point Sprites and an invariant attribute for variables to enhance shader code reliability.)

OpenGL2.1的效果

一篇好文章——《OpenGL發展曆程》
一篇好文章——《OpenGL發展曆程》
一篇好文章——《OpenGL發展曆程》

2 OpenGL擴充(OpenGL Extensions)

OpenGL和Direct3D比較起來,最大的一個長處就是其擴充機制。硬體廠商開發出一個新功能,可以針對新功能開發OpenGL擴充,軟體開發人員通過這個擴充就可以使用新的硬體功能。是以雖然顯示卡的發展速度比OpenGL版本更新速度快得多,但程式員仍然可以通過OpenGL使用最新的硬體功能。而Direct3D則沒有擴充機制,硬體的新功能要等到微軟釋出新版DirectX後才可能支援。

OpenGL擴充也不是沒有缺點,正因為各個硬體廠商都可以開發自己的擴充,是以擴充的數目比較大,而且有點混亂,有些擴充實作的相同的功能,可因為是不同廠商開發的,接口卻不一樣,是以程式中為了實作這個功能,往往要為不同的顯示卡寫不同的程式。這個問題在OpenGL 2.0出來後可能會得到解決,OpenGL 2.0的一個目标就是統一擴充,減少擴充數目。

2.1 擴充名

每個擴充都有一個擴充名,擴充名類似如下形式:

GL_ARB_multitexture

第一段GL,用來表示針對OpenGL哪部分開發的擴充,有以下幾個值:

GL – 針對OpenGL核心的擴充

WGL – 針對Windows平台的擴充

GLX – 針對Unix / Linux平台的擴充

GLU – 針對OpenGL Utility Library的擴充

第二段ARB,用來表示是誰開發的這個擴充,常見以下幾個值:

ARB – 經OpenGL Architecture Review Board(OpenGL管理機構)正式核準的擴充,往往由廠商開發的擴充發展而來,如果同時存在廠商開發的擴充和ARB擴充,應該優先使用ARB擴充

EXT – 被多個硬體廠商支援的擴充

NV – nVIDIA 公司開發的擴充

ATI – ATI公司開發的擴充

ATIX– ATI公司開發的實驗性擴充

SGI – Silicon Graphics(SGI)公司開發的擴充

SGIX– Silicon Graphics(SGI)公司開發的實驗性擴充

第三段multitexture就是真正的擴充名了,如multitexture就是多重紋理擴充。

2.2使用OpenGL擴充

要使用一個OpenGL擴充,首先必須檢查顯示卡是否支援這個擴充,以下代碼可以擷取一個顯示卡支援的的OpenGL擴充:

const char *str = glGetString( GL_EXTENSIONS );

函數傳回一個字元串指針,這個字元串就是顯示卡所支援的所有擴充的擴充名,不同的擴充名之間用空格隔開,形如:

"GL_ARB_imaging GL_ARB_multitexture GL_ARB_point_parameters ……"

OpenGL擴充往往都會新增一些函數,在Windows平台上,這些函數不是通過.lib庫連接配接到程式裡的,而要在運作時動态獲得函數的指針。我們以GL_ARB_point_parameters擴充為例看看怎麼獲得函數指針。

首先要定義函數指針類型,

typedef void (APIENTRY * PFNGLPOINTPARAMETERFARBPROC)(GLenum pname,

GLfloat param);

typedef void (APIENTRY * PFNGLPOINTPARAMETERFVARBPROC)(GLenum pname,

const GLfloat *params);

這個工作SGI已經為我們做好,它提供了一個頭檔案 glext.h ,裡面有目前絕大多數擴充的常量和函數指針定義,下載下傳下來放到編譯器的include/GL檔案夾下面,然後在程式裡面加上:

#include <GL/glext.h>

就可以在程式中使用常量和函數指針類型了。

然後要定義函數指針:

PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;

PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;

再檢查顯示卡是否支援GL_ARB_point_parameters擴充,其中isExtensionSupported是自定義的一個函數,就是在glGetString( GL_EXTENSIONS )傳回的字元串裡查找是否存在指定的擴充名:

int hasPointParams = isExtensionSupported("GL_ARB_point_parameters");

如果支援,就可以用wglGetProcAddress函數擷取擴充函數的指針:

if (hasPointParams)

{

glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)/

wglGetProcAddress( "glPointParameterfEXT" );

glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) /

wglGetProcAddress( "glPointParameterfvEXT" );

}

最後就可以在程式裡使用擴充函數:

if (hasPointParams)

{

static GLfloat quadratic[3] = { 0.25, 0.0, 1/60.0 };

glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, quadratic);

glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0);

}

另外,下面代碼說明如何通路擴充函數:(資料來源于csdn知識庫)

調用wglGetProcAddress函數通路一個不在标準OpenGL庫中的擴充函數。如果該擴充函數存在目前的執行(implementation)中,那麼wglGetProcAddress傳回一個用來通路該函數的函數指針。否則,wglGetProcAddress傳回NULL.

例如,要通路glAddSwapHintRectWIN擴充函數,如下調用wglGetProcAddress:

// Get a pointer to the extension function.

typedef void (WINAPI *FNSWAPHINT)(GLint, GLint, GLsizei, GLsizei);

fnSwapHint = (FNSWAPHINT)wglGetProcAddress("glAddSwapHintRectWIN");

// Actual call to glAddSwapHintRectWIN.

if (fnSwapHint != NULL)

(*fnSwapHint)(0, 0, 100, 100);

2.3 WGL擴充

glGetString( GL_EXTENSIONS )取得的擴充字元串中并不包括針對Windows平台的WGL擴充,WGL擴充串要通過WGL_ARB_extensions_string擴充來獲得,以下代碼示範了如何獲得WGL擴充串:

定義WGL_ARB_extensions_string擴充新增函數wglGetExtensionsStringARB的函數指針類型,同樣這個工作SGI已經為我們做好,隻不過不在glext.h中,而在它提供的另外一個頭檔案 wglext.h 中:

typedef const char *(APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC)(

HDC hdc);

定義函數指針:

PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;

檢查是否支援WGL_ARB_extensions_string擴充,如果不支援,表示這個顯示卡不支援WGL擴充,如果支援,則得到wglGetExtensionsStringARB函數的指針,并調用它得到WGL擴充串:

int hasWGLext = isExtensionSupported("WGL_ARB_extensions_string");

if (hasWGLext)

{

wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) /

wglGetProcAddress( "wglGetExtensionsStringARB" );

const char *wglExt = wglGetExtensionsStringARB( hdc );

……

}

2.4 OpenGL版本

一些常用的OpenGL擴充會在新版的OpenGL中加到OpenGL核心中去,成為OpenGL标準的一部分,可以簡化程式開發,程式員使用這些功能時不必做繁瑣的擴充初始化工作。比如多重紋理功能,在OpenGL 1.2.1 加入到OpenGL核心中,以前要使用多重紋理,要先檢查是否支援GL_ARB_multitexture擴充,然後初始化glActiveTextureARB等函數,很麻煩,而OpenGL1.2後,則可以直接使用glActiveTexture函數。

不過,這種簡化隻有Mac/Unix/Linux程式員才能享受到,在Windows平台上沒有這麼簡單。微軟為了維護Direct3D,對OpenGL的支援很消極,其OpenGL實作仍然是1.1。由于Windows上的OpenGL程式最終都會動态連結到微軟的OpenGL32.dll,可OpenGL32.dll隻支援OpenGL 1.1,使我們不能直接使用新版OpenGL,仍然要用擴充通路OpenGL1.1以來新增的功能。

2.5 OpenGL擴充資料

All About OpenGL Extensions :必讀。

讨論OpenGL擴充機制,講述了如何閱讀擴充官方說明書,并舉了一些擴充的例子。

OpenGL Extension Registry :

由SGI維護,列出了目前公開的所有擴充及其官方說明書。

OpenGL Hardware Registry : 由Delphi3D.net維護,列出了目前幾乎所有3D加速卡的OpenGL硬體資訊,包括其支援的擴充。當然,這裡面列的擴充不能作為程式的依據,程式中要使用某個擴充,還是要先檢查顯示卡是否支援。因為同樣的顯示卡,如果驅動程式不同,支援的擴充也不相同,往往新的驅動程式會加入新的擴充,丢掉一些廢棄的擴充。

2.6 OpenGL硬體加速

在Windows平台上,OpenGL驅動可能有三種模式:純軟體、MCD和ICD:

純軟體模式:微軟提供一個OpenGL的軟體實作,所有渲染操作均由CPU完成,速度很慢。如果安裝系統時使用Windows自帶的顯示卡驅動程式,那麼OpenGL程式就會運作在軟體模式下。而且由于微軟有自己的Direct3D,是以對OpenGL的支援很消極,它的OpenGL純軟體實作隻支援OpenGL1.1,而目前OpenGL的最新版本為1.4

MCD(Mini Client Driver):MCD是早期微軟在Windows NT上支援OpenGL時,為了簡化驅動開發時使用的一個模型。在這個模型中,OpenGL渲染管線的變換、光照部分仍然由軟體實作,而光栅化部分則由硬體廠商實作,是以隻要硬體支援,MCD可以硬體加速光栅化部分。MCD雖然可以簡化驅動開發,但是功能限制太大,現在市面上的3D加速卡均支援硬體變換和光照,MCD卻不能利用這一特性,看上去MCD已經沒有存在的價值

ICD(Installable Client Driver):ICD是一個完整的OpenGL驅動模型,比MCD複雜得多。硬體廠商要實作完整的OpenGL渲染管線,如變換、光照、光栅化等,是以隻要硬體支援,ICD可以硬體加速整個OpenGL渲染管線。我們通常說的OpenGL硬體加速就是指的通過ICD模型獲得的硬體加速,而現在硬體廠商提供的OpenGL驅動程式也都是依照ICD模型開發的。主要硬體廠商的ICD已經可以支援OpenGL的最新版1.4

Windows怎麼實作OpenGL硬體加速呢?OpenGL32.dll是微軟的OpenGL 1.1純軟體實作,我們的程式都要動态連結到這個dll。如果安裝3D晶片廠商的驅動程式,會将一個不同名字的dll放到Windows系統目錄下,比如在Windows 2000下安裝nVIDIA GeForce2 MX的驅動程式,會在系統目錄下放一個nvoglnt.dll(這就是nVIDIA的OpenGL驅動),并在系統資料庫中登記nvoglnt.dll,讓Windows知道硬體加速OpenGL驅動的名字,以後運作OpenGL程式,OpenGL32.dll就會把OpenGL調用直接轉到nvoglnt.dll。

Windows平台上,一個OpenGL程式是否使用硬體加速由三個因素決定,這三個因素缺一不可,否則程式都會運作于純軟體模式:

是否有一塊3D加速卡

是否安裝了顯示卡廠商提供的最新的驅動程式,Windows自帶的顯示卡驅動程式并不會提供OpenGL硬體加速能力

指定的像素格式是否被顯示卡硬體所支援

判斷一種像素格式是否被顯示卡硬體所支援,可以用函數DescribePixelFormat取得該像素格式的資料,然後看結構體PIXELFORMATDESCRIPTOR中的dwFlags的值,如果

PFD_GENERIC_FORMAT被置1,并且PFD_GENERIC_ACCELERATED被置0,即

(pfd.dwFlags & PFD_GENERIC_FORMAT) &&

!(pfd.dwFlags & PFD_GENERIC_ACCELERATED)

表明該像素格式不被顯示卡硬體支援,使用該像素格式的OpenGL程式将使用純軟體模式渲染

PFD_GENERIC_FORMAT被置1,并且PFD_GENERIC_ACCELERATED被置1,即

(pfd.dwFlags & PFD_GENERIC_FORMAT) &&

(pfd.dwFlags & PFD_GENERIC_ACCELERATED)

表明該像素格式被顯示卡硬體支援,并且程式使用MCD模式渲染

PFD_GENERIC_FORMAT被置0,并且PFD_GENERIC_ACCELERATED被置0,

!(pfd.dwFlags & PFD_GENERIC_FORMAT) &&

!(pfd.dwFlags & PFD_GENERIC_ACCELERATED)

表明該像素格式被顯示卡硬體支援,并且程式使用ICD模式渲染

3 OpenGL Extension

這個軟體可以自動測試顯示卡對OpenGL的版本支援和擴充指令。

4、如何使用擴充

如果你在Windows平台下開發OpenGL程式,那麼系統中自帶的OpenGL庫就是1.1的,如果想使用1.2或者更高版本的OpenGL庫,那麼隻能使用OpenGL擴充。很多參考書上都會提到OpenGL2.0、OpenGL2.1,但是微軟對OpenGL的支援隻到1.1,1.1以後微軟就不再支援了,為什麼,因為微軟更想發展自家的DirectX。是以如果想使用OpenGL1.1以上的功能或者函數,隻能使用OpenGL擴充,這些擴充是一些OpenGL團體或個人開發出來的能Windows上使用的OpenGL1.1以後的一些功能及函數。是以,在Windows上根本就沒有什麼OpenGL2.0的頭檔案或庫檔案了,OpenGL1.1以後的東西都已經以擴充的形式存在了,而且,并沒有一個統一的标準,你可以使用glex,glew,glee等等。

是否能用擴充和顯示卡的功能有關,const     GLubyte   * glGetString( GLenum name )我們以GL_EXTENSIONS為參數調用該函數,就能獲得目前顯示卡所支援的所有擴充,像下面這樣:const GLubyte *str = glGetString(GL_EXTENSIONS) ; cout << str << endl ;輸出的各個擴充之間以空格分隔,如果這些擴充中包含GL_ARB_imaging,那麼你就可以使用glBlendEquation這個函數了。當然,這樣查詢的隻是gl擴充,還可以用gluGetString獲得glu擴充。在判斷了顯示卡所支援的擴充以後,就可以使用該擴充中所包含的函數了。

4.1 使用glext

這裡下載下傳:(http://graphics.ethz.ch/pointsho ... lext_8h-source.html)

a)頭檔案的包含 這個檔案并不是Windows系統中原有的,需要到網上下載下傳。使用的時候有一點要注意,如果程式中還用到了glut.h檔案,那麼一定要把glext.h放在glut.h的後面,因為glext.h要用到gl.h,而glut.h中包含了gl.h,如果順序搞錯了,編譯的時候會有一大堆錯誤,正确的順序如下:

#include <iostream>

#include <windows.h>

#include <GL/glut.h>

#include <GL/glext.h>

b)擷取函數指針

先定義函數指針,PFNGLBLENDEQUATIONPROC  glBlendEquation = NULL;

再擷取函數位址, 使用wglGetProcAddress函數,注意這一句要加在使用glBlendEquation函數的語句之前才有效,最後後面緊跟着使用glBlendEquation的函數語句,切記不要加在所有子程式的外面,否則擷取的指針是無效的

glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");

例如可以這樣加:

PFNGLBLENDEQUATIONPROC glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");

switch(key)

{ case 'a':

case 'A':  //Note: glBlendEquation is a subset of GL_ARB_imaging, please call glGetString

//first to confirm whether your video card support this extension.

                   glBlendEquation(GL_FUNC_ADD) ;

 break ;

         case 's':

         case 'S':

                   glBlendEquation(GL_FUNC_SUBTRACT) ;

                   break ;

4.2 使用glew

glew也是一個擴充庫,包含了OpenGL中許多核心及擴充函數,現在的版本是 1.3.5 ,支援OpenGL2.1,可以到這裡下載下傳:

http://glew.sourceforge.net/

上面的方法可能有些麻煩,如果已經下載下傳了glew庫的話,那麼可以直接使用該擴充,但是使用之前首先要确定你的顯示卡是否支援該擴充。方法如下:首先還是要判斷顯示卡是否支援該擴充,我們這裡假定已經支援,

1).包含頭檔案glew.h,注意這裡和上面不同,這回glut.h要放在glew.h的後面了

像下面這樣

#include <GL/glew.h>

#include <GL/glut.h>

然後就可以在程式中直接使用glBlendEquation了,其他擴充的判斷和使用方法與此類似。

最後還有一點切記!那就是還要調用glewInit() ;來初始化一下方可使用擴充,如下:

GLenum err = glewInit() ;

         if (GLEW_OK != err)

         {

                   MessageBoxA(NULL, "error", "My Window", 1) ;

         }

   你現在可以使用擴充了!

繼續閱讀