The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers


2 Getting Started

Please refer to the Getting Started Wiki pages for more up-to-date information.

2.005 Where can I find 3D graphics info?

The FAQ contains 3D graphics information that isn't specific to OpenGL.

For general OpenGL and 3D graphics information, OpenGL API Code and Tutorial Listings is a good online source of information.

An excellent general computer graphics text is Computer Graphics: Principles and Practice, Second Edition, by James Foley, et al. ISBN 0-201-12110-7. This book may be out of print, however, some online book retailers still seem to have it for sale. Try There may be a third edition planned for release in January 2001

Here's a source for linear algebra source code.

2.010 Where can I find examples, tutorials, documentation, and other OpenGL information?

OpenGL is the most extensively documented 3D graphics API to date. Information is all over the Web and in print. It would be impossible to exhaustively list all sources of OpenGL information. This FAQ therefore provides links to large storehouses of information and sites that maintain many links to other OpenGL sites.

OpenGL Basics FAQ

Samuel Paik has created a large repository of links to OpenGL information on Microsoft Web sites.

The Registry has the current OpenGL specification and manual pages.

A repository of OpenGL implementations for several platforms

The GLUT source code distribution contains several informative OpenGL examples and demos.

Lucian Wischik's Web page at contains excellent information on Microsoft Windows OpenGL, especially with 3dfx hardware.

The NeHe Web page has many links to other sites and plenty of useful tutorials. Many people have found this site useful.

An interactive OpenGL tutorial can be found here.

Check for OpenGL tutorials and articles.

Embarcadero Developer Network has a good section on setting up OpenGL in C++ Builder.

Embarcadero Developer Network has a good section on using OpenGL with Delphi

2.020 What OpenGL books are available?

There are several books on OpenGL, but the two most revered are the "red" and "blue" books:

OpenGL Programming Guide, Third Edition, Mason Woo et al.
ISBN 0-201-60458-2 (aka the red book)

OpenGL Reference Manual, Third Edition, Dave Shreiner (Editor), et al.
ISBN 0-201-65765-1 (aka the blue book)

The third edition of these books describes OpenGL 1.2. The original and second editions describe 1.0 and 1.1, respectively.

The OpenGL Org web site has a link to an online version of the 1.1 Programming Guide.

For the OpenGL Reference Manual, here are two sources:

In addition to the red and blue books, see the green book for X Windows programming, and the white book for Microsoft Windows programming. You can obtain a more exhaustive list of OpenGL books by visiting the Book section

2.030 What OpenGL chat rooms and newsgroups are available?

The Usenet newsgroup, devoted to OpenGL programming, is

The IRC channels are on (FreeNode). The main channel is now '##OpenGL' (two hashes) and there's also a '##opengl3' channel specific to OpenGL 3.x development.

2.040 What OpenGL implementations come with source code?

The Mesa library is an OpenGL look-alike. It has an identical interface to OpenGL. The only reason it can't be called "OpenGL" is because its creator hasn't purchased a license from the OpenGL ARB.

2.050 What compiler can I use?

OpenGL programs are typically written in C and C++. You can also program OpenGL from Delphi (a Pascal-like language), Basic, Fortran, Ada, and others.


Programming OpenGL with Borland compilers is the same as with any other compiler, with one exception: OpenGL apps can produce floating point exceptions at run time. To disable these harmless errors, add the following to your app before you call an OpenGL function:

_control87(MCW_EM, MCW_EM);

Borland users need to be aware that versions prior to 4.0 only support OpenGL 1.0 out of the box. Download the OpenGL SDK from Microsoft to use OpenGL v1.1, or v1.2 when it becomes available.

Use Borland's implib utility to generate Borland-compatible .LIB export libraries from Microsoft-compatible .DLL libraries. If you accidently link with Microsoft-format .LIB files, you will receive a linker error like the following:

