X Window Programming/Print version
This is the print version of X Window Programming You won't see this message or any elements not part of the book's content when you print or preview this page. |
The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/X_Window_Programming
Contents
Table of contents
edit- Introduction
- About this book
- What is X Window? (what is it, what is it used for, what can be done with it, getting it)
- X Window protocol
- Available libraries
- Making a Toolkit
- Widgets
- Interfaces
- Resources
- Appendices
- Xlib functions
- XCB functions
- Motif functions
- GTK+ functions
- Qt functions
- SDL functions
- OpenGL functions
- Freedesktop Specification
Introduction
This book is designed for people interested in learning how to program the X Window System and assumes some basic knowledge on how to use a computer, how to setup and use The X Window System, how to use a compiler, and how to write a program in the C programming language. This book is open work, so if you find any problems with terms or concepts, you can contribute an explanation to it. Feel free to participate; you are welcome to do so.
The X Window System (or X and X11 for short) is a server application that provides basic functions for displaying graphics and gathering user input transparently, either locally or over a network. X distributes user input to and accepts output requests from applications through the X Window System protocol.
X does not mandate the visual appearance and interface of applications, choosing instead to allow applications to use whatever visual style and interface is desired. As a result, different applications may present radically different interfaces.
Xlib
Xlib is an X Window System protocol client library written in the C programming language. It contains functions for interacting with an X server. These functions allow programmers to write programs without knowing the details of the protocol. Few applications use Xlib directly; rather, they employ other libraries that use Xlib functions to provide widget toolkits:
- Intrinsics (Xt)
- Athena widget set (Xaw)
- Motif
- GTK+
- Qt (X11 version)
- fpGUI (Free Pascal GUI Toolkit)
Xlib appeared around 1985, and is currently used in GUIs for many Unix-like operating systems.
The XCB library is an attempt to replace Xlib.
Data types
editThe main types of data in Xlib are the Display
structure and the types of the identifiers.
Informally, a display is a physical or virtual device where graphical operations are done. The Display
structure of the Xlib library contains information about the display, but more importantly it contains information relative to the channel between the client and the server. For example, in a Unix-like operating system, the Display
structure contains the file handle of the socket of this channel (this can be retrieved using the ConnectionNumber
macro.) Most Xlib functions have a Display
structure as an argument because they either operate on the channel or are relative to a specific channel. In particular, all Xlib functions that interact with the server need this structure for accessing the channel. Some other functions need this structure, even if they operate locally, because they operate on data relative to a specific channel. Operations of this kind include for example operations on the event queue, which is described below.
Windows, colormaps, etc, are managed by the server. Thus, all their data are stored in the server, and the client cannot directly modify or operate on an object. Instead, the client submits requests to the server, each request specifying an operation and an object's identifier.
The types Window
, Pixmap
, Font
, Colormap
, etc, are all identifiers, which are 32-bit integers (just as in the X11 protocol itself). A client “creates” a window by asking the server to create a window. This is done via a call to an Xlib function that returns an identifier (a number) for the window. This identifier can then be used by the client to request further operations on that window.
The identifiers are unique to the server. Most of them can be used by different applications to refer to the same objects. For example, two applications connecting to the same server would use the same identifier to refer to the same window. These two applications use separate channels, and therefore have two different Display
structures; however, when they request operations on the same identifier, these operations will be done on the same object.
Protocol and events
editThe Xlib functions that send requests to the server usually do not send these requests immediately but store them in a buffer, called the output buffer. The term output in this case refers to the output from the client that is directed to the server: the output buffer can contain all kinds of requests to the server, not only those having a visible effect on the screen. The output buffer is guaranteed to be flushed (i.e., all requests done so far are sent to the server) after a call to the functions XSync
or XFlush
, after a call to a function that returns a value from the server (these functions block until the answer is received), and in some other conditions.
Xlib stores the received events in a queue. The client application can inspect and retrieve events from the queue. While the X server sends events asynchronously, applications using the Xlib library are required to explicitly call Xlib functions for accessing the events in the queue. Some of these functions may block; in this case, they also flush the output buffer.
Errors are instead received and treated asynchronously: the application can provide an error handler that will be called whenever an error message from the server is received.
The content of a window is not guaranteed to be preserved if the window of one of its parts are made not visible. In this case, the application is sent an Expose
event when the window of one part of it is made visible again. The application is then supposed to draw the window content again.
Functions
editThe functions in the Xlib library can be grouped in:
- operations on the connection (
XOpenDisplay
,XCloseDisplay
, ...); - requests to the server, including requests for operations (
XCreateWindow
,XCreateGC
,...) and requests for information (XGetWindowProperty
, ...); and - operations that are local to the client: operations on the event queue (
XNextEvent
,XPeekEvent
, ...) and other operations on local data (XLookupKeysym
,XParseGeometry
,XSetRegion
,XCreateImage
,XSaveContext
, ...)
Example
editThe following program creates a window with a little black square in it and exits on a keypress.
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
enum {
RECT_X = 20,
RECT_Y = 20,
RECT_WIDTH = 10,
RECT_HEIGHT = 10,
WIN_X = 10,
WIN_Y = 10,
WIN_WIDTH = 100,
WIN_HEIGHT = 100,
WIN_BORDER = 1
};
int main() {
Display *display;
Window window;
XEvent event;
int screen;
/* open connection with the server */
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
screen = DefaultScreen(display);
/* create window */
window = XCreateSimpleWindow(display, RootWindow(display, screen), WIN_X, WIN_Y, WIN_WIDTH, WIN_HEIGHT,
WIN_BORDER, BlackPixel(display, screen), WhitePixel(display, screen));
/* process window close event through event handler so XNextEvent does not fail */
Atom del_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(display, window, &del_window, 1);
/* select kind of events we are interested in */
XSelectInput(display, window, ExposureMask | KeyPressMask);
/* display the window */
XMapWindow(display, window);
/* event loop */
while (1) {
XNextEvent(display, &event);
switch (event.type) {
case KeyPress:
/* FALLTHROUGH */
case ClientMessage:
goto breakout;
case Expose:
/* draw the window */
XFillRectangle(display, window, DefaultGC(display, screen), RECT_X, RECT_Y, RECT_WIDTH, RECT_HEIGHT);
/* NO DEFAULT */
}
}
breakout:
/* destroy window */
XDestroyWindow(display, window);
/* close connection to server */
XCloseDisplay(display);
return 0;
}
The client creates a connection with the server by calling XOpenDisplay
. It then requests the creation of a window with XCreateSimpleWindow
. A separate call to XMapWindow
is necessary for mapping the window, that is, for making it visible on the screen.
The square is drawn by calling XFillRectangle
. This operation can only be performed after the window is created. However, performing it once may not be enough. Indeed, the content of the window is not always guaranteed to be preserved. For example, if the window is covered and then uncovered again, its content might require that it be drawn again. The program is informed that the window or a part of it has to be drawn by the reception of an Expose
event.
The drawing of the window content is therefore made inside the loop handling the events. Before entering this loop, the events the application is interested in are selected, in this case with XSelectInput
. The event loop waits for an incoming event: if this event is a key press, the application exits; if it is an expose event, the window content is drawn. The function XNextEvent
blocks and flushes the output buffer if there is no event in the queue.
Going Further
editOther libraries
editXlib does not provide support for buttons, menus, scrollbar, etc. Such widgets are provided by other libraries, which in turn use Xlib. There are two kinds of such libraries:
- libraries built atop of the Intrinsics library (Xt), which provides support for widgets but does not provide any particular widget; specific widgets are provided by widget set libraries that use Xt, such as Xaw and Motif;
- libraries that provide widget sets using Xlib directly, without the Xt library, such as GTK+, Qt (X11 version), and FLTK (X11 version).
Applications using any of these widget libraries typically specify the content of the window before entering the main loop and do not need to explicitly handle Expose
events and redraw the window content.
The XCB library is an alternative to Xlib. Its two main aims are: reduction in library size and direct access to the X11 protocol. A modification of Xlib has been produced to use XCB as a low-level layer.
XCB
Introduction
editXCB (X C Binding) is a C language binding for the X Window System. It aims to replace XLib. The project was started in 2001 by Bart Massey.
Xlib/XCB provides application binary interface compatibility with both Xlib and XCB, providing an incremental porting path.
Aims of XCB
editThe main aims of XCB are:
- reduction in library size and complexity;
- direct access to the X11 protocol.
Secondary aims include making the C interface asynchronous, facilitating better multithreading and making extensions easier to implement (via XML protocol descriptions).
The core and extension protocol descriptions are in XML, with the C bindings created via XSLT. A tertiary aim is to repurpose these protocol descriptions for the creation of protocol documentation, further language bindings, and server-side stubs.
Massey has worked to prove XCB formally correct, using Z notation. (Xlib has long been known to contain errors.)
Example
edit/* Simple XCB application drawing a box in a window */
#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
int
main (int argc, char **argv)
{
xcb_connection_t *c;
xcb_screen_t *s;
xcb_window_t w;
xcb_gcontext_t g;
xcb_generic_event_t *e;
uint32_t mask;
uint32_t values[2];
int done;
xcb_rectangle_t r = { 20, 20, 60, 60 };
/* open connection with the server */
c = xcb_connect (NULL, NULL);
if (xcb_connection_has_error(c) > 0)
{
printf ("Cannot open display\n");
exit (1);
}
s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
/* create window */
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = s->white_pixel;
values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
w = xcb_generate_id (c);
xcb_create_window (c, XCB_COPY_FROM_PARENT, w, s->root,
10, 10, 100, 100, 1,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
s->root_visual,
mask, values);
/* create black graphics context */
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = s->black_pixel;
values[1] = 0;
g = xcb_generate_id (c);
xcb_create_gc (c, g, w, mask, values);
/* map (show) the window */
xcb_map_window (c, w);
xcb_flush (c);
/* event loop */
done = 0;
while (!done && (e = xcb_wait_for_event (c)))
{
switch (e->response_type)
{
/* (re)draw the window */
case XCB_EXPOSE:
printf ("EXPOSE\n");
xcb_poly_fill_rectangle (c, w, g, 1, &r);
xcb_flush (c);
break;
/* exit on keypress */
case XCB_KEY_PRESS:
done = 1;
break;
}
free (e);
}
/* close connection to server */
xcb_disconnect (c);
return 0;
}
Old Example
edit /* Simple XCB application drawing a box in a window */
/* note that this is old code, modern XCB has dropped
* CamelCase, eg XCBConnection -> xcb_connection_t
*/
#include <X11/XCB/xcb.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
XCBConnection *c;
XCBSCREEN *s;
XCBDRAWABLE w;
XCBGCONTEXT g;
XCBGenericEvent *e;
CARD32 mask;
CARD32 values[2];
int done = 0;
XCBRECTANGLE r = { 20, 20, 60, 60 };
/* open connection with the server */
c = XCBConnect(NULL,NULL);
if (c == NULL) {
printf("Cannot open display\n");
exit(1);
}
/* get the first screen */
s = XCBSetupRootsIter( XCBGetSetup(c) ).data;
/* create black graphics context */
g = XCBGCONTEXTNew(c);
w.window = s->root;
mask = XCBGCForeground | XCBGCGraphicsExposures;
values[0] = s->black_pixel;
values[1] = 0;
XCBCreateGC(c, g, w, mask, values);
/* create window */
w.window = XCBWINDOWNew(c);
mask = XCBCWBackPixel | XCBCWEventMask;
values[0] = s->white_pixel;
values[1] = XCBEventMaskExposure | XCBEventMaskKeyPress;
XCBCreateWindow(c, s->root_depth, w.window, s->root,
10, 10, 100, 100, 1,
XCBWindowClassInputOutput, s->root_visual,
mask, values);
/* map (show) the window */
XCBMapWindow(c, w.window);
XCBFlush(c);
/* event loop */
while (!done && (e = XCBWaitForEvent(c))) {
switch (e->response_type & ~0x80) {
case XCBExpose: /* draw or redraw the window */
XCBPolyFillRectangle(c, w, g, 1, &r);
XCBFlush(c);
break;
case XCBKeyPress: /* exit on key press */
done = 1;
break;
}
free(e);
}
/* close connection to server */
XCBDisconnect(c);
return 0;
}
XCB has a comparable, but slightly lower-level API than XLib, as can be seen with these examples.
References
edit- XCB: An X Protocol C Binding ( ) (Bart Massey and Jamey Sharp, 19 September 2001, presented at XFree86 Technical Conference 2001)
- XCL: An Xlib Compatibility Layer For XCB (Jamey Sharp and Bart Massey, 15 April 2002, presented at USENIX 2002)
- X Meets Z: Verifying Correctness In The Presence Of POSIX Threads (Bart Massey and Robert Bauer, 15 April 2002, presented at USENIX 2002)
Motif
Introduction
editMotif (often capitalized as MOTIF) is a graphical widget toolkit for building graphical user interfaces under the X Window System on Unix and other POSIX-compliant systems. It emerged in the 1980s as UNIX workstations were on the rise, as an alternative to the OpenLook GUI.
It is also an industry standard by the name IEEE 1295 (in which case it would be better referred to as the Motif API in order to avoid ambiguity). It was and still is used as the basic building blocks for the Common Desktop Environment. As of version 2.1 Motif supports Unicode which has made it widely used in several multilingual environments.
Motif is distinguished by its use of square, chiseled, three dimensional effects for the various user interface elements — menus, buttons, sliders, text boxes, and the like. This was in vogue, however, as Microsoft Windows 3.x had added a 3D effect and Motif on Unix was increasingly seen as a competitor to Microsoft on Intel personal computers.
Some argue that it is practically obsolete when compared to GTK+ or Qt: Sun Microsystems, a major Motif user, has announced that they will switch over to GTK+ (and GNOME). However, Motif is still the choice for many mission critical systems, especially in the aerospace industry.
Motif was created by the Open Software Foundation (and was sometimes even called OSF/Motif) but is nowadays owned by The Open Group.
There are a few implementations of the Motif API. Motif the toolkit is the first. There is also Open Motif which is a release of the "original" Motif under more liberal licensing terms. Finally, the LessTif project has been working hard to implement the API under the LGPL license.
Open Motif
editOpen Motif (or, unofficially, OpenMotif) is a source code release of the Motif computer programming toolkit by The Open Group, the current owners of Motif.
Open Motif has the same functionality and source code as Motif, but is offered under a license which allows royalty free distribution of Open Motif if the platform upon which it is used is Open Source. This is in contrast to Motif, whose use and distribution requires the payment of royalties.
The license of Open Motif, in other words, allows developers to replace Motif (which many applications still depend on) with Open Motif and avoid the payment of royalties, if the platform the application runs on is Open Source. This includes popular platforms such as Linux and the various variants of BSD.
Open Motif was released to make it easier for users of open source platforms to use applications that require the Motif toolkit to run (thus creating a greater market for vendors of Motif applications).
The initial release of Open Motif was version 2.1.30 in May 2000. The current release that most Linux distributions ship is Open Motif 2.2.3. Open Motif 2.3 is currently in beta test and is available for download at the Open Motif project page.
LessTif
editLessTif is a reimplementation or clone of the Motif computer programming toolkit. LessTif is developed by the Hungry Programmers. It aims to be a compatible free software replacement for Motif.
As opposed to Motif, which is distributed under a proprietary software license that can require the payment of royalties, LessTif is distributed under the LGPL, a less restrictive but free software license, which makes LessTif more attractive to many developers, distributors and users. The license of Motif was the main motivation for the development of LessTif.
LessTif aims for full source and binary compatibility with Motif. While this has not yet been achieved, many Motif applications run with LessTif and/or can be compiled with it.
After the release of Open Motif there is now a second alternative to replace Motif for open source applications. Still, since Open Motif is not itself Open Source software, the development of LessTif continues.
SDL
Introduction
editSimple DirectMedia Layer (SDL) is a cross-platform multimedia library written in C that creates an abstraction over various platforms' graphics, sound, and input APIs, allowing a developer to write a computer game or other multimedia application once and run it on many operating systems including GNU/Linux, Microsoft Windows and MacOS X. It manages video, events, digital audio, CD-ROM, sound, threads, shared object loading, networking and timers.
History
editSam Lantinga created the library, first releasing it in early 1998, while working for Loki Software. He got the idea while porting a Windows application to Macintosh. He then used SDL to port Doom to BeOS. Several other free libraries appeared to work with SDL, such as SMPEG and OpenAL.
The SDL library has bindings with almost every programming language there is, from the popular (C++, Perl, Python (through pygame), Pascal etc.) to the less known (such as Euphoria or Pliant). This and the fact that it is open-source and licensed under the LGPL make SDL a common choice for a lot of multimedia applications.
SDL itself is very simple; it merely acts as a thin, cross-platform wrapper, providing support for 2D pixel operations, sound, file access, event handling, timing, threading, and more. OpenGL is often used with SDL to provide fast 3D rendering. It is often thought of as a cross-platform DirectX, although it lacks some of its more advanced functionality. SDL instead has a huge number of third party extensions that make it easy to do more advanced functions.
The library is divided into several subsystems, namely the Video (handles both surface functions and OpenGL), Audio, CD-ROM, Joystick and Timer subsystems. Besides this basic, low-level support, there also are a few SDL-dependent libraries that provide some additional functionality. These include SDL_image (provides an easy way to load today's most common image formats), SDL_mixer (complex audio functions, mainly for sound mixing), SDL_net (networking support), SDL_ttf (TrueType Font rendering support), SDL_gfx (some additional graphical functions, such as image resizing and rotating) and SDL_rtf (simple Rich Text Format rendering).
Example C Code
edit// Headers
#include "SDL.h"
// Main function
int main( int argc, char* argv[] )
{
// Initialize SDL
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
return 1;
// Delay 2 seconds
SDL_Delay( 2000 );
// Quit SDL
SDL_Quit();
// Return
return 0;
}
A very basic SDL program. It loads SDL subsystems, pauses for 2 seconds, closes SDL, then exits the program.
Here is more advanced example :
#include <SDL.h>
#define DIM 400.0
int main() {
SDL_Surface *screen = SDL_SetVideoMode(DIM, DIM, 0, 0);
SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, DIM, DIM, 24, 0xFF, 0xFF00, 0xFF0000, 0);
double fact = 2;
double cx = -0.74364500005891;
double cy = 0.13182700000109;
while (fact > 1e-18) {
double xa = cx - fact;
double ya = cy - fact;
int y;
for (y = 0; y < DIM; y++) {
Uint8 *pixline = surface->pixels + y*surface->pitch;
double y0 = ya + y/DIM*2*fact;
int x;
for (x = 0; x < DIM; x++) {
double x0 = xa + x/DIM*2*fact;
double xn = 0, yn = 0, tmpxn;
int i;
for (i = 0; i<512; i++) {
tmpxn = xn*xn - yn*yn + x0;
yn = 2*xn*yn + y0;
xn = tmpxn;
if (xn*xn + yn*yn > 4)
break; // approximate infinity
}
if (i == 512) {
// in Mandelbrot set
pixline[x*3] = pixline[x*3+1] = pixline[x*3+2] = 0;
} else {
// not in Mandelbrot set; use escape iteration value to set color (grades of blue then white)
pixline[x*3] = pixline[x*3+1] = i < 256 ? 0 : i - 256;
pixline[x*3+2] = i < 256 ? i : 255;
}
}
}
SDL_BlitSurface(surface, NULL, screen, NULL);
SDL_Flip(screen);
fact /= 2;
}
SDL_Quit();
return(0);
}
That is easily compiled and ran under Linux with "gcc `sdl-config --cflags --libs` -O3 mandelbrot.c && ./a.out", on Windows it's the same, but you have to use MinGW to compile it.
Extensions
edit- SMPEG - SDL MPEG Player Library
- Guichan and ParaGUI - Widget Sets
- GGI - a free cross-platform graphics interface
OpenGL
Introduction
editOpenGL (Open Graphics Library) is a standard specification defining a cross-language cross-platform API for writing applications that produce 3D computer graphics (and 2D computer graphics as well). The interface consists of over 250 different function calls which can be used to draw complex three-dimensional scenes from simple primitives. OpenGL was developed by Silicon Graphics and is popular in the video games industry, where it competes with Direct3D on Microsoft Windows platforms. OpenGL is widely used in computer-aided design, virtual reality, scientific visualization, information visualization, flight simulation, and video game development.
Specification
editAt its most basic level, OpenGL is a specification, meaning it is simply a document that describes a set of functions and the precise behaviors that they must perform. From this specification, hardware vendors create implementations — libraries of functions created to match the functions stated in the OpenGL specification, making use of hardware acceleration where possible. Hardware vendors have to meet specific tests to be able to qualify their implementation as an OpenGL implementation.
Efficient vendor-supplied implementations of OpenGL (making use of graphics acceleration hardware to a greater or lesser extent) exist for Mac OS, Microsoft Windows, Linux, many Unix platforms, Wii and PlayStation 3. Various software implementations exist, bringing OpenGL to a variety of platforms that do not have vendor support. Notably, the open source library Mesa is a fully software-based graphics API which is code-compatible with OpenGL. However to avoid licensing costs associated with formally calling itself an OpenGL implementation, it claims merely to be a "very similar" API.
The OpenGL specification is currently overseen by the OpenGL Architecture Review Board (ARB), which was formed in 1992. The ARB consists of a set of companies with a vested interest in creating a consistent and widely available API. Voting members of the ARB as of April 2006 include 3D hardware manufacturers Silicon Graphics, 3Dlabs, ATI Technologies, NVIDIA and Intel, and computer manufacturers IBM, Apple Computer, Dell, and Sun Microsystems. Microsoft, one of the founding members, left in March 2003. Aside from these corporations, each year many other companies are invited to be part of the OpenGL ARB for one-year terms. With so many companies involved with such a diverse set of interests, OpenGL has become very much a general-purpose API with a wide range of capabilities.
According to current plans, control of OpenGL will pass to the Khronos Group by the end of 2006. This is being done in order to improve the marketing of OpenGL, and to remove barriers between the development of OpenGL and OpenGL ES.[1]
Kurt Akeley and Mark Segal authored the original OpenGL specification. Chris Frazier edited version 1.1. Jon Leech edited versions 1.2 through the present version 2.0.
Design
editOpenGL serves two main purposes:
- To hide the complexities of interfacing with different 3D accelerators, by presenting the programmer with a single, uniform API.
- To hide the differing capabilities of hardware platforms, by requiring that all implementations support the full OpenGL feature set (using software emulation if necessary).
OpenGL's basic operation is to accept primitives such as points, lines and polygons, and convert them into pixels. This is done by a graphics pipeline known as the OpenGL state machine. Most OpenGL commands either issue primitives to the graphics pipeline, or configure how the pipeline processes these primitives. Prior to the introduction of OpenGL 2.0, each stage of the pipeline performed a fixed function and was configurable only within tight limits but in OpenGL 2.0 several stages are fully programmable using GLSL.
OpenGL is a low-level, procedural API, requiring the programmer to dictate the exact steps required to render a scene. This contrasts with descriptive (aka scene graph or retained mode) APIs, where a programmer only needs to describe a scene and can let the library manage the details of rendering it. OpenGL's low-level design requires programmers to have a good knowledge of the graphics pipeline, but also gives a certain amount of freedom to implement novel rendering algorithms.
OpenGL has historically been influential on the development of 3D accelerators, promoting a base level of functionality that is now common in consumer-level hardware:
- Rasterised points, lines and polygons as basic primitives
- A transform and lighting pipeline
- Z-buffering
- Texture mapping
- Alpha blending
Many modern 3D accelerators provide functionality far above this baseline, but these new features are generally enhancements of this basic pipeline rather than radical reinventions of it.
Example
editWe first clear the color buffer, in order to start with a blank canvas:
glClear( GL_COLOR_BUFFER_BIT );
We now set the modelview matrix, which controls the position of the camera relative to the primitives we render. We move it backwards 3 units along the Z axis, which leaves it pointing towards the origin:
glMatrixMode( GL_MODELVIEW ); /* Subsequent matrix commands will affect the modelview matrix */ glLoadIdentity(); /* Initialize the modelview to identity */ glTranslatef( 0, 0, -3 ); /* Translate the modelview 3 units along the Z axis */
The projection matrix governs the perspective effect applied to primitives, and is controlled in a similar way to the modelview matrix:
glMatrixMode( GL_PROJECTION ); /* Subsequent matrix commands will affect the projection matrix */ glLoadIdentity(); /* Initialize the projection matrix to identity */ glFrustum( -1, 1, -1, 1, 1, 1000 ); /* Apply a perspective-projection matrix */
Finally, we issue a polygon - a green square oriented in the XY plane:
glBegin( GL_POLYGON ); /* Begin issuing a polygon */ glColor3f( 0, 1, 0 ); /* Set the current color to green */ glVertex3f( -1, -1, 0 ); /* Issue a vertex */ glVertex3f( -1, 1, 0 ); /* Issue a vertex */ glVertex3f( 1, 1, 0 ); /* Issue a vertex */ glVertex3f( 1, -1, 0 ); /* Issue a vertex */ glEnd(); /* Finish issuing the polygon */
Documentation
editOpenGL's popularity is partially due to the excellence of its official documentation. The OpenGL ARB released a series of manuals along with the specification which have been updated to track changes in the API. These are almost universally known by the colors of their covers:
- The Red Book - The OpenGL Programmer's guide. ISBN 0-321-33573-2
- A readable tutorial and reference book - this is a 'must have' book for OpenGL programmers.
- The Blue Book - The OpenGL Reference manual. ISBN 0-321-17383-X
- Essentially a hard-copy printout of the man pages for OpenGL.
- Includes a poster-sized fold-out diagram showing the structure of an idealized OpenGL implementation.
- The Green Book - Programming OpenGL for the X Window System. ISBN 0-201-48359-9
- A book about X11 interfacing and GLUT.
- The Alpha Book (which actually has a white cover) - OpenGL Programming for Windows 95 and Windows NT. ISBN 0-201-40709-4
- A book about interfacing OpenGL with Microsoft Windows.
Then, for OpenGL 2.0 and beyond:
- The Orange Book - The OpenGL Shading Language. ISBN 0-321-33489-2
- A readable tutorial and reference book for GLSL.
Extensions
editThe OpenGL standard allows individual vendors to provide additional functionality through extensions as new technology is created. Extensions may introduce new functions and new constants, and may relax or remove restrictions on existing OpenGL functions. Each vendor has an alphabetic abbreviation that is used in naming their new functions and constants. For example, NVIDIA's abbreviation (NV) is used in defining their proprietary function glCombinerParameterfvNV()
and their constant GL_NORMAL_MAP_NV
. It may happen that more than one vendor agrees to implement the same extended functionality. In that case, the abbreviation EXT is used. It may further happen that the Architecture Review Board "blesses" the extension. It then becomes known as a standard extension, and the abbreviation ARB is used. The first ARB extension was GL_ARB_multitexture
, introduced in version 1.2.1. Following the official extension promotion path, multitexturing is no longer an optionally implemented ARB extension, but has been a part of the OpenGL core API since version 1.3.
Before using an extension a program must first determine its availability, and then obtain pointers to any new functions the extension defines. The mechanism for doing this is platform-specific and libraries such as GLEW and GLEE exist to simplify the process.
Specifications for nearly all extensions can be found at the official extension registry [1].
Associated utility libraries
editSeveral libraries are built on top of or beside OpenGL to provide features not available in OpenGL itself. Libraries such as GLU can always be found with OpenGL implementations, and others such as GLUT and SDL have grown over time and provide rudimentary cross platform windowing and mouse functionality and if unavailable can easily be downloaded and added to a development environment. Simple graphical user interface functionality can be found in libraries like GLUI or FLTK. Still others libraries like AUX are deprecated libraries that have been superseded by functionality commonly available in more popular libraries, but code still exists out there particularly in simple tutorials. Other libraries have been created to provide OpenGL application developers a simple means of managing OpenGL extensions and versioning, examples of these libraries include GLEW "The OpenGL Extension Wrangler Library" and GLEE "The OpenGL Easy Extension library".
In addition to the aforementioned simple libraries other higher level object oriented scene graph retained mode libraries exist such as PLIB, OpenSG, OpenSceneGraph, and OpenGL Performer, these are available as cross platform Open Source or proprietary programming interfaces written on top of OpenGL and systems libraries to enable the creation of real-time visual simulation applications.
Mesa 3D ([2]) is an Open Sourced implementation of OpenGL. It supports pure software rendering as well as providing hardware acceleration for several 3D graphics cards under Linux. As of February 2 2006 it implements the 1.5 standard, and provides some of its own extensions for some platforms.
Bindings
editIn order to emphasize its multi-language and multi-platform characteristics, various bindings and ports have been developed for OpenGL in many languages. Most notably, the Java 3D library can rely on OpenGL for its hardware acceleration. Direct bindings are also available like the Lightweight Java Game Library which has a direct binding of OpenGL for Java and other game related components. Very recently, Sun has released beta versions of the JOGL system, which provides direct bindings to C OpenGL commands, unlike Java 3D which does not provide such low level support. The OpenGL official page [3] lists various bindings for Java, Fortran 90, Perl, Pike, Python, Ada, Delphi and Visual Basic. Bindings are also available for C++ and C#, see [4].
Higher level functionality
editOpenGL was designed to be graphic output-only: it provides only rendering functions. The core API has no concept of windowing systems, audio, printing to the screen, keyboard/mouse or other input devices. While this seems restrictive at first, it allows the code that does the rendering to be completely independent of the operating system it is running on, allowing cross-platform development. However some integration with the native windowing system is required to allow clean interaction with the host system. This is performed through the following add-on APIs:
- GLX - X11 (including network transparency)
- WGL - Microsoft Windows
Additionally the GLUT and SDL libraries provide functionality for basic windowing using OpenGL, in a portable manner. MacOS X has three APIs to get OpenGL support: AGL for Carbon, NSOpenGL for Cocoa and CGL for lower-level access.
History
editToday the digital generation of animated scenes in three dimensions is a regular fixture in everyday life. Scientists utilize computer graphics to analyze simulations of every possibility. Engineers and architects design virtual models using computer graphics. Movies employ computer graphics to create stunning special effects or entire animated films. And over the past few years, computer games have brought computer graphics technology to regular consumers, using graphics to bring their players into worlds that could never exist.
Bringing digital graphics technology to such widespread use was not without its challenges. Fifteen years ago, developing software that could function with a wide range of graphics hardware and all of their different interfaces was time consuming. Each team of programmers developed interfaces separately, and there was consequently much duplicated code. This was hindering the growing industry of computer graphics.
By the early 1990's SGI, a leader in 3D graphics, and its programming API, IrisGL, had become a defacto industry standard, over-shadowing the open-standards-based PHIGS. The IrisGL programming interface (API) was elegant, easy-to-use, and, importantly, supported immediate-mode rendering. By contrast, PHIGS was clunky, hard to use, and was several generations behind IrisGL in function and capability, primarily due to the dysfunctional PHIGS standardization process. None-the-less, competing vendors, including Sun Microsystems, Hewlett-Packard and IBM were able to bring to market credible 3D hardware, supported by proprietary extensions to PHIGS. By the early 90's, 3D graphics hardware technology was fairly well understood by a large number of competitors and was no longer a discriminating factor in computer systems purchases. Thus, rather than prolonging a contentious and dangerous fight between IrisGL and PHIGS, SGI sought to turn a defacto standard into a true open standard.
The IrisGL API itself wasn't suitable for opening (although it had been previously licensed to IBM and others), in part because it had accumulated cruft over the years. For example, it included a windowing, keyboard and mouse API, in part because it was developed before the X11 Window System versus Sun's NeWS battle had resolved. Thus, the API to be opened needed to be cleaned up. In addition, IrisGL had a large software vendor (ISV) portfolio; the change to the OpenGL API would keep ISV's locked onto SGI (and IBM) hardware for a few years while market support for OpenGL matured. Meanwhile, SGI would continue to try to maintain a vendor lock by pushing the higher-level and proprietary Iris Inventor and Iris Performer programming API's.
The result is known as OpenGL. OpenGL standardized access to hardware, and pushed the development responsibility of hardware interface programs, sometimes called device drivers, to hardware manufacturers and delegated windowing functions to the underlying operating system. With so many different kinds of graphic hardware, getting them all to speak the same language in this way had a remarkable impact by giving software developers a higher level platform for 3D-software development.
In 1992, SGI led the creation of the OpenGL architectural review board (OpenGL ARB), the group of companies that would maintain and expand the OpenGL specification for years to come. OpenGL evolved from (and is very similar in style to) SGI's earlier 3D interface, IrisGL. One of the restrictions of IrisGL was that it only provided access to features supported by the underlying hardware. If the graphics hardware did not support a feature, then the application could not use it. OpenGL overcame this problem by providing support in software for features unsupported by hardware, allowing applications to use advanced graphics on relatively low-powered systems.
In 1994 SGI played with the idea of releasing something called "OpenGL++" which included elements such as a scene-graph API (presumably based around their Performer technology). The specification was circulated among a few interested parties - but never turned into a product.
When Direct3D was released in 1995, Microsoft, SGI, and Hewlett-Packard initiated the Fahrenheit project, which was a joint effort with the goal of unifying the OpenGL and Direct3D interfaces - and again, adding a scene-graph API. It initially showed some promise of bringing order to the world of interactive 3D computer graphics APIs, but on account of financial constraints at SGI and general lack of industry support it was abandoned. The engineers involved at SGI held a beach party in celebration - complete with bonfires on which they burned piles of Fahrenheit documentation.
OpenGL 2.0
editOpenGL 2.0 was conceived by 3Dlabs to address concerns that OpenGL was stagnating and lacked a strong direction. 3Dlabs proposed a number of major additions to the standard, the most significant of which was GLSL (the OpenGL Shading Language, also slang). This would enable the programmer to replace the OpenGL fixed-function vertex and fragment pipelines with shaders written in a C-like language, massively expanding the range of graphical effects possible. GLSL was notable for making relatively few concessions to the limitations of the hardware then available; this hearkened back to the earlier tradition of OpenGL setting an ambitious, forward-looking target for 3D accelerators rather than merely tracking the state of currently available hardware. The final OpenGL 2.0 specification [5] includes support for GLSL, but omits many of the other features originally proposed which were deferred to later versions of OpenGL (although many are now available as extensions).
OpenGL 2.1
editOpenGL 2.1 was released on August 2, 2006 and is backward compatible with all prior OpenGL versions. OpenGL 2.1 incorporates the following functionality:
- OpenGL Shading Language revision 1.20
- Commands to specify and query non-square matrix uniforms for use with the OpenGL Shading Language
- Pixel buffer objects for efficient image transfers to and from buffer objects for commands such as glTexImage2D and glReadPixels.
- This functionality corresponds to the ARB_pixel_buffer_object extension.
- sRGB texture formats.
- This functionality corresponds to the EXT_texture_sRGB extension.
OpenGL support libraries
edit- GLUT - The OpenGL utility toolkit.
- GLU - Some additional functions for OpenGL programs.
- GLEW - The OpenGL Extension Wrangler Library.
References
edit- ↑ "OpenGL ARB to Pass Control of OpenGL Specification to Khronos Group". Press Releases. Khronos Group. July 31, 2006. Retrieved 2006-08-01.
Qt
Introduction
editQt is a cross-platform application development framework, widely used for the development of graphical user interface programs, and, since the release of Qt 4, also used for developing non-GUI programs such as console tools and servers. Qt is most notably used in KDE, Qtopia and OPIE. It is produced by the Norwegian company Trolltech, formerly Quasar Technologies and was later bought by Nokia. Trolltech insiders pronounce Qt as "cute".
Qt uses standard C++, but extends the language by providing an additional pre-processor that converts Qt's extensions into pure C++. Qt can also be used by programmers using other languages; bindings exist for Python (PyQt), Ruby, PHP, C, Perl, Pascal, and Java (Jambi). It runs on all major platforms, and has extensive internationalization support. Non-GUI features include SQL database access, XML parsing, thread management, and a unified cross-platform API for file handling.
Varieties
editQt is released by Trolltech on the following platforms:
- Qt/X11 — Qt for X Window System
- Qt/Mac — Qt for Apple MacOS X
- Qt/Windows — Qt for Microsoft Windows
- Qt/Embedded — Qt for embedded platforms (PDA, Smartphone, ...)
- Qt/Jambi — Qt for Java platform Development.
There are four editions of Qt available on each of these platforms, namely:
- Qt Console — edition for non-GUI development.
- Qt Desktop Light — entry level GUI edition, stripped of network and database support.
- Qt Desktop — complete edition.
- Qt Open Source Edition — complete edition for open source developers.
The first three editions are released under a commercial license which permits closed source development; while the Open Source edition is available under the GPL license, and the LGPL (starting with version 4.5) and additionally under the Q Public License (QPL) for the Qt/X11 version.
In case of the X11 platform, the QPL allows the final application to be licensed under various open source licenses, such as the LGPL or the Artistic license. For the Windows and Mac OS X platforms, the GPL is the only Open Source license available so the applications developed with it must be GPL as well.
All editions support a wide range of compilers, including the GCC C++ compiler. Official support for the Visual Studio suite is, however, restricted to the commercial Qt/Windows edition. The Q../Free project has released several patches which add support for Microsoft Visual Studio and Borland C++ Builder to the open-source version of Qt/Windows.
Current
editTrolltech released Qt 4 on June 28, 2005 and introduced five new technologies in the framework:
- Tulip A set of template container classes.
- Interview A model/view architecture for item views.
- Arthur A 2D painting framework.
- Scribe A Unicode text renderer with a public API for performing low-level text layout.
- MainWindow A modern action-based main window, toolbar, menu, and docking architecture.
Qt 4 is dual-licensed under GPL and proprietary licenses on all supported platforms including Windows (while Qt/Windows 3.3 is only released under a proprietary license).
Qt 4.1, released on December 19, 2005, introduced integrated SVG Tiny support, a PDF backend to Qt's printing system, and a few other features.
Qt 4.2, released on October 4, 2006, introduced native CSS support for widget styling, as well as the QGraphicsView framework for efficient rendering of thousands of 2D objects onscreen, to replace Qt 3.x's QCanvas class.
History
editHaavard Nord and Eirik Chambe-Eng (the original developers of Qt and the CEO and President of Trolltech respectively) began development of "Qt" in 1991, three years before the company was incorporated as Quasar Technologies, then changed the name to Troll Tech, and then to Trolltech.
The toolkit was called Qt because the letter Q looked beautiful in Haavard's Emacs font, and T was inspired by Xt, the X toolkit.
Controversy erupted around 1998 when it became clear that KDE was going to become one of the leading desktop environments for GNU/Linux. As KDE was based on Qt, many people in the open source and free software movements were worried that an essential piece of one of their major operating systems would be proprietary.
This gave rise to two efforts: the Harmony toolkit which sought to duplicate the Qt Toolkit under a free software license and the GNOME desktop that was meant to supplant KDE entirely. The GNOME Desktop uses the GTK+ toolkit which was written for the GIMP, and mainly uses the C programming language.
Until version 1.45, source code for Qt was released under the FreeQt license — which was viewed as not compliant to the open source principle by the Open Source Initiative and Free Software Foundation because while the source was available it did not allow the redistribution of modified versions. With the release of version 2.0 of the toolkit, the license was changed to the QPL, a free software license but one regarded by the Free Software Foundation as incompatible with the GPL. Compromises were sought between KDE and Trolltech wherein Qt would not be able to fall under a more restrictive license than the QPL, even if Trolltech was bought out or went bankrupt. This led to the creation of the KDE Free Qt foundation, which guarantees that Qt would fall under a BSD license should no open source version of Qt be released during 12 months.
The first versions of Qt had only two flavors: Qt/X11 for Unix and Qt/Windows for the Windows platform. The Windows platform was only available under the commercial license. In the end of 2001, Trolltech released Qt 3.0 which added support for the Mac OS X platform. The Mac OS X support was available only in the commercial license, until June 2003, where Trolltech released the version 3.2 with Mac OS X support available under the GPL license.
In 2002 members of the KDE on Cygwin project began porting the GPL licensed Qt/X11 code base to Windows. This was in response to Trolltech's refusal to license Qt/Windows under the GPL on the grounds that Windows was not an open-source platform. The project achieved reasonable success although it never reached production quality. Qt/Windows 4 was released under the GPL by Trolltech in June 2005. Qt4 now supports the same set of platforms in the Open Source editions as in the commercial edition.
Design
editThe innovation of Qt when it was first released relied on a few key concepts.
Complete abstraction of the GUI
editQt uses its own paint engine and controls. This makes the work of porting to other platforms easier because very few classes in Qt depended really on the target platform. Qt used to emulate the native look of its intended platforms, which occasionally led to slight discrepancies where that emulation wasn't perfect. This, however, no longer applies because the latest versions of Qt use the native styles API of the different platforms to draw the Qt controls.
Meta Object Compiler
editKnown as the moc, this is a tool that one must run on the sources of a Qt program prior to compiling it. The tool will generate "Meta Information" about the classes used in the program. This meta information is used by Qt to provide programming features not available in C++: introspection and the signals and slots|signal/slot system.
The use of an additional tool has been criticised by part of the C++ community, stating that Qt programming is making a mockery of C++. In particular, the choice of an implementation based on macros has been criticized for its absence of type safety. Some people confused the macros with new C++ keywords, and criticized the pollution of the namespace. This is viewed by Trolltech as a necessary trade-off to provide introspection and dynamically generated slots or signals. Further, when Qt 1.x was released, consistency between compiler template implementations could not be relied upon.
The use of moc allows for a very flexible signal/slot messaging system, so that multiple signals can connect to multiple slots, to other signals, or to slots on different threads, in a "callback safe" manner.
Examples
edit- Mandel is an interactive, multiplatform and multilingual program by Wolf Jung for drawing the Mandelbrot set and Julia sets, and for illustrating and researching their mathematical properties. It's graphical user interface is based on Qt. It is available on Linux, Unix, Windows, and Mac. The source code is available under the GNU General Public License.
References
edit
GTK+
Introduction
editThe GIMP Toolkit (abbreviated as GTK+) is a free and open source widget toolkit for creating graphical user interfaces that was initially created in 1998 for the GIMP, a raster graphics editor, by Spencer Kimball, Peter Mattis, and Josh MacDonald — all of whom were members of eXperimental Computing Facility (XCF) at Berkeley University. GTK+ is licensed under the LGPL.
Unlike many other widget toolkits, GTK+ isn't based on Xt. The advantage of this is that it allows GTK+ to be available on other systems and to be much more flexible. GTK+ allows the end-user to configure the look of the toolkit, down to offering a number of different display engines. Engines exist which emulate the look of other popular toolkits or platforms, like Windows 95, Motif, Qt or NextStep. The disadvantage is that it doesn't have access to the X resource database, which is the traditional way for customizing X11 applications.
GTK+ 2 includes improved text rendering using Pango, a new theme engine, improved accessibility using Accessibility Toolkit, complete transition to Unicode using UTF-8 strings and a more flexible API. However, GTK+ 2 lacks compatibility with GTK+ 1, and programmers must port applications to it. Starting with version 2.8 GTK+ relies on the Cairo library for rendering of vector graphics.
Programming languages
editGTK+ uses the C programming language, although its designers use an object-oriented paradigm. The GNOME platform bindings provide for C++ (gtkmm), Perl, Ruby, Java and Python (PyGTK) bindings; others have written bindings for many other programming languages (including Ada, D, Haskell, Lua, Pascal, PHP, Pike and all .NET programming languages).
Environments that use GTK+
edit- The GNOME environment uses GTK+ as a base, which means that programs written for GNOME use GTK+ as their toolkit.
- Xfce also uses it as its base, though its apps typically do not depend on as many programs. (This is the difference between something being branded as a "GNOME program" and as a "GTK+ program".)
- The GPE Palmtop Environment, Maemo (Nokia's Internet-tablet framework), and Access Linux Platform (a new Palm OS-compatible Personal digital PDA platform) also use GTK+ as a base.
Those desktop environments are not required to run GTK+ programs, though. If the libraries the program requires are installed, a GTK+ program can run on top of other X11-based environments such as KDE or an X11-plus-window manager environment; this includes MacOS X if X11.app is installed. GTK+ can also run under Microsoft Windows. Some of the more unusual ports include DirectFB and ncurses.
Resources
Resources
edit- Xorg Foundation Official Website (http://www.x.org)
- X Window FAQs (http://www.faqs.org/faqs/x-faq/)
- X Window Wikipedia entry (http://en.wikipedia.org/wiki/X_Window_System)
- XLib Programming Manual, Published by O'Reilly & Associates, Inc. (http://www.sbin.org/doc/Xlib/)
- XLib Functions Manual (http://tronche.com/gui/x/xlib/function-index.html)
- GTK+ References (http://www.gtk.org/api/)
- GTK+ Tutorial (http://www.gtk.org/tutorial/)
- XCB wiki (http://xcb.freedesktop.org/)
- XCB API reference (http://xcb.freedesktop.org/XcbApi)
- XCB Further publications (http://xcb.freedesktop.org/Publications)
- SDL website (http://www.libsdl.org)
- SDL.NET homepage (http://cs-sdl.sourceforge.net)
- The Game Programming Wiki's SDL Tutorials (http://gpwiki.org/index.php/SDL_tutorials)
- SDL Documentation (http://www.libsdl.org/cgi/docwiki.cgi/FrontPage)
- Site dedicated to SDL. SDL forum (http://gamescreators.sourceforge.net/)
- Official OpenGL Website (http://www.opengl.org)
- SGI's OpenGL website (http://www.sgi.com/products/software/opengl/)
- OpenGL at Curlie
Further reading
edit- Richard S. Wright Jr. and Benjamin Lipchak: OpenGL Superbible, Third Edition, Sams Publishing, 2005, ISBN 0-672-32601-9
- Astle, Dave and Hawkins, Kevin: Beginning OpenGL Game Programming, Course Technology PTR, ISBN 1-59200-369-9
- Fosner, Ron: OpenGL Programming for Windows 95 and Windows NT, Addison Wesley, ISBN 0-201-40709-4
- Kilgard, Mark: OpenGL for the X Window System, Addison-Wesley, ISBN 0-201-48359-9
- Lengyel, Eric: The OpenGL Extensions Guide, Charles River Media, ISBN 1-58450-294-0
- OpenGL Architecture Review Board, et al: OpenGL Reference Manual: The Official Reference Document to OpenGL, Version 1.4, Addison-Wesley, ISBN 0-321-17383-X
- OpenGL Architecture Review Board, et al: OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 2, Fifth Edition, Addison-Wesley, ISBN 0-321-33573-2
- Rost, Randi J.: OpenGL Shading Language, Addison-Wesley, ISBN 0-321-19789-5