Wiki

Clone wiki

glLoadGen / Style_Pointer_CPP

The pointer_cpp style is designed to work well in C++. Where pointer_c maximizes interoperability with other systems (it defines global functions with the expected C names), pointer_cpp is primarily about making it easy for intellisense and the like to find the function definitions for easy work.

With the exception of the typedefs, everything lives in a C++ namespace based on each spec: gl, wgl, and glX (the same names that would have gone on the front of the function names). If the -prefix option was provided, then the spec namespace will itself be within a namespace named for the prefix.

The extension variables are in their own namespace: <prefix>::<spec>::exts. The type of the variable is not a mere bool; it is an exts::LoadTest. This type is convertible to bool (via the safe-bool idiom, so no need to worry about that), but it also has a function to see how many functions failed to load for that extension. It will always report that it loaded if the extension string is in the spec; the exts::LoadTest::GetNumFailed() will return the number of functions that failed to load (if any).

The enumerators are actual C++ enums now. There is no enumeration name; all of the enums live in one big enumeration. Because the enumerators are namespace-qualified now, there is no need to put the (W)GL(X)_ in front of them. So we do not. However, this causes two problems:

  1. Some enumerators (2D, for example. Yes, that is an OpenGL enumerator; it's for feedback rendering) begin with characters that C++ doesn't allow as identifiers. Thus, these enumerators are prefixed with an "_" character. So 2D becomes _2D.
  2. Certain enumerators use widely used by OS's for various things. Windows for example #defines TRUE and FALSE, among others. There's no automated way to detect this, so there's just a list of the known ones. The C++ standard states that all identifiers that begin with an underscore followed by a capital letter are reserved for the standard library. So we cannot prefix them with an underscore; instead, we suffix them with one. So TRUE becomes TRUE_.

The functions are function pointers, but their names are not hidden behind a #define. This should allow code-completion tools to be more useful. They also aren't prefixed with (w)gl(X), since they live in a namespace.

The system functions (the function that loads the function pointers, version getting, etc) are contained in the <prefix>::<spec>::sys namespace. The loader function will always be called LoadFunctions. It returns an ext::LoadTest, which works as above. It will only be false if it couldn't even attempt to load functions (due to being unable to get the extension string). The number of functions that failed to load refers to the core functions (and core extension functions).

Example

This example is for loading the OpenGL functions; it expects the OpenGL header to be included. For loading WGL/GLX functions, include their headers and change the "gl" namespaces to "wgl" or "glx" as appropriate.

//Create OpenGL context and make it current.

gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
if(!didLoad)
{
  //The context cannot work with the generated headers for some reason. Abort.
  //Destroy the context
  return;
}

printf("Number of functions that failed to load: %i.\n", didLoad.GetNumMissing());

The presence of extensions can be checked as follows:

if(gl::exts::var_EXT_texture_compression_s3tc)
  gl::CompressedTexSubImage2D(gl::TEXTURE_2D, 0, 0, 0, 256, 256,
    gl::COMPRESSED_RGBA_S3TC_DXT5_EXT, compressedSize, compressedPixels);
else
{
  void *decompressedPixels = DecompressPixels(256, 256,
    compressedSize, compressedPixels);

  gl::TexSubImage2D(gl::TEXTURE_2D, 0, 0, 0, 256, 256,
    gl::RGBA, gl::UNSIGNED_BYTE, decompressedPixels);
  free(decompressedPixels);
}

Versions

When you use this system and provide a version number of OpenGL, pointer_cpp will assume that you are serious about that version number. Which means that if you create a 3.3 header, and you do not supply a context that claims support for at least OpenGL version 3.3, loading failure may occur.

In particular, OpenGL changed the mechanism to check for the presence/absence of extensions in version 3.0. Therefore, pointer_cpp will also change how it checks for the presence/absence of extensions based on that. If you provide a version 3.0 or greater, it will use the new style. Thus, if your context is only version 2.1, then this style will be unable to function and will return LOAD_FAILED.

Compatibility

These headers are "compatible" with headers from other libraries (FreeGLUT, GLFW, etc), but only in the sense that they define the appropriate typedefs globally. If any of these headers have inline functions that make calls into GL, expecting functions to be named in the standard GL style, then they're in trouble. Also, these headers prevent the later inclusion of gl.h and similar headers, so that kind of code will likely complain.

If you're using some kind of hybrid like this, you need to create an insulation layer between those inline functions and the appropriate typedefs.

Updated