C:\BORLAND\BCC55\LIB\GLUT32.LIB' contains invalis OMF record, type 0x21 (possibly COOF)

The Usenet news server has two newsgroups that pertain to graphics: and

The Borland Community is an online source of FAQs that address Borland compiler issues.

Code and utilities for using OpenGL through Delphi are available.

Visual Basic

Here are three sites with info on how to use OpenGL through Visual Basic:

2.060 What do I need to compile and run OpenGL programs?

The following applies specifically to C/C++ usage.

To compile and link OpenGL programs, you'll need OpenGL header files and libraries. To run OpenGL programs you may need shared or dynamically loaded OpenGL libraries, or a vendor-specific OpenGL Installable Client Driver (ICD) specific to your device. Also, you may need include files and libraries for the GLU and GLUT libraries. Where you get these files and libraries will depend on which OpenGL system platform you're using. maintains a list of links to OpenGL Utility libraries. You can download most of what you need from there.

Under Microsoft Windows 9x, NT, and 2000:

If you're using Visual C++, your compiler comes with include files for OpenGL and GLU, as well as .lib files to link with.

For GLUT, download these files. Install glut.h in your compiler's include directory, glut32.lib in your compiler's lib directory, and glut32.dll in your Windows system directory (c:\windows\system for Windows 9x, or c:\winnt\system32 for Windows NT/2000).

In summary, a fully installed Windows OpenGL development environment will look like this:

File Location

where [compiler] is your compiler directory (such as c:\Program Files\Microsoft Visual Studio\VC98) and [system] is your Windows 9x/NT/2000 system directory (such as c:\winnt\system32 or c:\windows\system).

If you're on a hardware platform that accelerates OpenGL, you'll need to install the ICD for your device. This may have shipped with your hardware, or you can download it from your hardware vendor's Web page. Your vendor may also provide a replacement or addition for gl.h, which provides definitions and declarations for vendor-specific OpenGL extensions. See the extensions section in this FAQ for more information.

If you see files such as opengl.lib and glut.lib, these are SGI's unsupported libraries for Microsoft Windows. They should not be used. To use hardware acceleration, the Microsoft libraries are recommended. More info on the SGI libraries can be found here. Always link with either all Microsoft libraries (e.g., glu32.lib, glut32.lib, and opengl32.lib) or all SGI libraries (e.g., glu.lib, glut.lib, and opengl.lib). You can't use a combination of both Microsoft libarires and SGI libraries. However, you can install both sets of libraries on the same system. If you use SGI's .lib files, you'll need the corresponding .dll files installed in your system folder. (i.e., linking against opengl.lib requires that opengl.dll is installed at run time).

You'll need to instruct your compiler to link with the OpenGL, GLU, and GLUT libraries. In Visual C++ 6.0, you can accomplish this with the Project menu's Settings dialog box. Scroll to the Link tab. In the Object/library modules edit box, add glut32.lib, glu32.lib, and opengl32.lib to the end of any text that is present.

For UNIX or UNIX-like operating systems:

If you don't find the header files and libraries that you need to use in standard locations, you need to point the compiler and linker to their location with the appropriate -I and -L options. The libraries you link with must be specified at link time with the -l option; -lglut -lGLU -lGL -lXmu -lX11 is typical.

If you want to use GLUT, you need to download it. If you can't find the precompiled binaries, you'll want to download the source and compile it. GLUT builds easily on many platforms, and comes with many README files explaining how to do a build. The GLUT compiler uses the imake utility, which makes it easy to build GLUT on new platforms.

For Linux, Macintosh, and other systems:

Mesa is a free OpenGL-like library that is available on a number of platforms.

2.070 Why am I getting compile, link, and runtime errors?

Most compile and link errors stem from either a system that doesn't have the OpenGL development environment installed correctly, or failure to instruct the compiler where to find the include and library files.

If you are encountering these problems in the Windows 9x/NT/2000 environment, read question 2.060 above to ensure that you've installed all files in their correct locations, and that you've correctly instructed the linker to find the .lib files.

