SIGGRAPH '97

Course 24: OpenGL and Window System Integration

Comparison of OpenGL Window Sytem Interfaces



Contents


1. Introduction

Since OpenGL is designed to be independent of any window system, integration of OpenGL with a window system is accomplished with a special interface. This interface is dependent on the window system and is typically designed and implemented by the window system vendor.

Though each OpenGL window system interface is different they are all similar in functionality. This document compares the functionality of several interfaces. Programmers writing applications for more than one window systems should find this information especially relevant.

The following interfaces are compared:



2. Basic Functionality

There are five basic steps to OpenGL and window system integration in an application:
  1. Test for OpenGL capability - be sure that the system supports OpenGL rendering.
  2. Select a visual/pixel type - based on criteria such as RGB vs color index, single vs double buffering, depth buffering, stenciling, etc select a visual/pixel type.
  3. Create an OpenGL rendering context - create a rendering context for the visual/pixel type selected.
  4. Create a drawable - create a window or color buffer using the window system's API. One of the parameters to the window creation function will probably be the visual/pixel type.
  5. Bind the rendering context to the drawable - binding a context to a drawable activates the context and directs rendering to that drawable.
Note that the rendering context and drawable must usually use the same visual/pixel type. In other words, if you need two rendering windows which don't share the same visual/pixel type you'll need to create a separate context for each window.



3. Data types and objects

There are several data types or handles which are used for similar purposes in all the OpenGL interfaces.
Display/Session handle
The notion of a display or drawing/device context.

Datatypes

  • AGL: none
  • GLX: Display
  • PGL: HAB
  • WGL: HDC
Visual/Pixel format
The way in which pixel data in a frame buffer is displayed is controlled by a visual or pixel format. OpenGL typically augments a window system's visuals/pixel formats with information about double buffering, depth buffers, stencil buffers, etc.

Datatypes

  • AGL: AGLPixelFmtID
  • GLX: XVisualInfo
  • PGL: PVISUALCONFIG
  • WGL: an integer pixel format number or a PIXELFORMATDESCRIPTOR structure
OpenGL rendering context
OpenGL is designed as a state machine. OpenGL state is encapsulated in a context. Multiple contexts may be created but only one may be active at a time. If an application needs to render into several windows, one context may be used for both windows if the windows use the same visual or pixel format. If different pixel formats are used then different OpenGL contexts may be required.

Datatypes

  • AGL: AGLContext
  • GLX: GLXContext
  • PGL: HGC
  • WGL: HGLRC
Window/drawable
The destination of OpenGL rendering is typically a window on your terminal screen. The OpenGL interface may also allow rendering into an off-screen color buffer. The handle for an off-screen buffer is typically compatible with a window handle.

An OpenGL rendering context is activated by binding a context to a window or drawable.

Datatypes

  • AGL: AGLDrawable
  • GLX: GLXDrawable (a Window or GLXPixmap)
  • PGL: HWND
  • WGL: HDC


4. Interface Functions

This section presents the major function of the interfaces catagorized according to their purpose.

4.1 Testing for OpenGL availability

At runtime it may be necessary to determine if a display or terminal is capable of OpenGL rendering.
GLX
Bool glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
PGL
LONG pglQueryCapability( HAB hab )

4.2 Getting OpenGL version information

Since OpenGL is an evolving standard it's sometimes useful to be able to determine which version of OpenGL render is being used.
AGL
GLboolean aglQueryVersion( int *major, int *minor )
GLX
Bool glXQueryVersion( Display *dpy, int *major, int *minor )
PGL
void pglQueryVersion( HAB hab, int *major, int *minor )

4.3 Selection of a visual or pixel format

A visual or pixel format describes the frame buffer and ancillary buffers. Attributes include RGB vs color index, bits per color component, single vs double buffered, size of depth buffer, size of stencil buffer, etc.

The application programmer should know what frame buffer attributes are needed and select a visual or pixel format accordingly.

These functions return a visual or pixel format based on a attribute list provided by the programmer.

AGL
AGLPixelFmtID aglChoosePixelFmt( GDHandle *dev, int ndev, int *attribs )
GLX
XVisualInfo* glXChooseVisual( Display *dpy, int screen, int *attribList )
PGL
PVISUALCONFIG pglChooseConfig( HAB hab, int *attriblist )
WGL
int ChoosePixelFormat( HDC hdc, PIXELFORMATDESCRIPTOR *pfd )

