Paula Womack September 29, 1995 A. SPECIFICATION Is there already an extension that does what I want? The specifications for extensions that have already been proposed by licensees can be obtained from sgiblab.sgi.com. via ftp using the opengl_l account. (Get the tar file extension_info.tar.Z.) Check out the extensions here before creating your own. There may be another licensee working on a similar extension. Some of the extension specifications are also available to the public on sgigate (using anonymous ftp). Look in pub/opengl/extensions. What is the best way to create a new extension? The best way to create a new extension is to first write a specification. A template can be found in the extension_info.tar.Z file. It is important to think about all the different areas of the OpenGL (and maybe GLX) specification that are affected. (For example, if you are defining a new attribute, can it be pushed and popped? How do you read back the values?) The template can help you with this. syntax.rules is also included in extension_info.tar.Z. Your extension should follow the OpenGL syntax guidelines. All the new names introduced by the extension should have a vendor-specific suffix appended to them. (e.g., glNewCommandSGI or glXNewCommandSGI) If another licensee agrees to support the extension, or if the ARB approves the extension, then the EXT designation can be used. How do I name my extension? All extensions must be named and the name should be included in the extension specification. The extension name must have the vendor-specific acronym or EXT prepended to the front. (e.g., SGI_new_extension or EXT_new_extension) If the extension modifies OpenGL then the token GL_ (e.g., GL_SGI_new_extension or GL_EXT_new_extension) must be included in the extension string that is returned by glGetString and it also must be defined in gl.h (or an include file that gl.h includes). If the extension modifies GLX then the token GLX_ (e.g., GLX_SGI_new_extension or GLX_EXT_new_extension) must be included in the extension string that is returned by glXQueryExtensionsString, glXGetClientString, and glXQueryServerString (See below for a description of the different routines) and it also must be defined in glx.h (or an include file that glx.h includes). Note that extensions can have both OpenGL components and windowing system components. For example, the SGI multisampling extension modifies both GLX and OpenGL. In this case there will be two tokens associated with the extension (e.g., GL_SGIS_multisample and GLX_SGIS_multisample) and the extension will be advertised by both OpenGL and GLX. What else do I need to do? SGI keeps a registry of enumerated type values, GLX codes (vendor private opcodes, vendor private with reply opcodes, new visual attribute type values, GLX error codes and GLX event codes), OpenGL rendering codes for GLX, OpenGL rendering codes for gls and extension numbers. If an extension defines new enumerated types then you need to register a block of values from SGI (they are allocated in blocks of 16). If an extension defines new OpenGL rendering commands then you need to register gls rendering codes for it. Also, if you want the extensions to work with the X windowing system (i.e., with GLX), then you need to request some GLX opcodes and define GLX protocol for it. All new extensions should have a number associated with them for documentation purposes. If an extension depends on another extension, the other extension must have a lower number. (Note that when an extension is deprecated the number associated with it is not reassigned.) This number must also be registered with SGI. It is a good idea to include the new enumerated values, GLX codes and extension number in the specification. Once you have completed the extension, you should consider making it available to other licensees by mailing it to opengl-licensees@sgi.com. SGI will then include the new extension in the extension_info.tar file on sgiblab.sgi.com. B. IMPLEMENTATION Errors: Whenever possible, extensions should use existing errors instead of defining new error returns. For GLX, if a new protocol error is introduced, then a error number must be registered with SGI. Vendors may ship a single OpenGL library, containing extensions, for a variety of platforms. It is possible that some of the extension routines defined in the library may not be supported on some of the platforms. If this is the case and an application calls a routine that is not supported by the current OpenGL renderer then a GL_INVALID_OPERATION error should be returned. Extension availability: OpenGL extensions must be advertised in the extension string returned by glGetString. Note that in a client-server environment, this call returns the set of extensions that can be supported on the connection. GLX client libraries must send a glXClientInfo request to the server at start up time (if the client libarary is 1.1 or later) indicating the version of the client library and the the OpenGL extensions that it supports. Then, when glGetString is called, the client issues a GetString request. The server intersects the set of extensions that the client supports with the set of extensions that it supports (if a glXClientInfo request was never received then the server assumes that the client supports no OpenGL extensions) and returns the result to the client. The client library then appends any client-side only extensions to the list and returns the result. Extension names for OpenGL extensions recognized by libGL.x must be defined in gl.h, or a header file that gl.h includes (e.g., #define GL_SGI_new_extension) GLX client-side extensions must be advertised in the extension string returned by glXGetClientString(); server-side extensions must be advertised in the extension string returned by glXQueryServerString(). glXQueryExtensionsString() returns the list of extensions that can be supported on the connection. If the server supports GLX version 1.1 or greater then the client issues a glXQueryServerString request, intersects the returned string with the set of extensions it can support and then appends any client-side only extensions to the list. Extension names for OpenGL extensions recognized by libGL.x must be defined in glx.h, or a header file that glx.h includes (e.g., #define GLX_SGI_new_extension) C. USING EXTENSIONS Programmers that wish to use a particular OpenGL extension should check both compile-time defines (to ensure that the extension is supported by the library they are compiling against) and the extension string returned by glGetString (to ensure that the renderer supports the extension). For example, the following code could be used to check whether the renderer supports an OpenGL extension called GL_EXT_new_extension. This code would need to be executed after the context had been made current: static GLboolean CheckExtension(char *extName, const char *extString) { /* ** Search for extName in the extensions string. Use of strstr() ** is not sufficient because extension names can be prefixes of ** other extension names. Could use strtok() but the constant ** string returned by glGetString can be in read-only memory. */ char *p = (char *)extString; char *end; int extNameLen; extNameLen = strlen(extName); end = p + strlen(p); while (p < end) { int n = strcspn(p, " "); if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) { return GL_TRUE; } p += (n + 1); } return GL_FALSE; } const GLubyte *ext_string; int new_ext_supported = GL_FALSE; if ( CheckExtension("GL_EXT_new_extension", glGetString(GL_EXTENSIONS)) ) new_ext_supported = GL_TRUE; If the renderer supports the extension, then it is safe to use it at runtime. (Note that in a client-server environment, glGetString will only return the set of extensions that can be supported by the client and server.) However, compile time checks must be made to ensure that the library that you are linked against supports the extension. For example: #ifdef GL_EXT_new_extension if (new_ext_supported) glNewExtensionEXT(...) #endif Before using a GLX extension, programmers should check the compile time defines and the extension string returned by glXQueryExtensionsString. Since glXQueryExtensionsString, is only available in GLX versions 1.1 and later, programmers must also check the GLX version. For example, the following code could be used to check whether an extension called GLX_EXT_new_extension can be used on the connection. This code would need to be executed after the connection had been opened and the existence of the GLX extension had been established. Display *dpy; int new_ext_supported = GL_FALSE; int major, minor, screen; if( !glXQueryVersion(dpy, &major, &minor) ) exit(1); screen = DefaultScreen(dpy); #ifdef GLX_VERSION_1_1 if ( minor > 0 || major > 1 ) if ( CheckExtension("GLX_EXT_new_extension", glXQueryExtensionsString(dpy, screen)) ) new_ext_supported = GL_TRUE; #endif If the extension is supported on the connection, then it is safe to use it at runtime. However, compile time checks must be made to ensure that the library that you are linked against supports the extension. For example: #ifdef GLX_EXT_new_extension if (new_ext_supported) glNewExtensionEXT(...) #endif