Also, note that you'll need to put an #include <windows.h> statement before the #include<GL/gl.h>. Microsoft requires system DLLs to use a specific calling convention that isn't the default calling convention for most Win32 C compilers, so they've annotated the OpenGL calls in gl.h with some macros that expand to nonstandard C syntax. This causes Microsoft's C compilers to use the system calling convention.  One of the include files included by windows.h defines the macros.

Another caveat for Win32 developers: With Microsoft Visual C++ (and probably most other Win32 C compilers), the standard Win32 application entry point is WinMain with four parameters, rather than main(int argc, char **argv).  Visual C++ has an option to include code to parse the standard Win32 application entry, and call main with a parsed command line; this is called a console application instead of a Win32 application. If you download code from the Net and try to build it, make sure you've configured your compiler to build the right kind of application, either console or Win32. This can be controlled with linker options or pragmas. Microsoft Visual C++ supports the following pragmas for controlling the entry point and application type:

// Use one of: #pragma comment (linker, "/ENTRY:mainCRTStartup") #pragma comment (linker, "/ENTRY:wmainCRTStartup") #pragma comment (linker, "/ENTRY:WinMainCRTStartup") #pragma comment (linker, "/ENTRY:wWinMainCRTStartup") // Use one of: #pragma comment (linker, "/SUBSYSTEM:WINDOWS") #pragma comment (linker, "/SUBSYSTEM:CONSOLE")

The following is a table of errors and their possible causes and solutions. It is targeted toward Microsoft Visual C++ users, but the types of errors can apply, in general, to any platform.

Example error text Possible cause and solution
d:\c++\file.c(20) : warning C4013: 'glutDestroyWindow' undefined; assuming extern returning int
d:\c++\file.c(71) : warning C4013: 'glMatrixMode' undefined; assuming extern returning int
d:\c++\file.c(71) : error C2065: 'GL_MODELVIEW' : undeclared identifier
Didn't #include gl.h, glu.h, or glut.h

A GLUT source file should:
#include <GL/glut.h>
Non-GLUT source files should:
#include <GL/glu.h>
#include <GL/gl.h>

c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2054: expected '(' to follow 'WINGDIAPI'
c:\program files\microsoft visual studio\vc98\include\gl\gl.h(1152) : error C2085: 'APIENTRY' : not in formal parameter list
Didn't #include windows.h or included it after gl.h.

Source files that use neither GLUT nor MFC, but which make calls to OpenGL, should:
#include <windows.h>
#include <GL/gl.h>

d:c++\file.c(231) : warning C4305: 'initializing' : truncation from 'const double ' to 'float ' Floating-point constants (e.g., 1.0) default to type double. This is a harmless warning that can be disabled in Visual C++ with:
#ifdef WIN32
#pragma warning( disable : 4305)
at the top of the source file.
file.obj : error LNK2001: unresolved external symbol __imp__glMatrixMode@4
file.obj : error LNK2001: unresolved external symbol __imp__glViewport@16
file.obj : error LNK2001: unresolved external symbol __imp__glLoadIdentity@0
Didn't link with opengl32.lib, glu32.lib, or glut32.lib.

Section 2.060 above describes how to inform the Visual C++ 6 linker about the location of the .lib files.

The dynamic link library OPENGL.dll could not be found in the specified path.. Failure to correctly install .dll files. See section 2.060 above for information on where these files should be installed for your Windows system.
Nothing renders, just a blank window. Mixed linkage against .lib files from both Microsoft and SGI can cause this. Make sure you specify either glut32.lib, glu32.lib opengl32.lib or glut.lib, glu.lib, and opengl.lib to the linker, but not a combination of the files from these two file sets.
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/test.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
Not an OpenGL question per se, but definitely a FAQ on due to the way GLUT works in Microsoft Windows.