4.4 Query visual/pixel format attributes

As an alternative to asking the window system for a visual/pixel format which matches an attribute list, one may query the attributes of a particular visual or pixel format. This allows the programmer complete control over visual/pixel format selection. These functions return the value of an attribute for a given visual/pixel format.
AGL
GLboolean aglGetConfig( AGLPixelFmtID pix, int attrib, int *value )
GLX
int glXGetConfig( Display *dpy, XVisualInfo *vis, int attrib, int *value )
PGL
PVISUALCONFIG *pglQueryConfigs( HAB hab )
WGL
int DescribePixelFormat( HDC hdc, int pixelformat, UINT bytes, LPPIXELFORMATDESCRIPTOR pfd )

4.5 Creating a rendering context

After a visual/pixel format has been selected an OpenGL rendering context may be allocated. Rendering contexts may share display lists and texture maps if the contexts are compatible. Contexts are considered to be compatible if they share the same address space and pixel format and are both direct or indirect.

Direct contexts provide a means of utilizing local graphics hardware in the most efficient means possible. Indirect contexts are used in other situations such as when rendering remotely.

In the case of GLX, a direct context may be used when using local graphics hardware; the GLX protocol encoding/decoding is bypassed. An indirect context allows remote display to X servers which support the GLX extension.

Some OpenGL interfaces make no distinction between direct and indirect rendering.

AGL
AGLContext aglCreateContext( AGLPixelFmtID pix, AGLContext shareList )
GLX
GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct )
PGL
HGC pglCreateContext( HAB hab, PVISUALCONFIG pVisualConfig, HGC ShareList, BOOL IsDirect )
WGL
HGLRC wglCreateContext( HDC hdc )

BOOL wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )

4.6 Destroying a rendering context

When finished with a context it may be destroyed.
AGL
GLboolean aglDestroyContext( AGLContext ctx )
GLX
void glXDestroyContext( Display *dpy, GLXContext ctx )
PGL
BOOL pglDestroyContext( HAB hab, HGC hgc )
WGL
wglDeleteContext( HRC hrc )

4.7 Context binding

When a rendering context is bound to a window it becomes the current context. OpenGL rendering may then begin. Note that it is not until this point that one may test for OpenGL extensions.
AGL
GLboolean aglMakeCurrent( AGLDrawable drawable, AGLContext ctx )
GLX
Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
PGL
BOOL pglMakeCurrent( HAB hab, HGC hgc, HWND hwnd )
WGL
wglMakeCurrent( HDC hdc, HGLRC hrc )

4.8 Copying context state

These functions copy a subset of a context state from one context to another. The mask parameter takes the same values as glPushAttrib().
AGL
GLboolean aglCopyContext( AGLContext src, AGLContext dst, GLuint mask )
GLX
void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, GLuint mask )
PGL
BOOL pglCopyContext( HAB hab, HGC hgc_src, HGC hgc_dst, GLuint attrib_mask )
WGL
BOOL wglCopyContext( HGLRC hglrcSrc, hglrcDst, UINT mask )

4.9 Testing for direct rendering

These functions test if a rendering context is direct.
GLX
Bool glXIsDirect( Display *dpy, GLXContext ctx )
PGL
LONG pglIsIndirect( HAB hab, HGC hgc )

4.10 Swapping color buffers

The swap buffers operation exchanges the front and back color buffers when double buffering is enabled. The contents of the back buffer become undefined after the swap operation.
AGL
GLboolean aglSwapBuffers( AGLDrawable drawable )
GLX
void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
PGL
void pglSwapBuffers( HAB hab, HWND hwnd )
WGL
BOOL SwapBuffers( HDC hdc )

4.11 Off-screen rendering

These functions create an off-screen color buffer or pixmap. Be aware that rendering to an off-screen color buffer may not be accelerated by your graphics hardware.
AGL
AGLPixmap aglCreateAGLPixmap( AGLPixelFmtID pix, GWorldPtr pixmap )

GLboolean aglDestroyAGLPixmap( AGLPixmap pix )

GLX
GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *vis, Pixmap pixmap )

void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pix );

4.12 Bitmap fonts

