文檔簡(jiǎn)述:
隨著顯卡的飛速發(fā)展,更快的速度以及越來(lái)越多的新功能為硬件所支持,硬件的進(jìn)步使得圖形程序開(kāi)發(fā)人員可以創(chuàng)造出更加絢麗的視覺(jué)效果,現(xiàn)在,電影級(jí)動(dòng)畫(huà)的實(shí)時(shí)渲染已不再是夢(mèng)想。我們?cè)趺丛贠penGL中利用顯卡的新特性呢?答案就是OpenGL擴(kuò)展。 注:如不作特別說(shuō)明,本站文章中的顯卡均指面向普通用戶的非專業(yè)顯卡。
文檔目錄: OpenGL擴(kuò)展 顯卡差異 頂點(diǎn)/片斷編程 Cg/RenderMonkey/及其他
文檔內(nèi)容:
OpenGL和Direct3D比較起來(lái),最大的一個(gè)長(zhǎng)處就是其擴(kuò)展機(jī)制。硬件廠商開(kāi)發(fā)出一個(gè)新功能,可以針對(duì)新功能開(kāi)發(fā)OpenGL擴(kuò)展,軟件開(kāi)發(fā)人員通過(guò)這個(gè)擴(kuò)展就可以使用新的硬件功能。所以雖然顯卡的發(fā)展速度比OpenGL版本更新速度快得多,但程序員仍然可以通過(guò)OpenGL使用最新的硬件功能。而Direct3D則沒(méi)有擴(kuò)展機(jī)制,硬件的新功能要等到微軟發(fā)布新版DirectX后才可能支持。
OpenGL擴(kuò)展也不是沒(méi)有缺點(diǎn),正因?yàn)楦鱾€(gè)硬件廠商都可以開(kāi)發(fā)自己的擴(kuò)展,所以擴(kuò)展的數(shù)目比較大,而且有點(diǎn)混亂,有些擴(kuò)展實(shí)現(xiàn)的相同的功能,可因?yàn)槭遣煌瑥S商開(kāi)發(fā)的,接口卻不一樣,所以程序中為了實(shí)現(xiàn)這個(gè)功能,往往要為不同的顯卡寫(xiě)不同的程序。這個(gè)問(wèn)題在OpenGL 2.0出來(lái)后可能會(huì)得到解決,OpenGL 2.0的一個(gè)目標(biāo)就是統(tǒng)一擴(kuò)展,減少擴(kuò)展數(shù)目。
擴(kuò)展名
??? 每個(gè)擴(kuò)展都有一個(gè)擴(kuò)展名,擴(kuò)展名類似如下形式:
?????????????????????? GL_ARB_multitexture
第一段GL,用來(lái)表示針對(duì)OpenGL哪部分開(kāi)發(fā)的擴(kuò)展,有以下幾個(gè)值:
-
GL?
– 針對(duì)OpenGL核心的擴(kuò)展
-
WGL
– 針對(duì)Windows平臺(tái)的擴(kuò)展
-
GLX
– 針對(duì)Unix / Linux平臺(tái)的擴(kuò)展
-
GLU
– 針對(duì)OpenGL Utility Library的擴(kuò)展
第二段ARB,用來(lái)表示是誰(shuí)開(kāi)發(fā)的這個(gè)擴(kuò)展,常見(jiàn)以下幾個(gè)值:
-
ARB
– 經(jīng)OpenGL Architecture Review Board(OpenGL管理機(jī)構(gòu))正式核準(zhǔn)的擴(kuò)展,往往由廠商開(kāi)發(fā)的擴(kuò)展發(fā)展而來(lái),如果同時(shí)存在廠商開(kāi)發(fā)的擴(kuò)展和ARB擴(kuò)展,應(yīng)該優(yōu)先使用ARB擴(kuò)展?
-
EXT
– 被多個(gè)硬件廠商支持的擴(kuò)展
-
NV?
– nVIDIA 公司開(kāi)發(fā)的擴(kuò)展
-
ATI
– ATI公司開(kāi)發(fā)的擴(kuò)展
-
ATIX
– ATI公司開(kāi)發(fā)的實(shí)驗(yàn)性擴(kuò)展
-
SGI
– Silicon Graphics(SGI)公司開(kāi)發(fā)的擴(kuò)展
-
SGIX
– Silicon Graphics(SGI)公司開(kāi)發(fā)的實(shí)驗(yàn)性擴(kuò)展
第三段multitexture就是真正的擴(kuò)展名了,如multitexture就是多重紋理擴(kuò)展。
?
使用OpenGL擴(kuò)展
要使用一個(gè)OpenGL擴(kuò)展,首先必須檢查顯卡是否支持這個(gè)擴(kuò)展,以下代碼可以獲取一個(gè)顯卡支持的的OpenGL擴(kuò)展:
???
const char *str = glGetString( GL_EXTENSIONS );
函數(shù)返回一個(gè)字符串指針,這個(gè)字符串就是顯卡所支持的所有擴(kuò)展的擴(kuò)展名,不同的擴(kuò)展名之間用空格隔開(kāi),形如:
???
"GL_ARB_imaging GL_ARB_multitexture GL_ARB_point_parameters
……
"
????
OpenGL擴(kuò)展往往都會(huì)新增一些函數(shù),在Windows平臺(tái)上,這些函數(shù)不是通過(guò).lib庫(kù)連接到程序里的,而要在運(yùn)行時(shí)動(dòng)態(tài)獲得函數(shù)的指針。我們以GL_ARB_point_parameters擴(kuò)展為例看看怎么獲得函數(shù)指針。
??
首先要定義函數(shù)指針類型,
???
typedef void (APIENTRY * PFNGLPOINTPARAMETERFARBPROC)(GLenum pname, GLfloat param);
??? typedef void (APIENTRY * PFNGLPOINTPARAMETERFVARBPROC)(GLenum pname, const GLfloat *params);
這個(gè)工作SGI已經(jīng)為我們做好,它提供了一個(gè)頭文件 glext.h,里面有目前絕大多數(shù)擴(kuò)展的常量和函數(shù)指針定義,下載下來(lái)放到編譯器的include/GL文件夾下面,然后在程序里面加上:
???
#include <GL/glext.h>
就可以在程序中使用常量和函數(shù)指針類型了。
??
然后要定義函數(shù)指針:
???
PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
??? PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
?? 再檢查顯卡是否支持
GL_ARB_point_parameters
擴(kuò)展,其中
isExtensionSupported
是自定義的一個(gè)函數(shù),就是在glGetString( GL_EXTENSIONS )返回的字符串里查找是否存在指定的擴(kuò)展名:
???
int hasPointParams = isExtensionSupported("GL_ARB_point_parameters");
如果支持,就可以用
wglGetProcAddress
函數(shù)獲取擴(kuò)展函數(shù)的指針:
??? if (hasPointParams)?
??? { ??????? glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)\ wglGetProcAddress( "glPointParameterfEXT" ); ??????? glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) \ wglGetProcAddress( "glPointParameterfvEXT" ); ??? }
?? 最后就可以在程序里使用擴(kuò)展函數(shù):
??? 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); ??? }
WGL擴(kuò)展
glGetString( GL_EXTENSIONS )取得的擴(kuò)展字符串中并不包括針對(duì)Windows平臺(tái)的WGL擴(kuò)展,WGL擴(kuò)展串要通過(guò)WGL_ARB_extensions_string擴(kuò)展來(lái)獲得,以下代碼演示了如何獲得WGL擴(kuò)展串:
???
定義WGL_ARB_extensions_string擴(kuò)展新增函數(shù)wglGetExtensionsStringARB的函數(shù)指針類型,同樣這個(gè)工作SGI已經(jīng)為我們做好,只不過(guò)不在glext.h中,而在它提供的另外一個(gè)頭文件 wglext.h 中:
???
typedef const char *(APIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC)( HDC hdc);
定義函數(shù)指針:
??? PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
檢查是否支持WGL_ARB_extensions_string擴(kuò)展,如果不支持,表示這個(gè)顯卡不支持WGL擴(kuò)展,如果支持,則得到wglGetExtensionsStringARB函數(shù)的指針,并調(diào)用它得到WGL擴(kuò)展串:
??? int hasWGLext = isExtensionSupported("WGL_ARB_extensions_string");
??? if (hasWGLext)
??? {
??????? wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) \ wglGetProcAddress( "wglGetExtensionsStringARB" );
??????? const char *wglExt = wglGetExtensionsStringARB( hdc );
??????? ……
??? }
???
OpenGL版本
一些常用的OpenGL擴(kuò)展會(huì)在新版的OpenGL中加到OpenGL核心中去,成為OpenGL標(biāo)準(zhǔn)的一部分,可以簡(jiǎn)化程序開(kāi)發(fā),程序員使用這些功能時(shí)不必做繁瑣的擴(kuò)展初始化工作。比如多重紋理功能,在OpenGL1.2.1加入到OpenGL核心中,以前要使用多重紋理,要先檢查是否支持GL_ARB_multitexture擴(kuò)展,然后初始化glActiveTextureARB等函數(shù),很麻煩,而OpenGL1.2后,則可以直接使用glActiveTexture函數(shù)。
不過(guò),這種簡(jiǎn)化只有Mac/Unix/Linux程序員才能享受到,在Windows平臺(tái)上沒(méi)有這么簡(jiǎn)單。微軟為了維護(hù)Direct3D,對(duì)OpenGL的支持很消極,其OpenGL實(shí)現(xiàn)仍然是1.1。由于Windows上的OpenGL程序最終都會(huì)動(dòng)態(tài)鏈接到微軟的OpenGL32.dll,可OpenGL32.dll只支持OpenGL 1.1,使我們不能直接使用新版OpenGL,仍然要用擴(kuò)展訪問(wèn)OpenGL1.1以來(lái)新增的功能。
??
OpenGL擴(kuò)展資料
? All About OpenGL Extensions : ????? 討論OpenGL擴(kuò)展機(jī)制,講述了如何閱讀擴(kuò)展官方說(shuō)明書(shū),并舉了一些擴(kuò)展的例子。必讀。
? OpenGL Extension Registry : ????? 由SGI維護(hù),列出了目前公開(kāi)的所有擴(kuò)展及其官方說(shuō)明書(shū)。
? OpenGL Hardware Registry: ????? 由Delphi3D.net維護(hù),列出了目前幾乎所有3D加速卡的OpenGL硬件信息,包括其支持的擴(kuò)展。當(dāng)然,這里面列的擴(kuò)展不能作為程序的依據(jù),程序中要使用某個(gè)擴(kuò)展,還是要先檢查顯卡是否支持。因?yàn)橥瑯拥娘@卡,如果驅(qū)動(dòng)程序不同,支持的擴(kuò)展也不相同,往往新的驅(qū)動(dòng)程序會(huì)加入新的擴(kuò)展,丟掉一些廢棄的擴(kuò)展。
?? OpenGL硬件加速
在Windows平臺(tái)上,OpenGL驅(qū)動(dòng)可能有三種模式:純軟件、MCD和ICD:
-
純軟件模式:微軟提供一個(gè)OpenGL的軟件實(shí)現(xiàn),所有渲染操作均由CPU完成,速度很慢。如果安裝系統(tǒng)時(shí)使用Windows自帶的顯卡驅(qū)動(dòng)程序,那么OpenGL程序就會(huì)運(yùn)行在軟件模式下。而且由于微軟有自己的Direct3D,所以對(duì)OpenGL的支持很消極,它的OpenGL純軟件實(shí)現(xiàn)只支持OpenGL1.1,而目前OpenGL的最新版本為1.4
-
MCD(Mini Client Driver):MCD是早期微軟在Windows NT上支持OpenGL時(shí),為了簡(jiǎn)化驅(qū)動(dòng)開(kāi)發(fā)時(shí)使用的一個(gè)模型。在這個(gè)模型中,OpenGL渲染管線的變換、光照部分仍然由軟件實(shí)現(xiàn),而光柵化部分則由硬件廠商實(shí)現(xiàn),因此只要硬件支持,MCD可以硬件加速光柵化部分。MCD雖然可以簡(jiǎn)化驅(qū)動(dòng)開(kāi)發(fā),但是功能限制太大,現(xiàn)在市面上的3D加速卡均支持硬件變換和光照,MCD卻不能利用這一特性,看上去MCD已經(jīng)沒(méi)有存在的價(jià)值
-
ICD(Installable Client Driver):ICD是一個(gè)完整的OpenGL驅(qū)動(dòng)模型,比MCD復(fù)雜得多。硬件廠商要實(shí)現(xiàn)完整的OpenGL渲染管線,如變換、光照、光柵化等,因此只要硬件支持,ICD可以硬件加速整個(gè)OpenGL渲染管線。我們通常說(shuō)的OpenGL硬件加速就是指的通過(guò)ICD模型獲得的硬件加速,而現(xiàn)在硬件廠商提供的OpenGL驅(qū)動(dòng)程序也都是依照ICD模型開(kāi)發(fā)的。主要硬件廠商的ICD已經(jīng)可以支持OpenGL的最新版1.4
??
Windows怎么實(shí)現(xiàn)OpenGL硬件加速呢?OpenGL32.dll是微軟的OpenGL?1.1純軟件實(shí)現(xiàn),我們的程序都要?jiǎng)討B(tài)鏈接到這個(gè)dll。如果安裝3D芯片廠商的驅(qū)動(dòng)程序,會(huì)將一個(gè)不同名字的dll放到Windows系統(tǒng)目錄下,比如在Windows?2000下安裝nVIDIA?GeForce2?MX的驅(qū)動(dòng)程序,會(huì)在系統(tǒng)目錄下放一個(gè)nvoglnt.dll(這就是nVIDIA的OpenGL驅(qū)動(dòng)),并在注冊(cè)表中登記nvoglnt.dll,讓W(xué)indows知道硬件加速OpenGL驅(qū)動(dòng)的名字,以后運(yùn)行OpenGL程序,OpenGL32.dll就會(huì)把OpenGL調(diào)用直接轉(zhuǎn)到nvoglnt.dll。
??
??? Windows平臺(tái)上,一個(gè)OpenGL程序是否使用硬件加速由三個(gè)因素決定,這三個(gè)因素缺一不可,否則程序都會(huì)運(yùn)行于純軟件模式:
??? 判斷一種像素格式是否被顯卡硬件所支持,可以用函數(shù)
DescribePixelFormat
取得該像素格式的數(shù)據(jù),然后看結(jié)構(gòu)體
PIXELFORMATDESCRIPTOR
中的
dwFlags
的值,如果
-
PFD_GENERIC_FORMAT
被置1,并且
PFD_GENERIC_ACCELERATED
被置0,即
(pfd.dwFlags & PFD_GENERIC_FORMAT) &&? !(pfd.dwFlags & PFD_GENERIC_ACCELERATED)
表明該像素格式不被顯卡硬件支持,使用該像素格式的OpenGL程序?qū)⑹褂眉冘浖J戒秩?
-
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模式渲染
正如前面所說(shuō),不同的顯卡廠商可能會(huì)為相同的功能開(kāi)發(fā)不同的OpenGL擴(kuò)展,使得OpenGL擴(kuò)展的編程復(fù)雜化,就算實(shí)現(xiàn)相同的功能也可能需要為不同的顯卡開(kāi)發(fā)不同的程序。好在現(xiàn)在顯卡芯片市場(chǎng)只有nVIDIA和ATI兩家當(dāng)?shù)溃怨ぷ髁恳膊粫?huì)太大。而OpenGL 2.0推出后,這種情況會(huì)大為改觀。
游戲的運(yùn)行環(huán)境差異很大,可能運(yùn)行于只具備基本3D加速能力的老顯卡上,也可能運(yùn)行于最新推出的功能強(qiáng)大的3D加速卡上,而且顯卡芯片的廠商也各不相同。對(duì)于顯卡較差的機(jī)器,要保證游戲能運(yùn)行,而對(duì)于較好的顯卡,要充分發(fā)揮它的功能,創(chuàng)造絢麗的圖形效果。這就是說(shuō)游戲需要多條執(zhí)行路徑,運(yùn)行時(shí)根據(jù)顯卡配置選擇不同的執(zhí)行路徑。怎么決定需要多少種執(zhí)行路徑呢?
設(shè)計(jì)執(zhí)行路徑要考慮兩個(gè)主要因素:
現(xiàn)在3D顯卡芯片市場(chǎng)有兩個(gè)主要廠商nVIDIA和ATI,它們各自的OpenGL擴(kuò)展也最多,必須為它們?cè)O(shè)計(jì)相應(yīng)的執(zhí)行路徑。對(duì)于其他廠商,因?yàn)閹缀跛袕S商都會(huì)盡量支持ARB擴(kuò)展,可以設(shè)計(jì)執(zhí)行路徑,使用各個(gè)廠商都支持的ARB擴(kuò)展。
顯卡芯片都會(huì)有個(gè)芯片代號(hào),類似于軟件的版本號(hào)。相同主版本號(hào)的芯片屬于一個(gè)檔次,支持的功能往往一樣。設(shè)計(jì)圖形程序時(shí),可以根據(jù)芯片代號(hào)來(lái)決定需要設(shè)計(jì)多少種執(zhí)行路徑。要注意的是必須要設(shè)計(jì)一條和顯卡無(wú)關(guān)的,只使用OpenGL基本功能的執(zhí)行路徑,使得程序能夠在低端顯卡上運(yùn)行。
現(xiàn)在可能使用的nVIDIA和ATI的顯卡芯片代號(hào)和顯卡型號(hào)的對(duì)應(yīng)關(guān)系如下表:
|
?nVIDIA
|
|
?ATI
|
|
?芯片代號(hào)
|
顯卡型號(hào)
|
|
?芯片代號(hào)
|
顯卡型號(hào)
|
?NV1 ?NV2 ?NV3 ?NV4? ?NV5?
|
NV1 Riva 128 Riva 128ZX Riva TnT Riva TnT2
|
|
?RAGE(?)
|
RAGE PRO RAGE 128 RAGE 128 PRO
|
?NV10? ?NV11?
?NV15?
?NV17?
?NV18?
|
GeForce 256 GeForce2 MX *
GeForce2 *
GeForce4 MX *
GeForce4 MX AGP8X *
|
|
?R100?
?RV200
|
RADEON 7000 RADEON RADEON 7200 RADEON 7500
|
?NV20?
?NV25? ?NV28?
|
Geforce3 Ti200 GeForce3 GeForce3 Ti500 GeForce4 Ti *
GeForce4 Ti AGP 8X *
|
|
?RV250? ?R200?
?RV280?
|
RADEON 9000 RADEON 8500 RADEON 9100 RADEON 9200 AGP 8X
|
?NV34? ?NV31? ?NV30? ?NV35?
|
GeForce FX 5200 GeForce FX 5600 GeForce FX 5800 GeForce FX 5900
|
|
?RV300? ?RV350? ?R300? ?R350?
|
RADEON 9500 RADEON 9600 RADEON 9700 RADEON 9800
|
·其中標(biāo)注 * 的是產(chǎn)品系列,型號(hào)還會(huì)細(xì)分
·通常大家習(xí)慣用芯片代號(hào)的主版本號(hào)來(lái)統(tǒng)稱一代芯片,例如用NV20統(tǒng)稱NV20/NV25/NV28,用R200統(tǒng)稱RV250/R200/RV280
·雖然ATI RADEON 7500的芯片型號(hào)是RV200,但實(shí)際屬于R100檔次的產(chǎn)品 ??
我們來(lái)看一個(gè)執(zhí)行路徑的例子,idSoftware即將推出的Doom3的執(zhí)行路徑。
Doom3一共有6條執(zhí)行路徑:
-
ARB:幾乎不使用擴(kuò)展,沒(méi)有鏡面高光效果,沒(méi)有頂點(diǎn)編程(vertex program),保證程序能在低端顯卡上運(yùn)行
-
NV10:支持所有功能,每幀需要渲染5個(gè)pass(five rendering passes,指一個(gè)對(duì)象多次送入渲染管道,比如第一次渲染漫射光diffuse,第二次渲染鏡面高光specular ……,各次渲染結(jié)果通過(guò)glBlend混合在一起形成最終效果),沒(méi)有頂點(diǎn)編程
-
NV20:支持所有功能,2或3個(gè)pass
-
NV30:支持所有功能,1個(gè)pass
-
R200:支持所有功能,大部分情況下只需1個(gè)pass
-
ARB2:支持所有功能,浮點(diǎn)片斷編程(fragment program),1個(gè)pass
nVIDIA顯卡可能執(zhí)行ARB / NV10 / NV20 / NV30 / ARB2 五條路徑,其中NV10 / NV20 / NV30 專門針對(duì)不同檔次的nVIDIA顯卡開(kāi)發(fā)的。
ATI顯卡可能執(zhí)行 ARB / R200 / ARB2 三條路徑,其中R200是專門針對(duì)ATI開(kāi)發(fā)的。
而其他顯卡則根據(jù)檔次高低執(zhí)行ARB或ARB2路徑。ARB用于低端顯卡,ARB2用于高端顯卡。
1999年底,nVIDIA推出GeForce 256,并開(kāi)始使用GPU(Graphics Processing Unit)來(lái)稱呼顯卡芯片(也有廠商叫VPU(Visual Processing Unit),是一回事)。GeForce 256最大賣點(diǎn)是硬件T&L(Transform&Lighting,變換和光照),這意味著變換和光照計(jì)算可以在GPU中進(jìn)行,大大減輕了CPU的壓力,顯卡開(kāi)始成為獨(dú)立于CPU的一個(gè)處理器。
硬件T&L后,GPU最激動(dòng)人心的進(jìn)步就是引入了可編程能力。我們知道,OpenGL和Direct3D都有固定的渲染管線,定義光源,送入頂點(diǎn)位置、法線、紋理坐標(biāo)等,就可以給你渲染出一幅圖像來(lái),程序員對(duì)具體的渲染過(guò)程無(wú)法控制。而OpenGL擴(kuò)展和DirectX8給渲染管線引入可編程能力,圖形軟件開(kāi)發(fā)人員可以編寫(xiě)運(yùn)行于顯卡芯片的匯編程序來(lái)控制具體的渲染過(guò)程,這給予圖形軟件開(kāi)發(fā)更大的靈活性,并且由于硬件的支持,獲得這些靈活性并不會(huì)犧牲性能。GPU的可編程能力對(duì)實(shí)時(shí)圖形渲染會(huì)產(chǎn)生深遠(yuǎn)的影響。 ?
OpenGL支持兩種可編程模型:
-
頂點(diǎn)編程Vertex Program,對(duì)應(yīng)于Direct3D中的Vertex Shader,提供可編程的T&L能力,代替了傳統(tǒng)渲染流水線中的T&L,處理頂點(diǎn)的變換、光照計(jì)算
-
片斷編程Fragment Program,對(duì)應(yīng)于Direct3D的Pixel Shader,提供可編程的光柵化操作,代替了傳統(tǒng)流水線中的紋理映射、逐像素顏色及霧效處理
目前頂點(diǎn)編程相關(guān)的擴(kuò)展有:
-
GL_NV_vertex_program
:nVIDIA NV10檔次顯卡用軟件模擬,NV20及以上檔次顯卡上硬件支持
-
GL_NV_vertex_program1_1
:nVIDIA NV10檔次顯卡用軟件模擬,NV20及以上檔次顯卡上硬件支持
-
GL_EXT_vertex_shader
:在ATI R200及以上檔次顯卡上支持
-
GL_ARB_vertex_program
:由上面三個(gè)擴(kuò)展發(fā)展而來(lái),支持上面三個(gè)擴(kuò)展的顯卡安裝最新的驅(qū)動(dòng)程序后都會(huì)支持此擴(kuò)展,所以程序中不必支持上面三個(gè)擴(kuò)展,只支持此擴(kuò)展就可以了。此擴(kuò)展不支持分支循環(huán)
-
GL_NV_vertex_program2
:在nVIDIA NV30及以上檔次顯卡上支持,支持分支循環(huán),估計(jì)會(huì)成為GL_ARB_vertex_program2擴(kuò)展的原型
-
實(shí)際上ATI R300級(jí)別的顯卡已經(jīng)在頂點(diǎn)編程中支持分支循環(huán)(硬件支持DirectX9的vs2.0),但并沒(méi)有開(kāi)發(fā)擴(kuò)展提供給OpenGL程序員使用,估計(jì)是在等支持分支循環(huán)的GL_ARB_vertex_program2擴(kuò)展出臺(tái)
可見(jiàn)現(xiàn)在使用OpenGL的vertex program,只需支持GL_ARB_vertex_program和GL_NV_vertex_program2兩個(gè)擴(kuò)展。
?
目前片斷編程相關(guān)的擴(kuò)展有:
以上擴(kuò)展提供的功能不是編寫(xiě)運(yùn)行于GPU的匯編碼,而是通過(guò)函數(shù)調(diào)用的方式實(shí)現(xiàn),不如編寫(xiě)匯編碼直觀方便。下面幾個(gè)擴(kuò)展則可以通過(guò)編寫(xiě)匯編碼來(lái)實(shí)現(xiàn)片斷編程
與頂點(diǎn)編程相比,片斷編程要復(fù)雜得多:
-
在NV10系列上,只能使用GL_NV_register_combiners提供的部分片斷編程能力
-
在NV20系列上,則可以使用register combiners和texture shader實(shí)現(xiàn)片斷編程
-
在NV30系列上,可以使用GL_ARB_fragment_program和GL_NV_fragment_program
-
在ATI R200系列上,使用GL_ATI_fragment_shader
-
在ATI R300系列上,使用GL_ARB_fragment_program
看到這里我們不難理解為什么Doom3會(huì)將渲染執(zhí)行路徑分成ARB、NV10、NV20、NV30、R200、ARB2幾條了:
-
ARB既沒(méi)有頂點(diǎn)編程也沒(méi)有片斷編程
-
NV10沒(méi)有用到頂點(diǎn)編程(雖然NV10支持頂點(diǎn)編程,但是是軟件模擬,而顯卡硬件并不支持),但用到register combiners實(shí)現(xiàn)凹凸貼圖(Bump Mapping)
-
NV20使用頂點(diǎn)編程,并用register combiners和texture shader實(shí)現(xiàn)片斷編程
-
NV30使用頂點(diǎn)編程,并用GL_NV_fragment_program實(shí)現(xiàn)片斷編程
-
R200使用頂點(diǎn)編程,并用GL_ATI_fragment_shader實(shí)現(xiàn)片斷編程
-
ARB2使用頂點(diǎn)編程,并用GL_ARB_fragment_program實(shí)現(xiàn)片斷編程
???
附表:
nVIDIA顯卡頂點(diǎn)、片斷編程支持情況
|
芯片代號(hào)
|
紋理單元數(shù)
|
Register Combiner
|
Texture Shader
|
Vertex Program
|
Fragment Program
|
|
?NVX
|
2
|
X
|
X
|
X
|
X
|
|
?NV10
|
2
|
2
級(jí)
|
X
|
NVvp1.1/ARBvp1.0
|
RC
|
|
?NV20
|
4
|
8
級(jí)
|
支持
|
NVvp1.1/ARBvp1.0
|
RC/TS
|
|
?NV30
|
4
|
8
級(jí)
|
支持
|
NVvp2.0/ARBvp1.0
|
ARBfp1.0/NVfp
|
?
ATI顯卡頂點(diǎn)、片斷編程支持情況
|
芯片代號(hào)
|
紋理單元數(shù)
|
Vertex Program
|
Fragment Program
|
|
?RAGE
|
2
|
X
|
X
|
|
?R100
|
3
|
X
|
X
|
|
?R200
|
6
|
EXTvp/ARBvp1.0
|
ATIfp
|
|
?R300
|
8
|
EXTvp/ARBvp1.0
|
ARBfp1.0
|
Cg(C for Graphics)
直接使用擴(kuò)展編寫(xiě)vertex program和fragment program不太方便,要么是函數(shù)調(diào)用,要么是匯編碼,相當(dāng)于用x86匯編編寫(xiě)PC程序,而現(xiàn)在已經(jīng)有了面向vertex program和fragment program的高級(jí)語(yǔ)言,稱為HLSL(高級(jí)著色語(yǔ)言,High Level Shading Language)。
Cg是nVIDIA提出的一種高級(jí)著色語(yǔ)言,它的語(yǔ)法和C語(yǔ)言類似,可以大大簡(jiǎn)化vertex program和fragment program的編寫(xiě)。用它寫(xiě)的程序可以:
-
編譯成GL_NV_vertex_program / GL_NV_vertex_program1_1 / GL_ARB_vertex_program / GL_NV_vertex_program2 的匯編碼
-
編譯成GL_ARB_fragment_program / GL_NV_fragment_program的匯編碼
-
編譯成用于nvParse的RC(Register Combiners)及TS(Texture Shader)腳本
-
直接在程序中調(diào)用Cg提供的API,運(yùn)行Cg程序
-
編譯成DirectX的 vertex shader / pixel shader
我們可以看到Cg只是對(duì)nVIDIA的產(chǎn)品支持比較好,而其他廠商的產(chǎn)品只有支持GL_ARB_vertex_program/GL_ARB_fragment_program時(shí)才能從Cg獲得好處,不支持這兩個(gè)ARB擴(kuò)展的顯卡則不能運(yùn)行Cg編寫(xiě)的程序,大大降低了Cg的實(shí)用性。雖然Cg提供接口,使其他廠商可以對(duì)Cg進(jìn)行擴(kuò)展,以支持各個(gè)廠商自己的OpenGL擴(kuò)展,不過(guò)Cg畢竟是一個(gè)企業(yè)的產(chǎn)品,別的廠商不會(huì)支持,所以如果要寫(xiě)通用的圖形程序,Cg并不合適。
況且OpenGL的HLSL——GLslang(OpenGL Shading Language)規(guī)范已經(jīng)被ARB審核通過(guò),估計(jì)不久就可以使用GLslang編寫(xiě)vertex program和fragment program,到時(shí)Cg的位置應(yīng)該會(huì)相當(dāng)尷尬,因?yàn)镺penGL和DirectX都已經(jīng)有了自己的HLSL。不過(guò)話說(shuō)回來(lái),Cg可以同時(shí)支持OpenGL和DirectX,這也算是它的一個(gè)優(yōu)勢(shì)。
?
RenderMonkey并不是一種語(yǔ)言,而是ATI推出的一個(gè)編寫(xiě)調(diào)試vertex program和fragment program的集成開(kāi)發(fā)環(huán)境,目前只支持DirectX的vertex shader / pixel shader / HLSL,不過(guò)ATI正在和3Dlabs合作,不日RenderMonkey也會(huì)支持OpenGL vertex program / fragment program / GLslang。另外,RenderMonkey不僅僅是為程序員設(shè)計(jì)的,美工也可以使用。
nvParse是nVIDIA公司推出的一個(gè)庫(kù),可以簡(jiǎn)化RC(Register Combiners)及TS(Texture Shader)的開(kāi)發(fā)。使用GL_NV_register_combiners和GL_NV_texture_shader擴(kuò)展實(shí)現(xiàn)片斷編程全是函數(shù)調(diào)用的形式,很不方便,而nVIDIA為了簡(jiǎn)化RC和TS程序開(kāi)發(fā),建立了一種腳本格式,用簡(jiǎn)單的腳本代替復(fù)雜的GL_NV_register_combiners和GL_NV_texture_shader函數(shù)調(diào)用,nvParse則提供API用于解釋執(zhí)行RC和TS腳本。
??
模擬NV30
并非所有程序員都有一塊NV30顯卡,但nVIDIA最新的雷管驅(qū)動(dòng)程序(version 40.41及以后)支持軟件模擬NV30架構(gòu),只不過(guò)很慢,但對(duì)沒(méi)有NV30顯卡的程序員已經(jīng)是個(gè)福音了,只要我們有一塊GeForce級(jí)的顯卡,安裝最新的雷管驅(qū)動(dòng)程序,然后下載一個(gè)NVEmulate.exe (52 KB),運(yùn)行它,打開(kāi)NV30模擬,你的顯卡就支持NV30的所有功能了,這樣就算沒(méi)有NV30顯卡同樣可以針對(duì)NV30開(kāi)發(fā)程序。要注意的是,不需要NV30模擬的時(shí)候要記得關(guān)掉它,畢竟是軟件模擬,速度很慢。
??
后記
寫(xiě)這些只是希望為后來(lái)的朋友指一個(gè)方向,寫(xiě)得很簡(jiǎn)略,因?yàn)槲易约阂苍趯W(xué)習(xí),hoho,更多的東西還是需要大家自己多看多寫(xiě) :) 我將來(lái)也會(huì)慢慢放上一些詳細(xì)的文章以及源碼,希望能對(duì)大家有所幫助。關(guān)于這篇文章的問(wèn)題或建議,可以寫(xiě)信給我,我的聯(lián)系方式。
|