You should instruct your compiler to build a console application. It's trying to find the Win32 entry point, but your code wasn't written as a Win32 application.

Multiple access violations appear when running a Microsoft OpenGL MFC-based application. Set the CS_OWNDC style in the PreCreate*() routines in the view class.
Floating-point exceptions occur at runtime. The application was built with Borland C. Add the following to your app before you call any OpenGL functions:

_control87(MCW_EM, MCW_EM);

This is from Borland's own FAQ article #17197.

2.080 How do I initialize my windows, create contexts, etc.?

It depends on your windowing system. Here's some basic info, but for more details, refer to the documentation for your specific windowing system or a newsgroup devoted to programming in it.


The basic code for creating an RGB window with a depth buffer, and an OpenGL rendering context, is as follows:

#include <GL/glut.h> int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Simple"); /* ... */ }

The calls to set the window size and position are optional, and GLUT uses a default size and location if they are left out.

X Windows

You can create an RGB window with a depth buffer in X Windows using the following code:

#include <GL/glx.h> #include <GL/gl.h> main (int argc, char **argv) { Display display; XVisualInfo *vinfo; XSetWindowAttributes swattr; int attrList[20]; int indx=0; Window wid; GLXContext util_glctx;     if (!(display = XOpenDisplay (""))) exit ();     attrList[indx] = GLX_USE_GL; indx++; attrList[indx] = GLX_DEPTH_SIZE; indx++; attrList[indx] = 1; indx++; attrList[indx] = GLX_RGBA; indx++; attrList[indx] = GLX_RED_SIZE; indx++; attrList[indx] = 1; indx++; attrList[indx] = GLX_GREEN_SIZE; indx++; attrList[indx] = 1; indx++; attrList[indx] = GLX_BLUE_SIZE; indx++; attrList[indx] = 1; indx++;     attrList[indx] = None;     vinfo = glXChooseVisual(display, DefaultScreen(dpy), attrList);     if (vinfo == NULL) { printf ("ERROR: Can't open window\n"); exit (1);     }     swattr.colormap=XCreateColormap (display ,RootWindow (display,vinfo->screen), vinfo->visual, AllocNone);     swattr.background_pixel = BlackPixel (display, vinfo->screen);     swattr.border_pixel = BlackPixel (display, vinfo->screen);     wid = XCreateWindow(display,RootWindow(display, vinfo->screen),           30, 30, width, height, 0, vinfo->depth, CopyFromParent,           vinfo->visual,CWBackPixel | CWBorderPixel | CWColormap, &swattr);     util_glctx = glXCreateContext(display, vinfo, NULL, True);     if (util_glctx == NULL) { printf("glXCreateContext failed \n"); return(-1);     }     if (!glXMakeCurrent(display, wid, util_glctx)) { printf("glXMakeCurrent failed \n"); return(-1);     } }

Microsoft Windows 9x/NT/2000

The window must be created with the following bits OR'd into the window style: WS_CLIPCHILDREN | WS_CLIPSIBLINGS. Do this either when CreateWindow is called (in a typical Win32 app) or during the PreCreateWindow function (in an MFC app).

Once the window is created (when a WM_CREATE message arrives or in the OnInitialUpdate callback), use the following code to set the pixel format, create a rendering context, and make it current to the DC.

// Assume: // HWND hWnd; HDC hDC = GetDC (hWnd); PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = ChoosePixelFormat(hDC, &pfd); if (pixelFormat == 0) { // Handle error here } BOOL err = SetPixelFormat (hDC, pixelFormat, &pfd); if (!err) { // Handle error here } hRC = wglCreateContext(hDC); if (!hRC) { // Handle error here } err = wglMakeCurrent (hDC, hRC); if (!err) { // Handle error here }

You can then make the rendering context noncurrent, and release the DC with the following calls:

WglMakeCurrent(NULL,NULL); ReleaseDC (hWnd, hDC);

2.090 How do I create a full-screen window?

