23 Extensions and Versions

23.010 Where can I find information on different OpenGL extensions?

The OpenGL extension registry is the central resource for all OpenGL extensions. Also, the OpenGL org web page maintains a lot of information on different OpenGL extensions.

23.020 How will I know which OpenGL version my program is using?

It's commonplace for the OpenGL version to be named as a C preprocessor definition in gl.h. This enables your application to know the OpenGL version at compile time. To use this definition, your code might look like:

#ifdef GL_VERSION_1_2
   // Use OpenGL 1.2 functionality
#endif

OpenGL also provides a mechanism for detecting the OpenGL version at run time. An app may call glGetString(GL_VERSION), and parse the return string. The first part of the return string must be of the form [major-number].[minor-number], optionally followed by a release number or other vendor-specific information.

As with any OpenGL call, you need a current context to use glGetString().

23.030 What is the difference between OpenGL 1.0, 1.1, and 1.2?

In OpenGL 1.1, the following features are available:

  • Vertex Arrays, which are intended to decrease the number of subroutine calls required to transfer vertex data to OpenGL that is not in a display list
  • Polygon Offset, which allows depth values of fragments resulting from the filled primitives' rasterization to be shifted forward or backwards prior to depth testing
  • Logical Operations can be performed in RGBA mode
  • Internal Texture Formats, which let an application suggest to OpenGL a preferred storage precision for texture images
  • Texture Proxies, which allow an application to tailor its usage of texture resources at runtime
  • Copy Texture and Subtexture, which allow an application to copy textures or subregions of a texture from the framebuffer or client memory
  • Texture Objects, which let texture arrays and their associated texture parameter state be treated as a single texture object

In OpenGL 1.2, the following features are available:

  • Three-dimensional texturing, which supports hardware accelerated volume rendering
  • BGRA pixel formats and packed pixel formats to directly support more external file and hardware framebuffer types
  • Automatically rescaling vertex normals changed by the ModelView matrix. In some cases, rescaling can replace a more expensive renormalization operation.
  • Application of specular highlights after texturing for more realistic lighting effects
  • Texture coordinate edge clamping to avoid blending border and image texels during texturing
  • Level of detail control for mipmap textures to allow loading only a subset of levels. This can save texture memory when high-resolution texture images aren't required due to textured objects being far from the viewer.
  • Vertex array enhancements to specify a subrange of the array and draw geometry from that subrange in one operation. This allows a variety of optimizations such as pretransforming, caching transformed geometry, etc.
  • The concept of ARB-approved extensions. The first such extension is GL_ARB_imaging, a set of features collectively known as the Imaging Subset, intended for 2D image processing. Check for the extension string to see if this feature is available.

OpenGL 1.2.1 adds a second ARB-approved extension, GL_ARB_multitexture, which allows multiple texture maps to be applied to a single primitive. Again, check for the extension string to use this extension.

23.040 How can I code for different versions of OpenGL?

Because a feature or extension is available on the OpenGL development environment you use for building your app, it doesn't mean it will be available for use on your end user's system. Your code must avoid making feature or extension calls when those features and extensions aren't available.

When your program initializes, it must query the OpenGL library for information on the OpenGL version and available extensions, and surround version- and extension-specific code with the appropriate conditionals based on the results of that query. For example:

#include <stdlib.h>
   …
int gl12Supported;

gl12Supported = atof(glGetString(GL_VERSION)) >= 1.2;
   …
if (gl12Supported) {
   // Use OpenGL 1.2 functionality
}

23.050 How can I find which extensions are supported?

A call to glGetString(GL_EXTENSIONS) will return a space-separated string of extension names, which your application can parse at runtime.

23.060 How can I code for extensions that may not exist on a target platform?

At runtime, your application can inquire for the existence of a specific extension using glGetString(GL_EXTENSIONS). Search the list of supported extensions for the specific extension you're interested in. For example, to see if the polygon offset extension interface is available, an application might say:

#include <string.h>
   …
const GLubyte *str;
int glPolyOffExtAvailable;

str = glGetString (GL_EXTENSIONS);
glPolyOffExtAvailable = (strstr((const char *)str, "GL_EXT_polygon_offset")
      != NULL);

Your application can use the extension if it's available, but it needs a fallback plan if it's unavailable (i.e., some other way to obtain the same functionality).

If your application code needs to compile on multiple platforms, it must handle a development environment in which some extensions aren't defined. In C and C++, the preprocessor can protect extension-specific code from compiling when an extension isn't defined in the local development environment. For example:

#ifdef GL_EXT_polygon_offset
   glEnable (GL_POLYGON_OFFSET_EXT);
   glPolygonOffsetEXT (1., 1./(float)0x10000);
#endif /* GL_EXT_polygon_offset */

23.070 How can I call extension routines on Microsoft Windows?

Your application may find some extensions already available through Microsoft's opengl32.lib. However, depending on your OpenGL device and device driver, a particular vendor-specific extension may or may not be present at link time. If it's not present in opengl32.lib, you'll need to obtain the address of the extension's entry points at run time from the device's ICD.

Here's an example code segment that demonstrates obtaining function pointers for the ARB_multitexture extension:

/* Include the header that defines the extension. This may be a vendor-specific
   .h file, or GL/glExt.h as shown here, which contains definitions for all
   extensions. */
#include "GL/glExt.h"

/* Declare function pointers */
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;

…
    /* Obtain the address of the extension entry points. */
    glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)
        wglGetProcAddress("glActiveTextureARB");
    glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)
        wglGetProcAddress("glMultiTexCoord2fARB");

After you obtain the entry point addresses of the extension functions you wish to use, simply call through them as normal function pointers:

    /* Set texture unit 0 min and mag filters */
    (*glActiveTextureARB) (GL_TEXTURE0_ARB);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
…
    /* Draw multi textured quad */
    glBegin (GL_QUADS);
      (*glMultiTexCoord2fARB) (GL_TEXTURE0_ARB, 0.f, 0.f);
      (*glMultiTexCoord2fARB) (GL_TEXTURE1_ARB, 0.f, 0.f);
        glVertex3f (32.f,32.f, 0.f);
 …
    glEnd();

More information on wglGetProcAddress() is available through the MSDN documentation.

23.080 How can I call extension routines on Linux?

Like Microsoft Windows (and unlike proprietary UNIX implementations), an extension entry point may or may not be defined in the static link library. At run time, a Linux application must load the function's address, and call through this function pointer.

Linix uses the OpenGL ABI.

23.090 Where can I find extension enumerants and function prototypes?

See the OpenGL extension registry.