OpenGL版本與OpenGL擴展機制 (轉載)


分類: Direct3D/OpenGL 2007-10-28 11:03 484人閱讀 評論(0) 收藏 舉報 
擴展windowsdirect3dparametersextension微軟轉自http://blog.csdn.net/yqxx/archive/2005/05/27/382513.aspx


1 opengl的版本區別(在opengl官方文檔中有詳細說明) 


    針對Opengl不同版本的升級是主要是擴展指令集。 


       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擴展指令之一。 


去年8月已經推出opengl2.0。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”。 




 


 
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標準的一部分,可以簡化程序開發,程序員使用這些功能時不必做繁瑣的擴展初始化工作。比如多重紋理功能,在OpenGL1.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的版本支持和擴展命令。 




 


 
相關參考文獻: 


《Opengl擴展機制》 (用google能夠搜到,有代碼實現) 


Extensions to OpenGL (opengl網站對extension的簡單介紹) 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章