Prior to GLUT 3.7, you can generate a full-screen window using a call to glutFullScreen(void). With GLUT 3.7 and later, a more flexible interface was added.

With glutGameModeString(), an application can specify a desired full-screen width and height, as well as the pixel depth and refresh rate. You specify it with an ASCII character string of the form [width]x[height]:[depth]@[hertz]. An application can use this mode if it's available with a call to glutEnterGameMode(void). Here's an example:

glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutGameModeString("640x480:16@60"); glutEnterGameMode();

2.100 What is the general form of an OpenGL program?

There are no hard and fast rules. The following pseudocode is generally recognized as good OpenGL form.

    // Determine which depth or pixel format should be used.
    // Create a window with the desired format.
    // Create a rendering context and make it current with the window.
    // Set up initial OpenGL state.
    // Set up callback routines for window resize and window refresh.

    // Set projection transform with glOrtho, glFrustum, gluOrtho2D, gluPerspective, etc.


    // Set view transform with gluLookAt or equivalent

    // For each object (i) in the scene that needs to be rendered:
        // Push relevant stacks, e.g., glPushMatrix, glPushAttrib.
        // Set OpenGL state specific to object (i).
        // Set model transform for object (i) using glTranslatef, glScalef, glRotatef, and/or equivalent.
        // Issue rendering commands for object (i).
        // Pop relevant stacks, (e.g., glPopMatrix, glPopAttrib.)
    // End for loop.

    // Swap buffers.

2.110 My window is blank. What should I do?

A number of factors can cause a blank window when you're expecting a rendering. A blank window is generally caused by insufficient knowledge of 3D graphics fundamentals, insufficient knowledge of basic OpenGL mechanisms, or simply a mistake in the code.

There are a number of OpenGL books and online resources as well.

What follows is a list some of the more common causes of the dreaded "Black Window Syndrome" and what to do to fix it.

  • Your application may have made an erroneous call to OpenGL. Make liberal calls to glGetError(). You might create a macro or inline function, which does the following:
{ GLint err = glGetError(); if (err != GL_NO_ERROR) DisplayErrorMessage(); }

