週一到週五,天天一篇,北京時間早上7點準時更新~app
All of the examples shown in this book so far have relied on the core functionality of OpenGL(到目前爲止的案例都是基於OpenGL的核心標準的). However, one of OpenGL’s greatest strengths is that it can be extended and enhanced by hardware manufacturers, operating system vendors, and even publishers of tools and debuggers(然而還有一些擴展的API是某部分廠商的硬件獨特的特性,多是在標準API裏是沒有的). Extensions can have many different effects on OpenGL functionality(這些擴展的特性可能會帶來很不同的影響)框架
An extension is any addition to a core version of OpenGL(擴展是指對核心版本API的額外補充). Extensions are listed in the OpenGL extension registry on the OpenGL Web site(擴展列表在OpenGL的網站上有展現). These extensions are written as a list of differences from a particular version of the OpenGL specification, and note what that version of OpenGL is(這些擴展的實現與某個特定版本的OpenGL標準可能不一致,你須要注意擴展是哪一個版本的OpenGL擴展). That means the text of the extensions describes how the core OpenGL specification must be changed if the extension is supported(也就是說,擴展描述了若是你啓動了擴展,OpenGL的實現會變成什麼樣子). However, popular and generally useful extensions are normally 「promoted」 into the core versions of OpenGL(不過,不少有用的擴展通常都會最終被歸入核心標準中去); thus, if you are running the latest and greatest version of OpenGL, there might not be that many extensions that are interesting but not part of the core profile(也就是說,每次OpenGL更新到最新版本的時候,之前那些擴展可能就不存在了,而是被歸入了新版本OpenGL的標準裏). A complete list of the extensions that were promoted to each version of OpenGL and a brief synopsis of what they do is included in Appendix C, 「OpenGL Features and Versions.」(一個完整的擴展列表以及他們的其餘相關信息在附錄C裏)less
There are three major classifications of extensions: vendor, EXT, and ARB(主要有三種擴展:廠商、EXT、ARB). Vendor extensions are written and implemented on one vendor’s hardware(廠商的擴展是在廠商本身的硬件上實現的). Initials representing the specific vendor are usually part of the extension name—「AMD」 for Advanced Micro Devices or 「NV」 for NVIDIA, for example(一般實現的表述包含了廠商的名字,好比AMD就表明着Advanced Micro Devices,NV表明的是NVIDIA). It is possible that more than one vendor might support a specific vendor extension, especially if it becomes widely accepted(也可能存在多個廠商實現同一個廠商的擴展的狀況,特別是若是那個擴展被普遍接受的時候). EXT extensions are written together by two or more vendors(EXT擴展是被兩個以上的廠商實現的擴展). They often start their lives as vendor-specific extensions, but if another vendor is interested in implementing the extension, perhaps with minor changes, it may collaborate with the original authors to produce an EXT version(通常狀況下,可能起初只有一個廠商的擴展,後來又有其餘廠商對此感興趣,且想對其進行細微調整,因此他們就聯合起來搞了,搞出來的擴展就是EXT擴展). ARB extensions are an official part of OpenGL because they are approved by the OpenGL governing body, the Architecture Review Board (ARB)(ARB擴展是OpenGL的官方Architecture Review Board所推進的擴展). These extensions are often supported by most or all major hardware vendors and may also have started out as vendor or EXT extensions(ARB擴展常常被大部分或者所有硬件廠商所支持,它們也可能源自廠商的擴展或者是EXT擴展)ide
This extension process may sound confusing at first(剛開始聽到擴展的推進過程的時候可能會感到疑惑). Hundreds of extensions currently are available!(上百個擴展示在是能夠被使用的) But new versions of OpenGL are often constructed from extensions programmers have found useful(新的OpenGL版本每每是從有用的擴展進行構建的). In this way each extension gets its time in the sun(這樣一來,每個擴展都有見到陽光的那一天). The ones that shine can be promoted to core(那些很屌的擴展則會被放到核心OpenGL標準裏去); the ones that are less useful are not considered(那些不怎麼實用的則不會被考慮). This 「natural selection」 process helps to ensure only the most useful and important new features make it into a core version of OpenGL(天然選擇能幫助來篩選出那些最有用和最重要的新特性)函數
A useful tool to determine which extensions are supported in your computer’s OpenGL implementation is Realtech VR’s OpenGL Extensions Viewer. It is freely available from the Realtech VR Web site (see Figure 3.6)(一個能夠探測你電腦所支持的擴展的工具叫Realtech VR’s OpenGL Extensions Viewer,如圖3.6所示,它是免費的)工具
Enhancing OpenGL with Extensions(使用擴展加強OpenGL)oop
Before using any extensions, you must make sure that they’re supported by the OpenGL implementation that your application is running on(在使用擴展以前,你須要肯定,這個擴展在你當前運行的的設備上是被支持的). To find out which extensions OpenGL supports, there are two functions that you can use. First, to determine the number of supported extensions, you can call glGetIntegerv() with the GL_NUM_EXTENSIONS parameter(你能夠經過glGetIntegerv(GL_NUM_EXTENSIONS,*)來獲取當前環境支持的擴展的個數). Next, you can find out the name of each of the supported extensions by calling(而後你能夠經過下面的API獲取每一個擴展的名字)網站
const GLubyte* glGetStringi(GLenum name,GLuint index);ui
You should pass GL_EXTENSIONS as the name parameter, and a value between 0 and 1 less than the number of supported extensions in index(第一個參數要傳GL_EXTENSIONS,第二個參數是第幾個擴展,這個值要小於上一步得到的擴展個數). The function returns the name of the extension as a string(這個函數返回一個擴展的名字). To see if a specific extension is supported, you can simply query the number of extensions, and then loop through each supported extension and compare its name to the one you’re looking for(爲了知道一個擴展是否被支持,你能夠先拿到全部擴展的名字,而後在名字裏找找看,是否存在你想查詢的那個). The book’s source code comes with a simple function that does this for you(在本課程中,咱們就封裝了這樣一個方法). sb7IsExtensionSupported() has the prototype(它的名字叫sb7IsExtensionSupported,函數定義以下)this
int sb7IsExtensionSupported(const char * extname);
This function is declared in the header, takes the name of an extension, and returns non-zero if it is supported by the current OpenGL context and zero if it is not(這個函數申明在sb7ext.h中,若是被查詢的擴展被支持,則返回非0,不然返回0). Your application should always check for support for extensions you wish to use before using them(你的程序要在使用擴展前檢查擴展是否被支持)
Extensions generally add to OpenGL in some combination of four different ways(擴展一般由四種方式的某種組合添加到OpenGL中):
They can make things legal that weren’t before, by simply removing restrictions from the OpenGL specification.(他們能夠經過移除一些OpenGL的限制使得之前不合法的事情合法)
They can add tokens or extend the range of values that can be passed as parameters to existing functions.(他們相對於現存的函數,能夠接受範圍更廣的參數或者token)
They can extend GLSL to add functionality, built-in functions, variables, or data types.(他們能夠經過添加功能,內置變量或者什麼數據類型來加強GLSL)
They can add entirely new functions to OpenGL itself(他們爲OpenGL增長了的嶄新的函數)
In the first case, where things that once were considered errors no longer are, your application doesn’t need to do anything besides start using the newly allowed behavior (once you have determined that the extension is supported, of course)(第一種狀況下,之前被認爲是錯誤的調用會變得正確,除了使用新被容許的行爲,你不須要修改你的程序). Likewise, for the second case, you can just start using the new token values in the relevant functions, presuming that you have their values(一樣,對於第二種狀況,若是你有這些參數的話,你能夠開始在相關的API中使用新的參數). The values of the tokens are in the extension specifications, so you can look them up there if they are not included in your system’s header files.(若是你在系統的頭文件裏找不到的話,這些參數在擴展的文檔裏)
To enable use of extensions in GLSL, you must first include a line at the beginning of shaders that use them to tell the compiler that you’re going to need their features(爲了使用那些GLSL裏的擴展,你須要在GLSL中告訴編譯器,你須要使用到那些特性). For example, to enable the hypothetical GL_ABC_foobar_feature extension in GLSL,include the following in the beginning of your shader(好比,要使用GL_ABC_foobar_feature擴展,你須要在你的shader裏寫上下面這句話):
#extension GL_ABC_foobar_feature : enable
This tells the compiler that you intend to use the extension in your shader(這句話告訴編譯器,你要在shader裏使用這個特性). If the compiler knows about the extension, it will let you compile the shader, even if the underlying hardware doesn’t support the feature(若是編譯器知道這個特性,即使底層硬件不支持,編譯器也能夠編譯出正確的GPU程序). If this is the case, the compiler should issue a warning if it sees that the extension is actually being used(若是是這種狀況的話,若是這個特性確實被shader使用了,編譯器應該發出警告). Typically, extensions to GLSL will add preprocessor tokens to indicate their presence(一般來說,GLSL的擴展會被進行預處理,從而肯定他們的表現). For example, GL_ABC_foobar_feature will implicitly include(好比GL_ABC_foobar_feature將被隱式包含)
#define GL_ABC_foobar_feature 1
This means that you could write code such as(這句話就代表,你能夠寫以下的代碼)
#if GL_ABC_foobar_feature
// Use functions from the foobar extension
#else
// Emulate or otherwise work around the missing functionality
#endif
This allows you to conditionally compile or execute functionality that is part of an extension that may or may not be supported by the underlying OpenGL implementation. If your shader absolutely requires support for an extension and will not work at all without it, you can instead include this more assertive code:
#extension GL_ABC_foobar_feature : require
If the OpenGL implementation does not support the GL_ABC_foobar_feature extension, then it will fail to compile the shader and report an error on the line including the #extension directive(若是OpenGL的實現不支持GL_ABC_foobar_feature擴展,編譯shader時將會失敗,並報出錯誤在哪裏). In effect, GLSL extensions are opt-in features, and applications must tell compilers up front which extensions they intend to use(實際上GLSL擴展是具備選擇性特性的,應用程序應該告訴編譯器他們想使用什麼樣的擴展)
Next we come to extensions that introduce new functions to OpenGL(接下來,咱們看看那些爲OpenGL添加了新函數的擴展). On most platforms, you don’t have direct access to the OpenGL driver and extension functions don’t just magically appear as available to your applications to call(在大多數平臺上,你沒法直接訪問OpenGL的驅動,擴展函數不會那麼神奇的直接就能夠被你的程序訪問). Rather, you must ask the OpenGL driver for a function pointer that represents the function you want to call(更多的是,你須要找OpenGL的驅動要到你想要訪問的函數的指針). Function pointers are generally declared in two parts;(函數指針一般被定義成兩個部分) the first is the definition ofthe function pointer type, and the second is the function pointer variable itself.(第一個部分是函數的指針類型,第二個部分是函數指針自己) Consider this code as an example:(例以下面的)
typedef void
(APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode,GLuint id);
PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback = NULL;
This declares the PFNGLDRAWTRANSFORMFEEDBACKPROC type as a pointer to a function taking GLenum and GLuint parameters(這就定義了PFNGLDRAWTRANSFORMFEEDBACKPROC類型的函數指針,且這個函數接受一個GLenum和GLuint的參數). Next, it declares the glDrawTransformFeedback variable as an instance of this type(而後,它定義了該函數指針類型的實際的變量). In fact, on many platforms, the declaration of the glDrawTransformFeedback() function is actually just like this(實際上,在不少平臺上,就如同剛纔展現的這樣,glDrawTransformFeedback就是這麼定義的). This seems pretty complicated, but fortunately the following header files include declarations of all of the function prototypes, function pointer types, and token values introduced by all registered OpenGL extensions(這看上去很是的複雜,可是幸運的是,下面的這個頭文件定義了全部的函數類型,函數指針的類型以及那些參數):
#include
#include
#include
These files can be found at the OpenGL extension registry Web site(這些能夠在OpenGL擴展的網站上找到). The glext.h header contains both standard OpenGL extensions and many vendor-specific OpenGL extensions(glext.h包含了標準的OpenGL擴展和不少廠商的擴展), the wglext.h header contains a number of extensions that are Windows specific(wglext.h包含的是Windows上支持的擴展), and the glxext.h header contains definitions that are X specific (glxext.h包含的是X擴展,X指代的是Linux或者是Unix系的窗口系統)(X is the windowing system used on Linux and many other UNIX derivatives and implementations)
The method for querying the address of extension functions is actually platform specific(查詢擴展函數的訪問地址會因平臺而異). The book’s application framework wraps up these intricacies into a handy function that is declared in the header file(本書的框架把這些方法打包進了sb7ext.h的一個函數裏去了). The function sb7GetProcAddress() has this prototype(這個函數叫sb7GetProcAddress,它的定義以下):
void sb7GetProcAddress(const char funcname);
Here, funcname is the name of the extension function that you wish to use(這裏funcname是擴展函數的名字). The return value is the address of the function, if it’s supported, and NULL otherwise(若是擴展被支持,那麼該函數返回一個函數地址,不然返回NULL). Even if OpenGL returns a valid function pointer for a function that’s part of the extension you want to use, that doesn’t mean the extension is present(即使OpenGL返回了一個合法的函數指針,那也只是一個擴展,這並不意味着擴展存在). Sometimes the same function is part of more than one extension, and sometimes vendors ship drivers with partial implementations of extensions present(有時候一樣的函數是多個擴展的一部分,也有的時候廠商只實現了擴展的一部分). Always check for support for extensions using the official mechanisms or the sb7IsExtensionSupported() function(請確保使用擴展以前來檢查擴展是否被支持).
本日的翻譯就到這裏,明天見,拜拜~~