Determining OpenGL ES Capabilities
Both the OpenGL ES 1.1 and OpenGL ES 2.0 specifications define a minimum standard that every implementation must support. However, the OpenGL ES specification does not limit an implementation to just those capabilities. The OpenGL ES specification allows implementations to extend its capabilities in multiple ways. Another document, OpenGL ES Hardware Platform Guide for iOS, drills down into the specific capabilities of each OpenGL ES implementation provided by iOS. The precise capabilities of an implementation may vary based on the version of the specification implemented, the underlying graphics hardware, and the version of iOS running on the device.
Whether you have chosen to build an OpenGL ES 1.1 or OpenGL ES 2.0 application, the first thing your application should do is determine the exact capabilities of the underlying implementation. To do this, your application sets a current context and calls one or more OpenGL ES functions to retrieve the specific capabilities of the implementation. The capabilities of the context do not change after it is created; your application can test the capabilities once and use them to tailor its drawing code to fit within those capabilities. For example, depending on the number of texture units provided by the implementation, you might perform your calculations in a single pass, perform them in multiple passes, or choose a simpler algorithm. A common pattern is to design a class for each rendering path in your application, with the classes sharing a common superclass. At runtime you instantiate the class that best matches the capabilities of the context.
Read Implementation-Dependent Values
The OpenGL ES specification defines implementation-dependent values that define limits of what an OpenGL ES implementation is capable of. For example, the maximum size of a texture and the number of texture units are both common implementation-dependent values that an application is expected to check. iOS devices that support the PowerVR MBX graphics hardware support textures up to 1024 x 1024 in size, while the PowerVR SGX software supports textures up to 2048 x 2048; both sizes greatly exceed 64 x 64, which is the minimum size required in the OpenGL ES specification. If your application’s needs exceeds the minimum capabilities required by the OpenGL ES specification, it should query the implementation to check the actual capabilities of the hardware and fail gracefully; you may load a smaller texture or choose a different rendering strategy.
Although the specification provides a comprehensive list of these limitations, a few stand out in most OpenGL applications. Table 3-1 lists values that both OpenGL ES 1.1 and OpenGL ES 2.0 applications should test.
Maximum size of the texture | GL_MAX_TEXTURE_SIZE |
Number of depth buffer planes | GL_DEPTH_BITS |
Number of stencil buffer planes | GL_STENCIL_BITS |
In an OpenGL ES 2.0 application, your application primarily needs to read the limits placed on its shaders. All graphics hardware supports a limited number of attributes that can be passed into the vertex and fragment shaders. An OpenGL ES 2.0 implementation is not required to provide a software fallback if your application exceeds the values provided by the implementation; your application must either keep its usage below the minimum values in the specification, or it must check the shader limitations documented in Table 3-2 and choose shaders whose usage fits within those limits.
Maximum number of vertex attributes | GL_MAX_VERTEX_ATTRIBS |
Maximum number of uniform vertex vectors | GL_MAX_VERTEX_UNIFORM_VECTORS |
Maximum number of uniform fragment vectors | GL_MAX_FRAGMENT_UNIFORM_VECTORS |
Maximum number of varying vectors | GL_MAX_VARYING_VECTORS |
Maximum number of texture units usable in a vertex shader | GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS |
Maximum number of texture units usable in a fragment shader | GL_MAX_TEXTURE_IMAGE_UNITS |
For all of the vector types, the query returns the number of 4-component floating-point vectors available.
OpenGL ES 1.1 applications should check the number of texture units and the number of available clipping planes, as shown in Table 3-3.
Maximum number of texture units available to the fixed function pipeline | GL_MAX_TEXTURE_UNITS |
Maximum number of clip planes | GL_MAX_CLIP_PLANES |
Check for Extensions Before Using Them
An OpenGL ES implementation adds functionality to the OpenGL ES API by implementing OpenGL ES extensions. Your application must check for the existence of any OpenGL ES extension whose features it intends to use. The sole exception is the OES_framebuffer_object extension, which is always provided on all iOS implementations of OpenGL ES 1.1. iOS uses framebuffer objects as the only kind of framebuffer your application may draw into.
Listing 3-1 provides code you can use to check for the existence of extensions.
Listing 3-1 Checking for OpenGL ES extensions.
BOOL CheckForExtension(NSString *searchName) |
{ |
// For performance, the array can be created once and cached. |
NSString *extensionsString = [NSString stringWithCString:glGetString(GL_EXTENSIONS) encoding: NSASCIIStringEncoding]; |
NSArray *extensionsNames = [extensionsString componentsSeparatedByString:@" "]; |
return [extensionsNames containsObject: searchName]; |
} |
Call glGetError to Test for Errors
The debug version of your application should periodically call the glGetError function and flag any error that is returned. If an error is returned from the glGetError function, it means the application is using the OpenGL ES API incorrectly or the underlying implementation is not capable of performing the requested operation.
Note that repeatedly calling the glGetError function can significantly degrade the performance of your application. Call it sparingly in the release version of your application.
© 2013 Apple Inc. All Rights Reserved. (Last updated: 2013-04-23)