Place this code block after suspect groups of OpenGL function calls, and take advantage of the preprocessor, which will ensure that the calls can be eliminated easily in a production compile (i.e., #ifdef DEBUG...#endif).

glGetError() is the only way to tell whether you've issued an erroneous function call at runtime. If an OpenGL function generates an error, OpenGL won't process the offending function. This is often the cause of incorrect renderings or blank windows.

  • Incorrect placement of zFar and zNear clipping planes with respect to the geometry can cause a blank window. The geometry is clipped and nothing is rendered. zFar and zNear clipping planes are parameters to the glOrtho(), gluOrtho2D(), glFrustum(), and gluPerspective() calls. For glFrustum() and gluPerspective(), it's important to remember that the zNear and zFar clipping planes are specified as distances in front of the eye. So, for example, if your eye is at (0,0,0), which it is in OpenGL eye coordinate space, and the zNear clipping plane is at 2.0 and all of your geometry is in a unit cube centered at the origin, the zNear plane will clip all of it and render nothing. You'll need to specify a ModelView transform to push your geometry back, such as a call to glTranslatef(0,0,-3).

Similarly, the zFar clipping plane might be a problem if it is placed at, for example, 10.0, and all of your geometry is further than 10.0 units from the eye.

  • Incorrect transforms in general can cause a blank window. Your code is attempting to set the view and modeling transform correctly, but due to some problem, the net transformation is incorrect, and the geometry doesn't fall within the view volume. This is usually caused by a bug in the code or a lack of understanding of how OpenGL transforms work.

It's usually best to start simple and work your way to more complex transformations. Make code changes slowly, checking as you go, so you'll see where your mistakes came from.

  • Another cause of the blank window is a failure to call glEnd() or failure to call glBegin(). Geometry that you specify with one of the glVertex*() routines must be wrapped with a glBegin()/glEnd() pair to be processed by OpenGL. If you leave out both glBegin() and glEnd(), you won't get an error, but nothing will render.

If you call glBegin(), but fail to call glEnd() after your geometry, you're not guaranteed that anything will render. However, you should start to see OpenGL errors once you call functions (e.g., glFlush()) that can't be called within a glBegin()/glEnd() pair. If you call glEnd() but fail to call glBegin(), the glEnd() call will generate an error. Checking for errors is always a good idea.

  • Failure to swap buffers in a double-buffered window can cause blank windows. Your primitives are drawn into the back buffer, but the window on the screen is blank. You need to swap buffers at the end of each frame with a call to SwapBuffers, glXSwapBuffers, or glutSwapBuffers.
  • Failure to glClear() the buffers, in particular the depth buffer, is yet another cause. Call glClear() at the start of every frame to remedy this failue.
  • Some OpenGL implementations have bugs that can cause blank windows or other incorrect rendering. Try your application on another implementation. Correct behavior on one or more other implementations is strong evidence of a bug in the first implementation.

2.120 The first frame is rendered correctly, but subsequent frames are incorrect or further away or I just get a blank screen. What's going on?

This is often caused by a failure to realize that OpenGL matrix commands multiply, rather than load over the top of the current matrix.

Most OpenGL programs start rendering a frame by setting the ModelView matrix to the identity with a call to glLoadIdentity(). The view transform is then multiplied against the identity matrix with, for example, a call to gluLookAt(). Many new programmers assume the gluLookAt() call will load itself onto the current matrix and therefore fail to initialize the matrix with the glLoadIdentity() call. Rendering successive frames in this manner causes successive camera transforms to multiply onto each other, which normally results in an incorrect rendering.

2.130 What is the AUX library?

Very important: Don't use AUX. Use GLUT instead.

The AUX library was developed by SGI early in OpenGL's life to ease creation of small OpenGL demonstration programs. It's currently neither supported nor maintained. Developing OpenGL programs using AUX is strongly discouraged. Use the GLUT instead. It's more flexible and powerful and is available on a wide range of platforms.

For related information, see the GLUT Section.

2.140 What support for OpenGL does {Open,Net,Free}BSD or Linux provide?

The X Windows implementation, XFree86 4.0, includes support for OpenGL using Mesa or the OpenGL Sample Implementation.  XFree86 is released under the XFree86 license.

SGI has released the OpenGL Sample Implementation as open source. It can be built as an X server GLX implementation.  It has been released under SGI Free Software License B.

The Mesa 3D Graphics Library is an OpenGL clone that runs on many platforms, including MS-DOS, Win32, *BSD and Linux.  On PC UNIX platforms Mesa can be built to use GGI, X Windows, and as an X server GLX implementation.  Mesa is hardware accelerated for a number of 3D graphics accelerators.  Mesa 3.1 and later was released under an XFree86-style license.  Versions prior to 3.1 were released under GPL.

Utah-GLX is a hardware accelerated GLX implementation for the Matrox MGA-G200 and G-400, ATI 3D RAGE PRO, Intel i810, NVIDIA RIVA, and S3 ViRGE.  Utah-GLX is based on Mesa.  It is not clear what license Utah-GLX is released under.

Xi Graphics 3D Accelerated-X is an X server with GLX support. Supported devices include: ATI Xpert 2000, ATI Rage Fury Pro, ATI Rage Fury, ATI Rage Magnum, ATI All-in-Wonder 128 (all ATI RAGE 128 I believe), 3Dlabs Oxygen VX1, 3Dlabs Permedia 3 Create! (Permedia 3), Diamond Stealth III S540, Diamond Stealth III S540 Extreme, Creative Labs 3D Blaster Savage4 (S3 Savage4), Number Nine SR9, 3Dfx Voodoo 3000, 3Dfx Voodoo 3500 software.

2.150 Where is OpenGL 1.2?

When this was written (early 2000), few OpenGL 1.2 implementations were available. Sun and IBM are shipping OpenGL 1.2. The OpenGL-like Mesa library also supports 1.2. The OpenGL Sample Implementation is also available.

Microsoft hasn't released OpenGL 1.2 yet.  As of their most recent official announcement, it is to be included in a later Windows 2000 service pack. Once Microsoft releases OpenGL 1.2, you'll probably need a new driver to take advantage of its features.

Many OpenGL vendors running on Microsoft already support OpenGL 1.2 functionality through extensions to OpenGL 1.1.

OpenGL vendors that run on OS other than Microsoft will release OpenGL 1.2 on their own schedules.

The OpenGL 1.2 specification is available from the OpenGL Registry.


2.160 What are the OpenGL Conformance Tests?

The OpenGL Conformance Tests are a suite of tests that the OpenGL ARB uses to certify an OpenGL implementation conforms to the OpenGL spec, and, after paying the licensing fee, is therefore entitled to call itself "OpenGL". The source code for the conformance tests can be licensed from the OpenGL ARB.

The conformance tests were recently upgraded to test the full OpenGL 1.2 functionality. They do not exercise extension entry points. They will, however, report the full list of extensions that an implementation claims to support.

covogl is a special conformance test that simply calls every standard entry point. It is a "coverage" test, meant to ensure that all entry points exist and don't crash. All the other tests are intended to test spec conformance for a specific rendering task.

The test mustpass.c tests a defined core of functionality that all OpenGL implementations must support. (You must be able to render a line," etc.) Vendors that fail other tests are still allowed to use the name "OpenGL", but they must be able to show that they understand the bugs, and are working to resolve the issue in a future release.

The ability to push and pop state is thoroughly tested. Each test that runs is of the form:

push state
change state
run test
pop state
check all state values (via glGet*()) to make sure they have returned to the default values.

Some tests have some built-in error that allows for some variation from the OpenGL specification. For example, OpenGL spec states that when rasterizing a triangle, the center of each rendered pixel must be within the mathematical boundary of the triangle. However, the conformance test for rasterizing triangles allows pixels to be as much as 1/2 pixel outside this boundary without reporting an error.

Conversely, some tests appear to test for more than the spec calls for. For example, the test for alpha test requires 10 percent (between 4 and 5 bits) precision to pass, whereas the spec calls for only a single bit of precision.

Some tests don't make sense if you are not intimately familiar with the spec. For example, the spec says it's perfectly OK to not antialias polygons when the user has requested it, and the conformance tests allow this. Another example is dithering; the spec allows for a great deal of implementation variety, including no dithering at all, and as a consequence, the conformance tests won't display an error if your implementation doesn't dither.

All tests support path levels that execute the same tests with a variety of state settings that should still produce the same result. For example, rendering a triangle with polygon stipple disabled should produce the same result as rendering it with polygon stipple enabled and a stipple pattern of all 1 bits. Again, this should be identical to rendering with blending enabled and a blend function of (GL_ONE,GL_ZERO). A number of path levels are available, each testing more and more complex combinations of state settings.

All tests are run on all available pixel formats or visual types, including (if available) color index.

All tests verify correct rendering with glReadPixels(). Some tests read the entire test window, while other read only a few key pixels. In general, the tests use GL_RGBA and GL_FLOAT as the type and format. However, the readpix.c test thoroughly tests all type and format combinations. If glReadPixels() is broken, all tests could fail.

If glReadPixels() is slow, the conformance tests can take a long time to run. Furthermore, since all tests run at all path levels on all available pixel formats and visuals, it could take several days of serial compute time to run the entire test suite.

The conformance tests find many bugs. However, they don't guarantee a bug-free implementation. An implementation that passes the full suite of conformance tests might still be so buggy that many applications won't be able to run.

Column Header
Column Footer