Approved June 20, 2000
Editor: Jon Leech, SGI
Version 1.0 is complete. It was approved on June 20, 2000; all submitted votes were in favor.
1.1. This document is intended to solve two related problems. First, defining the ABI and runtime environment for applications using OpenGL under X11 on Linux. This will enable applications using the OpenGL API for rendering to run on a variety of underlying implementations transparently. The intent is to address all of open source, commercial closed binary, OpenGL SI-based, and Mesa-based implementations.
Second, defining the SDK for developing apps using OpenGL. This includes header file locations, conventions for use of extensions, etc.
It has similar goals to the Linux Standard Base, but focused much more narrowly: on the OpenGL API. Representatives from LSB are involved and ultimately this effort should be part of LSB.
We do not exactly track all LSB practice (particularly naming conventions for libraries) because LSB itself is not complete, and because existing practice with other OpenGL implementations suggests preferred methods which may differ from LSB.
1.2. Things we do not attempt to address include:
1.3. We believe all critical decisions have been made. Some remaining comments (previously identified as open issues) of interest are identified in the appendix. We recognize that some decisions are largely arbitrary (filenames and file locations, for example) and in those cases have been guided by existing practice (in other words, complaining about arbitrary decisions is unlikely to change them).
1.4. Participants in this effort to date include people working at or involved with the following companies and open source projects (as well as a large number of individuals with unknown affiliations):
3Dfx, Alias/Wavefront, Apple, Avid, Compaq, Debian, HP, IBM, Intel, Linux Standard Base, Loki Games, Mesa, Metro Link, NVIDIA, Nichimen, Parametric Technology Corporation, Precision Insight, SGI, Sharp Eye, Sun, XFree86, Xi Graphics.
2.1. OpenGL already includes its own datatypes (GLint, GLshort, etc.) used in the API. Guaranteed minimum sizes are stated (see table 2.2 of the OpenGL 1.2 Specification), but the actual choice of C datatype is left to the implementation. For our purposes, however, all implementations on a given binary architecture must have common definitions of these datatypes.
For the IA32 architecture, the definitions should be:
|GL datatype||Description||gcc equivalent for IA32|
|GLboolean||8-bit boolean||unsigned char|
|GLbyte||signed 8-bit 2's-complement integer||signed char|
|GLubyte||unsigned 8-bit integer||unsigned char|
|GLshort||signed 16-bit 2's-complement integer||short|
|GLushort||unsigned 16-bit integer||unsigned short|
|GLint||signed 32-bit 2's-complement integer||int|
|GLuint||unsigned 32-bit integer||unsigned int|
|GLsizei||non-negative 32-bit binary integer size||int|
|GLenum||enumerated 32-bit value||unsigned int|
|GLbitfield||32 bit bitfield||unsigned int|
|GLfloat||32-bit IEEE754 floating-point||float|
|GLclampf||Same as GLfloat, but in range [0, 1]||float|
|GLdouble||64-bit IEEE754 floating-point||double|
|GLclampd||Same as GLdouble, but in range [0, 1]||double|
2.2. Assembly-level call conventions must be shared. Since the OpenGL implementation may use C++ code internally (e.g. for GLU), this is potentially a serious problem. Static linking of C++ libraries used by OpenGL libraries may be required of the implementation (also see the Libraries section below).
3.1. There are two link-level libraries. libGL includes the OpenGL and GLX entry points and in general depends on underlying hardware and/or X server dependent code that may or may not be incorporated into this library. libGLU includes the GLU utility routines and should be hardware independent, using only the OpenGL API.
Each library has two names: the link name used on the ld command line, and the DT_SONAME within that library (specified by the -soname switch when linking the library), defining where it's looked up at runtime. Both forms must exist so that both linking and running will operate properly. The library names are:
|Link name||Runtime name (DT_SONAME)|
libGL.so and libGLU.so should be symbolic links pointing to the runtime names, so that future versions of the standard can be implemented transparently to applications by changing the link.
3.2. These libraries must be located in /usr/lib. The X-specific library direction (/usr/lib/X11) was also considered, but existing practice on Linux and other platforms indicates that /usr/lib is preferable.
3.3. C++ runtime environments are likely to be incompatible cross-platform, including both the standard C++ library location and entry points, and the semantics of issues such as static constructors and destructors. The LSB apparently mandates static linking of libraries which aren't already in LSB, but this could lead to problems with multiple C++ RTLs present in the same app using C++. We'll have to tread carefully here until this issue is more completely understood.
3.4. The libraries must export all OpenGL 1.2, GLU 1.3, GLX 1.3, and ARB_multitexture entry points statically.
It's possible (but unlikely) that additional ARB or vendor extensions will be mandated before the ABI is finalized. Applications should not expect to link statically against any entry points not specified here.
3.5. Because non-ARB extensions vary so widely and are constantly increasing in number, it's infeasible to require that they all be supported, and extensions can always be added to hardware drivers after the base link libraries are released. These drivers are dynamically loaded by libGL, so extensions not in the base library must also be obtained dynamically.
3.6. To perform the dynamic query, libGL also must export an entry point called
void (*glXGetProcAddressARB(const GLubyte *))();
The full specification of this function is available separately. It takes the string name of a GL or GLX entry point and returns a pointer to a function implementing that entry point. It is functionally identical to the wglGetProcAddress query defined by the Windows OpenGL library, except that the function pointers returned are context independent, unlike the WGL query.
All OpenGL and GLX entry points may be queried with this extension; GLU extensions cannot, because GLU is a client-side library that cannot easily be extended.
3.7. Thread safety (the ability to issue OpenGL calls to different graphics contexts from different application threads) is required. Multithreaded applications must use -lpthread.
3.8. libGL and libGLU must be transitively linked with any libraries they require in their own internal implementation, so that applications don't fail on some implementations due to not pulling in libraries needed not by the app, but by the implementation.
4.1. The following header files are required:
These headers should properly define prototypes and enumerants for use by applications written in either C or C++. Other language bindings are not addressed at this time.
4.2. These header files must be located in /usr/include/GL. /usr/include/X11/GL was considered and rejected for the same reasons as library locations in section 3.2 above.
4.3. The required headers must not pull in internal headers or headers from other packages where that would cause unexpected namespace pollution (for example, on IRIX glx.h pulls in <X11/Xmd.h>). Likewise the required headers must be protected against multiple inclusion and should not themselves include any headers that are not so protected. However, glx.h is allowed to include <X11/Xlib.h> and <X11/Xutil.h>.
4.4. glx.h must include the prototype of the glXGetProcAddressARB extension described above.
4.5. All OpenGL 1.2 and ARB_multitexture, GLU 1.3, and GLX 1.3 entry points and enumerants must be present in the corresponding header files gl.h, glu.h, and glx.h, even if only OpenGL 1.1 is implemented at runtime by the associated runtime libraries.
4.6. Non-ARB OpenGL extensions are defined in glext.h, and non-ARB GLX extensions in glxext.h. If these extensions are also defined in one of the other required headers, this must be done conditionally so that multiple definition problems don't occur.
4.7. Vendor-specific shortcuts, such as macros for higher performance GL entry points, are intrinsically unportable. These should not be present in the required header files, but instead in a vendor-specific header file that requires explicit effort to access, such as defining a vendor-specific preprocessor symbol. Likewise vendors who are not willing to include their extensions in glext.h must isolate those extensions in vendor-specific headers.
4.8. gl.h must define the symbol GL_OGLBASE_VERSION. This symbol must be an integer defining the version of the ABI supported by the headers. Its value is 1000 * major_version + minor_version where major_version and minor_version are the major and minor revision numbers of this ABI standard. The primary purpose of the symbol is to provide a compile-time test by which application code knows whether the ABI guarantees are in force.
5.1. Providing prototypes and enumerants for OpenGL extensions is challenging because of the expected wide variety of hardware drivers, continuing creation of extensions, and multiple sources of header files on Linux OpenGL implementations. Some extensions will be supported only for a specific implementation, and some will be supported only for a specific hardware driver within that implementation. This situation does not lend itself easily to independent maintenance of header files definining the extensions.
Instead, we require a single header file defining all OpenGL extensions be supplied from a central point and updated on a continuing basis as new extensions are added to the OpenGL extension registry (which is similarly centrally maintained). The central point is in the registry at http://www.opengl.org/registry/.
The latest version of glext.h is available in the registry. It is automatically generated from the master OpenGL function and enumerant registries, and is updated as new extensions are registered. The header is intended to be useful on other platforms than Linux, particularly Windows; please let us know (via feedback to OpenGL.org forums) if it needs enhancement for use on another platform. The generator scripts and ".spec" files used in generating glext.h are also available.
Likewise for GLX, a single header defining all GLX extensions, glxext.h, is required and is maintained centrally.
The registry also contains a header defining WGL extensions, wglext.h, but this is only for use on Windows; wglext.h is not required by or useful for the Linux ABI.
5.2. The centrally maintained glext.h will be continually updated, so version creep is expected. This could cause problems for open source projects distributing source code. The proper solution is for users to update glext.h to the latest version, but versioning has proven helpful with other extensible aspects of OpenGL. Therefore glext.h must include a preprocessor version symbol GL_GLEXT_VERSION, enabling apps to do something like:
#if GL_GLEXT_VERSION < 42
#error "I need a newer <GL/glext.h>. Please download it from http://www.opengl.org/registry/ABI/"
5.3. Only extensions whose fully documented specifications have been made available to the extension registry and whose authors have committed to shipping them in their drivers will be included in glext.h and glxext.h. The structure of each extension defined in these headers should resemble:
#define GL_EXT_extensionname 1
Define enumerants specific to this extension
Typedef function pointers for entry points specifically to this extension, dynamically obtained with glXGetProcAddressARB
Define prototypes specific to this extension
Benign redefinition of the enumerants is allowable, so these may be outside protective #ifndef statements (this structure results from the generator scripts used in the OpenGL SI to build glext.h, and also because some enums may be defined by multiple different extensions, so it could make sense to segregate them).
Function pointer typedefs will use the Windows convention (e.g. the typedef for a function glFooARB will be PFNGLFOOARBPROC) for application source code portability.
Normally, prototypes are present in the header files, but are not visible due to conditional compilation. To define prototypes as well as typedefs, the application must #define GL_GLEXT_PROTOTYPES prior to including gl.h or glx.h. (Note: consistency suggests using GLX_GLXEXT_PROTOTYPES for glxext.h - TBD).
The preprocessor symbol protecting the extension declaration must be the same as the name string identifying the extension at runtime and in the extension registry.
All OpenGL and GLX extensions that are shipping should have a full extension specification in the master extension registry on www.opengl.org. Vendors failing to document and specify their on extensions will not be allowed to incorporate the resulting inadequate interfaces into the ABI.
5.4. glext.h is normally #includeed by gl.h. This inclusion can be suppressed by the application defining the preprocessor symbol GL_GLEXT_LEGACY prior to its #include <GL/gl.h>.
Similarly, glxext.h is normally #includeed by glx.h. This inclusion can be suppressed by the application defining the preprocessor symbol GLX_GLXEXT_LEGACY prior to its #include <GL/glx.h>.
Since the ABI has been finalized, we are no longer maintaining the oglbase-discuss mailing list used during its development. List archives may still be available from http://www.mail-archive.com/[email protected]/
Section 2.1: Define GL datatypes for other supported Linux architectures - Alpha, PowerPC, MIPS, etc. (in general these will be identical to the IA32 types). Note: we may want to suggest GLlong and GLulong as 64-bit datatypes for future OpenGL revisions.
Section 2.2: C++ libraries at runtime can be problematic - take the gcc/egcs split, for example. Another potential problem area is static constructor/destructor issues, e.g. when a C main() is linked against GLU. Some tweaking may be required as apps running against different ABI revisions start appearing.
Section 3.1: LSB uses a more complex naming convention for libraries; we're avoiding this at least for now, because these conventions disagree with common practice on virtually all other Unix OpenGL implementations.
Section 3.2 (also Section 4.1): Placing the headers and libraries in non-X11 specific locations could impact non-GLX OpenGL implementations resident on the same platform. It is also somewhat out of keeping with other X extensions. However, this practice is so common on other platforms, and non-X based OpenGL implementations are so rarely used, that we chose to do so for build portability and "principle of least surprise" purposes.
Nothing prohibits the implementation from placing the actual library files in other locations and implementing the required library paths as links.
Section 3.6: The context-independence requirement was the subject of enormous controversy, mostly because the consequences of this requirement on the underlying link library and driver implementations can be significant. It is impossible to briefly recap the many pro and con arguments briefly; refer to the mailing list archive to learn more.
GLU does sometimes need to be extended to properly support new GL extensions; in particular, new pixel formats and types, or new targets for texture downloads, such as cube mapping, should ideally be exposed through the GLU mipmap generation routines. This is an unresolved problem, since GLU is client code not specific to any GL driver and thus not dynamically loadable. The best current option is for driver suppliers to make sure that whatever GLU functionality they need is contributed to the OpenGL Sample Implementation's GLU library.
Portable applications should treat the pointers as context-dependent.
We haven't determined if any non-ARB extensions should be standard entry points not requiring this dynamic lookup. As a reference point, here are lists of GL, GLX, and GLU extensions supported by a variety of OpenGL and Mesa implementations today (please send additions for other platforms to the oglbase-discuss mailing list so they can be added):
Section 4.5: Implementations may still implement only OpenGL 1.1 functionality, but the 1.2 header and link library material must still be provided. Since applications must already check both compile and runtime OpenGL version numbers, no problems due to lacking support for 1.2 are expected. The next version of this standard is anticipated to require OpenGL 1.2 support.
Section 4.6: It's important that glext.h and glxext.h can be updated from the extension registry without breaking gl.h and glx.h. Making sure that all extension definitions are properly protected helps to this end, as well as being good programming practice.
Section 4.8: GL_OGLBASE_VERSION is mostly provided so that apps can determine whether to use traditional static linking of extensions, or to dynamically query them. Unlike GL/GLX versioning, the ABI version is not dynamically queryable at runtime. Historical experience suggests that not providing the runtime query to begin with is a bad decision.
Section 5.2: Applications should not use the version number in glext.h to test for presence or absence of specific extension prototypes; this is extremely unportable and dangerous. Always use the extension-specific symbols described in section 5.3.
The header version symbol was changed from GL_GLEXT_VERSION_EXT to GL_GLEXT_VERSION for consistency with the GLEXT namespace the ABI group has started using.
Section 5.3: Other structures for the extension prototypes have been suggested, such as having separate header files for each extension. Having both structures may be preferable, but it requires more work.
Section 5.4: It's important to be able to suppress automatic inclusion of glext.h and glxext.h in order to support compilation of legacy code not written to be ABI-aware (e.g. assuming that extensions can be statically linked).