-style command line option defines how the header and source files are generated. They will always generate the same information (more or less); the difference between styles explains the form that this information takes. The information generated is:
- Typedefs for OpenGL types (
- A means to tell whether each of the extensions specified by the user is loaded or not. This is usually exposed via a global variable who's name contains the extension name.
- The enumerators for all of the extensions specified as well as any specified OpenGL versions/profiles (where applicable).
- Functions (whether function pointers or something else, that's up to the style) for the various extensions specified, as well as any specified OpenGL versions/profiles (where applicable).
- A function that will load all function pointers. Even if the style uses static linking, a function will still be provided. Until this function is called, you cannot use any of the mechanisms to test whether an extension is loaded, nor can you call any other functions.
The function's return value will be a status code saying whether it succeeded. Success is defined solely in terms of loading the specified core OpenGL version; therefore, WGL or GLX loader functions will always "succeed". Test for individual extensions if you want to know what happened there.
- Optionally, if using the OpenGL specification, the style will export a number of useful helper functions to query OpenGL version information. This is per-style.
The different types of styles will decide what form these take (enumerators could be
const variables of some kind instead of the usual
#defines, for example). But each style must provide this set of information.
There are a number of styles available, with documentation explaining exactly what they generate:
pointer_c: Function-pointer-based style for C. It is the most widely compatible, comparable to GLEW. It has variables to test whether an extension was loaded (and how many of its functions were loaded). Like GLEW, it requires calling an initialization function to set it up. This is best used for C or C++ users who need to be able to share the headers with other tools (note: usually, you don't need to do this).
pointer_cpp: Function-pointer-based style for C++. It wraps all function pointers, extension variables, and enumerators in a namespace (not the typedefs). It requires calling an initialization function to set it up. This is best used for C++ users who don't need compatibility, but would like OpenGL stuff to not pollute the global namespace so much.
func_cpp: Inline-function-based style for C++. This means that the header contains actual inline functions, which forward their parameters to the actual function pointers internally. Like
pointer_cpp, most of OpenGL is in a namespace. This is best used for C++ users who want the best possible autocompletion from their IDE or coding tool of choice.
noload_c: Automatic loading style for C. This is similar to the old loading tool GLee. Unlike the other styles, it does not require an initialization function; you simply call whatever function you want to use. The first time a call is encountered, it will load that function. This is best used for C or C++ users who don't want to do explicit initialization, and also want header compatibility like
noload_cpp: Automatic loading style for C++. This is similar to the old loading tool GLee. Unlike the other styles, it does not require an initialization function; you simply call whatever function you want to use. The first time a call is encountered, it will load that function. It will wrap most of OpenGL in a namespace. This is best used for C++ users who don't want to do explicit initialization.
OpenGL 3.0 introduced the concept of "core extensions." Normally with extensions, even ARB extensions, the enumerators, functions and typedefs end in the extension type suffix: ARB, EXT, etc. This allows any extension that is to be inducted into the core to have its behavior modified where necessary.
With GL 3.0, the ARB changed things by making certain extensions core extensions. These are extensions where their declarations don't have the extension suffix. This represents APIs that do not change between extension and core. As such, the enums/functions/etc are considered part of both the extension and a version of OpenGL.
Core extensions are special in that part of OpenGL is effectively in an extension. For example, ARB_uniform_buffer_object is a core extension; all of the functions/enums it defines are part of GL 3.1 as well as the extension.
Because of this, it is possible to ask for GL 3.1 (which will provide those functions/enums) and ARB_uniform_buffer_object at the same time. Or to ask for GL 3.0 (where it isn't core) and ARB_uniform_buffer_object. Or to ask for GL 3.1 without explicitly asking for ARB_uniform_buffer_object.
The way this works is as follows. If you explicitly ask for an extension, the system will always provide you a way to query whether that extension is loaded. If you don't ask for the extension, but the version number effectively requires that extension (asking for GL 3.1+ requires ARB_uniform_buffer_object), you'll still get the enums and functions, but you won't get a way to query whether that extension specifically is loaded.
In short, if you want GL 4.2, but you want to verify whether particular parts are "available," (ie: if you only get GL version 4.1, but there are 4.2 features exposed via extensions), you must explicitly request each extension.
The compatibility profile complicates code generation a bit. The system will do its best to cull inappropriate enumerators/functions based on core/compatibility.
However, this may not be possible in every case. For example, take the
GL_QUADS enumerator. This enumerator was defined way back in GL 1.1. But 3.1 removed it, so if you ask for a 3.1 core header, you shouldn't get
The problem is that it didn't stay removed. GL 4.0/ARB_tessellation_shader brought it back (though only as a tessellation target). Which means if you ask for a 3.1 core header it should be gone, but if you ask for a 3.1 core header that includes ARB_tessellation_shader, it should return. As it should if you ask for a 4.1 core header (with or without ARB_tessellation_shader).
This system cannot due that, primarily because the source of the OpenGL specification information (the .spec files, as processed through various scripts) does not provide enough information. The spec files only define what is core or compatibility in the current OpenGL version, not what used to be core for a while, then was only in compatibility, then came back into core.
Therefore, the system errs on the side of being inclusive. If it came back into core, it is considered to have never left core OpenGL. Thus, if you ask the system for 3.1, core profiles, you will see
GL_QUADS, as well as a few others. The number of these are rather few, so it should not be a problem.
The style mechanism is designed to be extensible. You should be able to write new styles relatively painlessly. This system is covered in some detail. The general idea is that you write a Lua script that exposes a number of functions. Then you hook this script into the build system by adding a line of code to one of the files. At which point, you're done. Making the style script is the hard part.