周一到周五,每天一篇,北京时间早上7点准时更新~
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里)
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扩展)
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)
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);
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,函数定义如下)
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(请确保使用扩展之前来检查扩展是否被支持).
本日的翻译就到这里,明天见,拜拜~~
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。