2 Getting Started 

2.005 Where can I find 3D graphics info?

The comp.graphics.algorithms FAQ contains a lot of 3D graphics information that isn't specific to OpenGL.

An excellent general computer graphics text is Computer Graphics: Principles and Practice, Second Edition, by James Foley, et al. ISBN 0-201-12110-7. It has been mentioned that this book is out of print and that a third edition is planned for release in January 2001. However, some online book retailers still seem to have it for sale. Try amazon.com.

Delphi code for performing basic vector, matrix, and quaternion operations can be found here.

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 Organization Web Page

SGI's OpenGL Web site and (apparently) SGI's other OpenGL Web site.

OpenGL Basics FAQ

OpenGL Game Developer's FAQ
In addition to information on OpenGL, the OpenGL Game Developer's FAQ has information on subscribing to the OpenGL Game Developer's mailing list.

The EFnet #OpenGL FAQ

The OpenGL org web site has the current OpenGL specification and manual pages. You can view the OpenGL spec v1.1 online as a Web page.

A repository of OpenGL implementations for several platforms

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

Codeguru maintains a small, but growing list, of useful OpenGL sample code.

Lucian Wischik's Web page at http://www.wischik.com/lu/programmer/wingl.html 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.

See Blaine Hodge's Web page for info on Win32 OpenGL programming.

An interactive OpenGL tutorial can be found here.

Check gamedev.net for OpenGL tutorials and articles.

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 of these books described 1.0 and 1.1, respectively.

The OpenGL red book is online. However, links to online copies of this book don't seem to last long. Reference pages similar to the OpenGL blue book are also online.

In addition to the red and blue books, the green and white books are for X Windows and Microsoft Windows programming, respectively. You can obtain a more exhaustive list of OpenGL books by visiting the www.opengl.org Web site.

2.030 What OpenGL chat rooms and newsgroups are available?

The Usenet newsgroup, devoted to OpenGL programming, is comp.graphics.api.opengl.

The #OpenGL IRC channel is devoted to OpenGL discussion.

2.040 Are there OpenGL implementations that 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.

The OpenGL Sample Implementation is also available.

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.

For information on using OpenGL through Borland C++ Builder, visit Scott Heiman's Web page.

Here are three sites with info on using OpenGL through Visual Basic: http://www.softoholic.bc.ca/opengl/down.htm, http://www.weihenstephan.de/~syring/ActiveX/, http://www.ieighty.net/~davepamn/colorcube.html.

Information on using OpenGL from Delphi can be found here, and also at the Delphi3D web page.

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.

The OpenGL Organization maintains a list of links to OpenGL developer and end-user files. 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. You might also check the Developer section at The OpenGL Organization's Web page for information about OpenGL for your specific platform.

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 comp.graphics.api.opengl 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)
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);

    /* … */

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 (taken from the OpenGL Reference Manual):

#include <GL/glx.h>
#include <GL/gl.h>

static Bool WaitForNotify(Display *d, XEvent *e, char *arg)
    return (e->type == MapNotify) && (e->xmap.window == (Window) arg);

static int sAttribList[] = {
    GLX_RED_SIZE, 1,
    None };

int main(void)
    Display *dpy;
    XVisualInfo *vi;
    XSetWindowAttributes swa;
    Window win;
    GLXContext cx;
    XEvent event;
    int swap_flag = GL_FALSE;

    dpy = XOpenDisplay(0);

    if ((vi = glXChooseVisual(dpy, DefaultScreen(dpy), sAttribList)) == NULL) {
        fprintf(stderr, "ERROR: Can't find suitable visual!\n");
        return 0;

    cx = glXCreateContext(dpy, vi, 0, GL_TRUE);

    swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
        vi->visual, AllocNone);
    swa.border_pixel = 0;
    swa.event_mask = StructureNotifyMask;
    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 100, 100, 0,
        CWBorderPixel | CWColormap | CWEventMask,

    XMapWindow(dpy, win);

    XIfEvent(dpy, &event, WaitForNotify, (char *)win);

    glXMakeCurrent(dpy, win, cx);

    /* … */

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);

memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nVersion = 1;
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:

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);

Also, see the "Full Screen Rendering" section in the OpenGL game developer's FAQ.

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.

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 and SGI's GLUT FAQ.

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. http://www.xfree86.org/

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. http://oss.sgi.com/projects/ogl-sample/

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. http://mesa3d.sourceforge.net/

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. http://utah-glx.sourceforge.net/

Metro Link OpenGL and Extreme 3D are GLX extensions for Metro Link X servers.  Metro Link OpenGL is a software implementation that can use accelerated X operations to gain a performance advantage over other software implementations.  Metro Link Extreme 3D is a hardware-accelerated implementation for REALimage, GLINT GMX 1000, 2000, GLINT DMX, GLINT MX, GLINT TX, and Permedia 2 and 3. http://www.metrolink.com/

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 are 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 http://www.opengl.org. The red and blue books have recently been revised to cover OpenGL 1.2 functionality.