Fonts provided by the window system may be converted to glBitmap() format and stored in display lists. Character strings may then be rendered with glCallLists(). These functions convert font glyphys from the window system to a sequence of display lists.
AGL
GLboolean aglUseFont( int familyID, int size, int first, int count, int listBase )
GLX
void glXUseXFont( Font font, int first, int count, int listBase )
PGL
BOOL pglUseFont( HAB hab, HPS hps, FATTRS fatAttrs, LONG llcid, int first, int count, int listbase )
WGL
BOOL wglUseFontBitmaps( HDC hdc, DWORD first, DWORD count, DWORD listBase )

BOOL wglUseFontOutlines( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf )

4.13 Querying the current context and drawable

The ID of the current rendering context and current window/drawable may be queried with these functions.
AGL
AGLContext aglGetCurrentContext( void )

AGLDrawable aglGetCurrentDrawable( void )

GLX
GLXContext glXGetCurrentContext( void )

GLXDrawable glXGetCurrentDrawable( void )

PGL
HGC pglGetCurrentContext( HAB hab )

HWND pglGetCurrentWindow( HAB hab )

WGL
HGLRC wglGetCurrentContext( void )

HDC wglGetCurrentDC( void )

int GetPixelFormat( HDC hdc )

4.14 Synchronization

Since both OpenGL and the native window system renderer may both draw into the same window synchronization is needed to be sure operations are performed in the correct order.
GLX
void glXWaitGL( void )

void glXWaitX( void )

PGL
HPS pglWaitGL( HAB hab )

void pglWaitPM( HAB hab )

4.15 Miscellaneous

Each OpenGL window system interface has some unique functions. Some of them are described here.
AGL
GLenum aglGetError( void )

Returns the current error setting or GL_OK if none.

int aglListPixelFmts( GDHandle dev, AGLPixelFmtID **fmts )

Returns a list of all pixel formats offered for the given device.

GLboolean aglSetOptions( int options )

Sets AGL-specific options.

GLboolean aglUpdateCurrent( void )

Causes the current context's state to be updated from the window system. This should be called whenever the window is moved, resized, or the screen resolution or depth is changed.

GLX: (version 1.1)
const char *glXQueryExtensionsString( Display *dpy, int screen )

Returns a list of space separated GLX extensions on the specified display.

const char *glXGetClientString( Display *dpy, int name )

Returns a string describing an attribute of the OpenGL client library.

const char *glXQueryServerString( Display *dpy, int screen, int name )

Returns a string describing an attribute of the OpenGL display server.

PGL
INT pglSelectColorIndexPalette( HAB hab, HPAL hpal, HGC hgc )

This function specifies the color index palette for OpenGL to use when drawing in RGB mode.

BOOL pglGrabFrontBitmap( HAB hab, HPS phps, HBITMAP phbitmap )

BOOL pglReleaseFrontBitmap( HAB hab )

These functions are used to gain exclusive access to a window.

WGL
wglCreateLayerContext, wglDescribeLayerPlane, wglGetLayerPaletteEntries, wglSetLayerPaletteEntries, and wglSwapLayerBuffers

Provide support for overlay and underlay color buffers.



5. To learn more

Introduction to OpenGL and X, Part 1: An Introduction (http://www.sgi.com/Technology/openGL/mjk.intro/intro.html) by Mark Kilgard of SGI describes how to get started with OpenGL and the X Window System.

The Unix man pages for GLX and the GLX specification documents describe the GLX functions in detail.

agl.txt describes the AGL interface. This information provided courtesy of Template Graphics Software.

OpenGL for OS/2 including documentation can be obtained from ftp://ftp.austin.ibm.com/pub/developer/os2/OpenGL/.

Using OpenGL in Visual C++ Version 4.x (http://www.iftech.com/oltc/opengl/opengl0.stm) by N. Alan Oursland of Interface Technologies, Inc. describes how to get started using OpenGL with Microsoft's Visual C++.

OpenGL I: Quick Start (http://www.microsoft.com/msdn/library/technote/gl1.htm) by Dale Rogerson of Microsoft is the first in a series of articles explaining how to use OpenGL with Windows 95 and Windows Nt.

Microsoft's Developer Studio / Visual C++ product includes online documentation of the WGL interface.




Last edited on April 13, 1997 by Brian Paul.