When targeting a large amount of platform, by coincidence OpenGL 3.2 to 4.5, OpenGL ES 2.0 to ES 3.1+ and WebGL 1.0 and 2.0, it takes quite some investigations to implement a feature optimally. The difference between doing this investigation and not doing it is basically shipping a buggy engine. As an example, let's study texture swizzle and how it's exposed in OpenGL, OpenGL ES and WebGL.
GL_EXT_texture swizzle, promoted to OpenGL 3.3 core specifiction through GL_ARB_texture_swizzle extension, introduced a functionality to handle texture with arbitrary ordering or the components without requiring CPU reordering. For example, it allows loading BGRA8 or ARGB8 source textures to OpenGL RGBA8 texture object.
With OpenGL 3.3 and OpenGL ES 3.0, loading a BGRA8 texture can be done using the following approach:
OpenGL 3.3, GL_ARB_texture_swizzle and GL_EXT_texture swizzle provides a slightly different approach that is not available with OpenGL ES 3.0:
Unfortunately, neither WebGL 1.0 or WebGL 2.0 support texture swizzle due to performance issue of implementation such feature on top of Direct3D which doesn't have any equivalent functionality.
OpenGL supports GL_BGRA external format to load BGRA8 source textures without requiring the application to swizzle the source data. This is done using the following code:
However, such functionnality isn't available with OpenGL ES. While, it's not useful for OpenGL ES 3.0 that has texture swizzling support, OpenGL ES 2.0 relies on some extensions to expose this feature but it does it differently than OpenGL.
Using the GL_EXT_texture_format_BGRA8888 or GL_APPLE_texture_format_BGRA8888 extensions, loading BGRA textures is done with the following code:
When GL_EXT_texture_storage (ES2) is supported, BGRA texture loading is perform with the following code.
To understand the difference between OpenGL, OpenGL ES and OpenGL ES with texture storage the reasoning is the following: On the contrary to OpenGL, OpenGL ES doesn't support external format to internal format conversion of any kind, including texture component swizzling. Additionally, OpenGL ES 2.0 requires unsized format for the internal format while OpenGL ES 3.0 and texture storage requires sized internal format.
In this section, we call a texture alpha, a texture we using the alpha channel (.a, .w, .q) in a shader. With OpenGL ES and WebGL, this can be done by creating a texture with an alpha format as shown with the following code samples.
Texture alpha format is also available in OpenGL compatibility profile and WebGL but was removed in OpenGL core profile. An alternative is to rely on texture red format and texture swizzle as shown with the following code samples.
On one hand, both OpenGL ES and OpenGL compatibility profile supports texture alpha and luminance alpha. However, OpenGL core profile doesn't. On other hand, OpenGL 3.0 and OpenGL ES 3.0 support texture red and texture red green.
Texture red format was introduced on desktop with OpenGL 3.0 and GL_ARB_texture_rg. On OpenGL ES, it was introduced with OpenGL ES 3.0 and GL_EXT_texture_rg.
Unfortunately, OpenGL 3.2 core profile doesn't support either texture alpha format or texture swizzling. A possible workaround is to expend the source data to RGBA8 which consumes 4 times the memory which might be necessary to support texture alpha on MacOSX 10.7.
Enjoy!