While Mesa uses the OpenGL API and follows the OpenGL specification very closely, it is important to understand that Mesa is not a true implementation of OpenGL. Official OpenGL products are licensed and must completely implement the OpenGL specification and pass a suite of conformance tests. Mesa meets none of these requirements.
At first, Mesa may seem to be a competitor to official OpenGL products. Actually, Mesa has helped to promote the OpenGL API by expanding the range of computers which may execute OpenGL programs. There are many systems which are not supported by OpenGL vendors but can run Mesa instead. People who are curious about OpenGL may try Mesa at no cost and later purchase a commercial OpenGL implementation which utilizes graphics hardware. Students may learn 3-D programming using Mesa and later develop OpenGL applications on the job.
In the spirit of free software, Mesa is distributed under the terms of the GNU library copyright.
Mesa compiles easily, requiring only an ANSI C compiler and the development
resources (header files and libraries) for the target platform.
From the application programmer's point of view, Mesa is a nearly seemless
replacement for OpenGL.
The Mesa header files are named the same as OpenGL's (GL/gl.h, GL/glu.h,
GL/glx.h, etc) and contain compatible datatypes, constants and function
prototypes.
The Mesa library files may be renamed to match the typical OpenGL library
names and locations. On some operating systems Mesa may be
built as a shared library.
After Mesa has been installed most OpenGL applications should compile and
execute without modification.
Because of its strong similarity to OpenGL it's more appropriate to discuss
the ways in which Mesa is different from OpenGL rather than the ways in
which it's similar. The following sections elaborate on this subject.
Mesa doesn't typically perform as well as commercial OpenGL implementations
for several reasons.
First, portability to a wide range of computers
is considered more important than optimizing for a particular architecture.
Second, the features of the underlying hardware can't be directly accessed
since Mesa exists as a software library above the operating system and
window system programming interfaces.
And finally, Mesa's development is not supported by any sort of development
team. Only so much can be accomplished by people working in their spare time.
In other respects Mesa has some advantages over OpenGL.
The OpenGL GLX extension is implemented in terms of the X/Mesa interface
and Xlib.
Implementing a true GLX extension requires modifying the X server and
is therefore not feasible with commercial servers.
Because of the way in which Mesa and its GLX exist between an OpenGL
application and Xlib, Mesa can be
thought of a translator which converts OpenGL API functions to Xlib commands.
Mesa's GLX is not 100% compatible with OpenGL's GLX. In several ways is
actually superior. For example, while OpenGL only supports RGB rendering
into TrueColor or DirectColor X visuals, Mesa allows RGB
rendering into virtually any type and depth of X visual. This is an
important feature since many X servers don't offer TrueColor or DirectColor
visuals. Other visuals are supported by dithering or converting
RGB values to gray levels.
This introduces two potential incompatibilities with OpenGL's GLX.
There is another nice benefit to implementing Mesa on top of Xlib.
Operating systems which support shared libraries can substitute Mesa for
OpenGL at runtime, allowing OpenGL applications to be displayed on non-GLX
capable X servers without recompiling. By using Mesa's GLX instead of
OpenGL's GLX, OpenGL API calls are translated into ordinary X protocol
which any X server understands.
An effort to implement a true GLX interface for Mesa is underway. This
involves writing an X server extension which can decode and execute
GLX protocol and writing a GLX client library which can encode GLX messages.
It is an alternative to the standard
An application using GLX pixmaps should use the following code to associate
a colormap with the GLX pixmap when using Mesa.
For
Programs using OpenGL, not Mesa, may also use the
Perhaps the GL_MESA_window_pos extension may be incorporated into a
future version of OpenGL since it is so convenient.
Many API functions simply modify state values and produce no output.
When rendering functions are invoked it is often necessary to evaluate
the current state to compute derived state values and setup pointers to
specific instances of rendering functions.
Lazy evaluation is used to updated the state.
For example, Mesa has many instances of specialized polygon drawing functions.
Which function to use depends on the state of smooth vs flat shading,
dithering, depth testing, etc. When any of these state values are changed
the new state flag is set. When
Vertices specified between
Each transformation and clip test stage is implemented in a tight
loop which compilers can unroll for efficient executution.
The size of the vertex buffer was chosen so that all vertex data touched
in the transformation loops will fit in a 16KB CPU data cache.
Several optimization are used during transformation.
The modelview and projection matrices often have particular elements with
values of zero or one.
These elements are tested to determine if simplified vector/matrix
multiplications can be used.
Depending on the current lighting parameters, either a full-featured or
specialized, optimized lighting function is used.
Lookup tables are used to compute the exponential spotlight and material
shininess functions.
After a vertex buffer has been processed it is rendered as a set of
points, lines or polygons as specified by
Arrays of points are rendered by either calling a specialized device
driver function or by falling back to a core Mesa drawing function.
Points whose clip flag is set are discarded.
Line segments are clipped if either endpoint's clip flag is set.
Then, the line is rasterized by calling either a specialized device driver
function or a core Mesa line drawing function.
Different line drawing functions are called for flat or smooth shading,
RGB or color index mode, texturing, etc.
Polygons are clipped with the Sutherland-Hodgman algorithm if any of the
vertex clip flags are set.
Next, the equation of the plane containing the polygon is computed.
The coefficients of the plane equation ax+by+cz=d are useful for a number
of things.
The c term indicates the front/back orientation of the polygon
and is used in culling, two-sided lighting and rasterization.
The remaining terms are used for implementing the polygon offset
extension and for computing Z values inside the polygon.
As with line segments, either a specialized device driver function or
core Mesa function is called to rasterize the polygon.
Currently, polygons are not decomposed into triangles.
The polygon rasterizer directly renders n-sided, convex polygons.
There are advantages to using triangle decomposition and that approach
will probably be implemented in the future.
The specialized device driver functions for point, line and polygon
rendering take vertices as input and directly modify the frame buffer.
Alternatively, the fallback rendering functions in Mesa handle rendering
of primitives with arbitrary raster operations.
Point and line rasterizers generate fragments which are stored in a
pixel buffer.
Polygons rasterizers generate horizontal runs of pixels called spans.
The pixel buffer and spans are subjected to fragment processing before
being written to the frame buffer.
Pixel buffer and span-based fragment processing are very similar, the only
difference is that the pixel buffer stores fragments with arbitrary window
coordinates while spans are continuous horizontal runs of fragments. It
should also be noted that
Since fragments may be culled during processing, each fragment has a write
flag associated with it. Initially, all fragments have their flags set
to true.
Clipping, scissoring, alpha testing, stenciling, and depth testing may
set a flag to false to indicate that it should not be considered
in further stages. In the end, only those fragments with
their flags set are written to the color buffer.
Each stage of fragment processing is implemented in succession with code
similar to:
The only fragment operation which must be handled below the device driver
level is dithering. Depth testing, bitwise logic operators and
masking may optionally be implemented by the device driver.
Some device driver functions are optional and if not implemented by the
device driver fall back to core Mesa code.
Examples are pixel logic operators, point, line, polygon drawing and the
depth buffer implementation.
The device driver interface is rather simple but still allows accelerated
rendering funtions to be utilized.
The code for writing RGB pixels to the color buffer could be expressed as:
When operating in single buffered mode, rendering is directed into an X
window. When operating in double buffered mode, rendering is directed
into either a Pixmap or XImage. A Pixmap can be accessed in the same
way as a window (both are considered to be drawables).
Whether a Pixmap or XImage gives best performance depends on a number of
factors.
Using a Pixmap can be quite efficient for rendering plain, flat-shaded
points, lines and polygons since the X point, line and polygon drawing
functions can be used. Performance is relatively good whether displaying
locally or remotely.
However, when using smooth shading or per-pixel fragment operations
pixels must be drawn individually with
In most cases using an XImage yields best performance in double buffer mode.
The reason is individual pixels can be directly "poked" into the
image since it resides in the client's address space.
Front/back buffer swapping is implemented by copying the XImage to the
X window.
The X Shared Memory extension is used when displaying on the local host
to accelerate this operation.
In the case of remote display, the amount of data transferred from
the client to the X server is directly proportional
to the window size and not the number of pixels generated during rendering.
Programmers should note that double buffering using an XImage can be faster
than single buffering.
Mesa's X driver includes optimized functions for drawing flat shaded lines
with or without depth buffering and functions for drawing flat or smooth
shaded polygons with or without depth buffering.
These are the most common cases for rendering 3-D models and perform
much better than using the fallback drawing functions since the pixel
buffer and span-based fragment processing is completely bypassed. The
line and polygon functions write directly into the color buffer.
The device driver interface to point, line and polygon drawing can also
be exploited for specialized 3-D graphics hardware.
At least two hardware acceleration projects are underway which use this
approach.
In this situation, Mesa maintains the library state and
performs geometric transformation but leaves rasterization to the hardware.
In the future Mesa will continue to be enhanced, optimized and ported
to new systems. No doubt, much of this work will be done
by additional volunteers who share an enthusiasm for computer
graphics and free software.
2. Using the Library
The Mesa distribution includes implementations of the core OpenGL library
functions, the GLU utility functions, the aux and tk toolkits,
Xt/Motif widgets, drivers for X11, Microsoft Windows '95/NT, NeXTStep,
AmigaDOS, and many demonstration programs. A Macintosh driver is
distributed separately.
2.1 Mesa and OpenGL Differences
Mesa does not implement the full OpenGL specification.
Antialiasing, for example, is not available and texture mapping is only
partially implemented.
Trimmed NURBS are not available and the GLX interface is only emulated.
It is expected that these features will eventually be implemented.
2.2 GLX Emulation
Mesa's interface to the X Window System is defined by the X/Mesa interface.
There are X/Mesa functions for creating rendering contexts, destroying
contexts, binding contexts to windows and pixmaps, swapping color buffers
and querying the current context.
The first problem is solved with a special Mesa extension to GLX, explained
later. The second problem can usually be fixed by modifying the application's
GLX code.
glXChooseVisual function.
2.3 Extensions
Mesa implements several popular OpenGL extensions and adds a few of its own.
2.3.1 OpenGL Extensions
Mesa has the following OpenGL extensions:
2.3.2 Mesa Extensions
Mesa offers two extensions.
GLX_MESA_pixmap_colormap
This extension adds the GLX function:
GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
Pixmap pixmap, Colormap cmap )
glXCreateGLXPixmap
function.
Since Mesa supports RGB rendering into any X visual, not just TrueColor
or DirectColor, Mesa needs colormap information to convert RGB
values into pixel values. An X window carries this information but a
pixmap does not. This function associates a colormap to a GLX pixmap.
#ifdef GLX_MESA_pixmap_colormap
glxpixmap = glXCreateGLXPixmapMESA( display, xvisualinfo,
xpixmap, colormap );
#else
glxpixmap = glXCreateGLXPixmap( display, xvisualinfo, xpixmap );
#endif
GL_MESA_window_pos
This extension adds the glWindowPos*MESA functions.
These functions are convenient alternatives to glRasterPos*
because they set the current raster position to a specific window coordinate,
bypassing the usual modelview, projection and viewport transformations.
This is especially useful for setting the position for
glDrawPixels or glBitmap to a desired window
coordinate.
glWindowPosMESA4f( x, y, z, w ) the
x, y, z, and w parameters
directly set the current raster position except that z is
clamped to the range [0,1].
The current raster position valid flag is always set to true.
The current raster distance is set to zero.
The current raster color and texture coordinate are updated in the
same manner as for glRasterPos.
In selection mode a hit record is always generated.
glWindowPos*MESA
functions since an implementation of it in terms of standard OpenGL
functions is included with Mesa.
3. Implementation
Mesa is written in ANSI C. The core library contains no operating system
or window system dependent code making it extremely portable.
A special device driver interface insulates the core Mesa library from the
underlying window system. Each Mesa window system interface implements
both public the OpenGL/window system API functions and the private device
driver funtions.
3.1 Library State
OpenGL is designed around the concept of a state machine. In Mesa this
state is stored in a large C struct. Much of the state is stored in
substructures which directly correspond to the attribute groups
such as the polygon group, lighting group and texture group. Pushing and
popping of attribute groups is just a matter of copying C structs to and
from a stack.
glBegin is called
the new state flag is tested and if set, the state is evaluated
to select the specialized polygon function and the flag is cleared.
3.2 Point, Line and Polygon Rendering
Arguably the most important feature of Mesa is efficient point, line and
polygon rendering.
The two major components of this are vertex transformation and rasterization.
glBegin and glEnd
are accumulated in a vertex buffer. When the buffer is full or
glEnd is called the buffer is processed.
Processing the vertex buffer includes transforming vertices from
object coordinates to eye coordinates, lighting, transforming
eye coordinates to clip coordinates, clip testing, and mapping clip
coordinates to window coordinates.
glBegin.
3.3 Fragment processing
Fragments are the pixels generated by rasterization augmented with
auxiliary information such as color, depth (Z) and texture coordinates.
OpenGL defines an extremely flexible fragment processing pipeline which
includes texturing, fogging, clipping, scissoring, alpha testing, stenciling,
depth testing, blending, dithering, bitwise logic operations, and masking.
glBitmap stores fragments in the
pixel buffer while glDrawPixels generates spans.
if (stage is enabled) {
for (each fragment in the buffer or span) {
apply the fragment operation,
possibly setting some write flags to false
}
}
Finally, fragments are written to the color buffer by device driver functions
similar to:
for (each fragment) {
if (fragment flag is true) {
write fragment color to color buffer
}
}
The special cases of all write flags set to true or false are handled
appropriately.
Also, the case in which all fragment colors are the same is a special case.
3.4 Device Driver Functions
The device driver interface is a set of function pointers which point to
implementations specific to the window system.
It includes function for:
The device driver must update these pointers whenever the make current
function is called or whenever the new state flag is found to be
true before rendering.
glClear color or index
glDrawPixels for specific situations
glFlush and glFinish
3.5 The X Device Driver
The X device driver is quite large because it supports rendering into
a wide variety of X visuals and has many specialized line and polygon
rendering functions.
for (each pixel i) {
pixel_value = convert_rgb_to_pixel( red[i], green[i], blue[i] );
put_pixel( x[i], y[i], pixel_value );
}
However, this would be very inefficient in most cases. The best method
to convert RGB values to pixel values depends on the X visual. The
best method to write pixels to the color buffer depends on whether the
buffer is implemented as an X Pixmap or XImage.
For these reasons, and the fact that this loop is critical to good
performance, there are many instances of device driver functions such as
write_color_span.
The device driver selects the appropriate function and sets a device driver
pointer to that function.
XSetForeground
and XDrawPoint calls.
The amount of data transferred from the client to X server is directly
proportional to the number of X calls made.
For XSetForeground/XDrawPoint rendering
this is usually unacceptably slow.
4. Closing Remarks
Mesa has turned out to be a very useful and popular 3-D library.
Its success can be attributed to the facts that the library is free, full
featured, reliable, portable and compatible with OpenGL.
Many volunteers have contributed to this success.
5. Obtaining Mesa
Mesa can be downloaded by anonymous ftp from iris.ssec.wisc.edu
in the pub/Mesa directory or through the
Mesa home page at
http://www.ssec.wisc.edu/~brianp/Mesa.html.
Last edited on May 14, 1996 by Brian Paul.