Next: , Previous: , Up: Classes   [Index]


GLXCanvasPane

GLXCanvasPane Class

The GLXCanvasPane class displays 3 dimensional graphics drawn with OpenGL in a X window. The class requires that the display server supports GLX visuals, which is the case with most modern X server installations.

The class includes instance variables that select GLX visual properties, methods that create and display the window, and provides a simple API for the window’s application program.

There is an example program that displays a GLXCanvasPane window at the end of this section. See GLXExampleProgram.

GLXCanvasPane Applications

The GLXCanvasPane class provides a simple application framework that is compatible with OpenGL’s single threading model. The framework consists of a number of callback methods and a run method, that are configured when the program starts.

The methods that install callbacks are:


onButtonPress
onIdle
onKeyPress
onExpose
onPointerMotion
onResize
onTimerTick
onAnimation

There is a complete description of each of these methods in the section, Instance Methods.

Typically, a program installs its callback methods and initializes the OpenGL system, and then calls the method run to begin the program’s event loop. The example program given at the end of this section follows this process. The program’s initialization and startup, which is contained in main (), is shown here.


int main () {
  GLXCanvasPane new pane;

  pane initialize (1, 150, 500, 500);
  pane title "GLXCanvasPane Demonstration";
  pane map;
  pane raiseWindow;

  pane onKeyPress "myKeyPressMethod";
  pane onExpose "myExposeMethod";
  pane onTimerTick "myTimerTickHandler";
  pane onResize "myResizeMethod";

  pane initGL;
  
  pane run;

}

Selecting GLX Visuals

The GLXCanvasPane class selects visuals based on the values of many of the instance variables. These instance variables correspond with the attributes recognized by the glXChooseVisual(3) library call.

The instance variables’ default settings select a double buffered, TrueColor or DirectColor visual, with 24 color bits per pixel, and a stencil buffer with 8 bit planes, which is supported by many common GLX servers. The equivalent C code for these attributes, formatted as an argument for glXChooseVisual(3), would be:


static GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8,
                      GLX_DOUBLEBUFFER, None};

These attributes also correspond to the available attributes output by a program like glxinfo(1). Refer to the glXChooseVisual(3) and glxinfo(1) manual pages for more information

Drawing with X Fonts

The GLXCanvasPane class defines three methods, useXFont, drawText, drawTextW, and freeXFont that facilitate drawing text with X fonts.

Typically, a program calls useXFont with the name of the X font when it initializes OpenGL (that is, after first creating the window and mapping the GLX context to the display), then using drawText to draw the text in the program’s drawing routine. Finally, the program calls freeXFont to release the font data before exiting, or when changing fonts if the program uses multiple fonts for drawing.


myPane useXFont "fixed";    /* Call during OpenGL initialization. */
                            /* The argument, "fixed," is the name */
                            /* of the font to be used.            */

...

                            /* Called from within the program's   */
                            /* drawing routine.                   */
myPane drawText "Text to appear in the window";


...

myPane freeXFont;           /* Called during program cleanup or   */
                            /* before calling useXFont again to   */
                            /* draw text in a different font.     */

The Ctalk distribution contains an example program in the demos/glx subdirectory, xfont.ca that demonstrates this drawing method.

Drawing with FreeType Fonts

The methods to draw text using the freetype libraries are similar to those that render X bitmap fonts. The Freetype libaries support text rendering using Freetype, Truetype, and Postscript Type1 fonts.

The main differences are that, because of the way the fonts are rendered on the screen, their measurements are given in the coordinates of the current viewing and transformation matrices.

In addition, when loading a font using useFTFont, the method uses the path name of the font file, not an identifier. This is the only interface that the Freetype libraries use. To use the system’s font caching, refer to See X11FreeTypeFont.

There is a demo program that renders Freetype fonts in the demos/glx subdirectory of the Ctalk source package, ftfont.ca.

Display Synchronization

On OpenGL releases that support synchronization, GLXCanvasPane applications can synchronize buffer swapping with the video display’s refresh rate. GLXCanvasPane class provides the methods syncSwap,refreshRate, and frameRate which allow programs to adjust buffer swapping to match the video refresh rate. The demonstration program, demos/glx/glxchaser.ca provides an example of how to use these methods.

To find out which GLX extensions the display server supports, the extensions method, below, returns the extensions as a String object.

Currently, video syncronization support is limited to MESA releases that provide the GLX_MESA_swap_control and GLX_OML_sync_control extensions.

Instance Variables

animationHandler

Defines the callback method that is called 24 times a second to perform animation.

buttonPressHandler

A Method object that defines the callback method that is executed when a mouse button is pressed.

buttonState

An Integer that records whether a mouse button is currently pressed. The class defines macro constants to record the states, and you can include these definitions in your programs to interpret the value of buttonState.


#define buttonStateButton1 (1 << 0)
#define buttonStateButton2 (1 << 1)
#define buttonStateButton3 (1 << 2)
#define buttonStateButton4 (1 << 3)
#define buttonStateButton5 (1 << 4)

So to check if the mouse button 1 is pressed, the program could contain an expression like the following.


if (myPane buttonState & buttonStateButton1) {
   printf ("Button 1 pressed.\n");
}

colormap

An Integer that contains the X resource ID of the default colormap of the current display and screen.

displayPtr

A Symbol that contains the address of the X server’s display handle as provided to the application. The displayPtr instance variable is filled in by the initialize methods.

exposeHandler

Defines the method that is called each time the program’s window receives an Expose event from the display. This handler is essential to displaying the window in coordination with other display events. If this variable is not initialized, then the run method calls the swapBuffers method.

glxContextPtr

A Symbol that contains the address of the GLXContext that is current for the GLXCanvasPane's window. This variable is normally filled in by the map method.

idleHandler

A Method that contains the callback that the program executes when not processing events from the display.

keyPressHandler

A Method that handles the KeyPress events that the display sends to the program’s window. This variable should be set during program initialization using the onKeyPress method before the program starts the run method.

pointerMotionHandler

A Method that is called whenever the window receives a MotionNotify event.

resizeHandler

A Method that is called whenever the window receives a ConfigureNotify event. The variable should be set using the onResize method before the program starts the run method.

shiftState

An Integer that records whether the any of the Shift, Control, or Alt keys is currently pressed. The class defines macro constants to record the states, and you should also include the definitions in your program if it needs to monitor the state of the modifier keys.


#define shiftStateShift (1 << 0)
#define shiftStateCtrl  (1 << 1)
#define shiftStateAlt   (1 << 2)

So, for example, to test whether a Control key is pressed, you can use an expression like the following.


if (myPane shiftState & shiftStateCtrl) 
   printf ("Control key pressed.\n");

timerMSec

An Integer that defines the time in milliseconds between onTimerTick handler calls. The default is 1 millisecond.

timerTickHandler

A Method that defines the callback that is executed when the classes’ interval timer reaches 0.

visualAuxBuffers

An Integer that, in combination with visualSetAuxBuffers, defines the minimum number of auxiliary buffers that the selected visual must have.

visualBufferSize

An Integer that defines the desired color index buffer size. The instance variable visualSetBufferSize must also be set to true.

visualDepthSize

An Integer that contains the size of the visual’s depth buffer. The visualSetDepthSize instance variable must also be true for this value to take effect.

visualDoubleBuffer

A Boolean that selects a double-buffered GLX visual if true, or a single-buffered visual if false.

visualInfoPtr

A Symbol that contains the address of a X visual selected when the pane’s window is created, which normally happens when a program calls one of the initialize methods described below.

visualRedSize
visualGreenSize
visualBlueSize
visualAlphaSize

Integer values that, if greater than zero, try to select thea largest buffer for that color channel of at least the specified size. If one of the values is zero, then glXChooseVisual(3) tries to select the smallest available buffer for that color channel.

visualRedAccumSize
visualGreenAccumSize
visualBlueAccumSize
visualAlphaAccumSize

Integer values that, if greater than zero, try to select thea largest accumulator buffer for that color channel of at least the specified size. If one of the values is zero, then glXChooseVisual(3) tries to select a visual with no accumulator buffer for that color channel.

visualRGBA

A Boolean that selects a TrueColor or DirectColor visual if true, or a PseudoColor or StaticColor visual if false. Also, the visualSetBufferSize and visualBufferSize instance variables are ignored when this variable is true.

visualStencilPlanes

An Integer the selects the number of stencil bitplanes if greater than zero. If zero, then a visual with no stencil buffer is selected if possible.

visualStereo

A Boolean value that selects a stereo visual if true.

xLineHeight

An Integer that contains the line height in pixels of a font that has been selected by the useXFont method. This variable is read only.

xMaxCharWidth

An Integer that contains the maximum width in pixels of a character for a X font that has been selected by useXFont. This value is read only.

Instance Methods

alpha (Float alpha)

Sets the alpha channel (opacity) when rendering outline fonts. Values should be between 0.0 (transparent) and 1.0 (opaque). The Ctalk library’s default value is 1.0. Calling this method also sets the value of the receiver pane’s ftFontVar fgAlpha instance variable.

deleteAndClose (void)

Releases the receiver pane’s GLX context and deletes the X11 window, and shuts down the application’s X11 input client.

displayHeigth (void)
displayWidth (void)

These methods return an Integer with the display height and width in pixels, respectively.

drawFmtText (Float xOrg, Float yOrg, String fmt, ...)

Draws the text given by fmt and its arguments at the matrix position given by xOrg,yOrg.

drawFmtTextFT (Float xOrg, Float yOrg, String fmt, ...)

Display the string given by fmt and its arguments at the matrix coordinates xOrg, yOrg in the currently selected Freetype font. This call, like all calls that render text, should be preceded by a call to useFTFont.

drawFmtTextW (Integer xOrg, Integer yOrg, String fmt, ...)

Draws the formatted text of fmt and its arguments at the pixel position given by xOrg, yOrg. OpenGL uses the lower left-hand corner of the window as the origin for pixel coordinates.

drawText (Float xOrg, Float yOrg, String text)
drawText (Float xOrg, Float yOrg, Float red, Float green, Float blue, String text)

Draws text at the matrix position given by xOrg,yOrg.

The program must have registered a X font for drawing with a previous call to the useXFont method.

If the red, green, and blue arguments are given, the method draws the text in that color. Otherwise, the method (via OpenGL) draws the text using the last OpenGL color setting.

drawTextFT (Float xOrg, Float yOrg, String text)
drawTextFT (Float xOrg, Float yOrg, Float red, Float green, Float blue, Float alpha, String text)

Draws the string given by text at the matrix coordinates xOrg, yOrg.

The red, green, blue, and alpha arguments, if used, should be between the values of 0.0 and 1.0, so they can be passed along to the OpenGL API directly, and also to set the receiver’s ftFontVar instance variable (a X11FreeTypeFont values for its instance variables: fgRed, fgGreen, fgBlue, and fgAlpha See X11FreeTypeFont.

drawTextW (Float xOrg, Float yOrg, String text)
drawTextW (Float xOrg, Float yOrg, Float red, Float green, Float blue, String text)

Draws text using the window’s xOrg,yOrg pixel as the origin.

If the red, green, and blue arguments are given, the method draws the text in that color. Otherwise, the method (via OpenGL) draws the text using the last OpenGL color setting.

This method allows text to be positioned relative to the window’s pixels, which avoids the need for programs to translate a matrix position into a pixel position manually. This allows a program to position text more easily when it is necessary to measure spaces using the dimensions of the text and font that are being displayed.

The coordinates’ origin (0,0) is at the lower left-hand corner of the window, and the pixel coordinates increase as the position moves toward the top and right of the window.

The GL function glWindowPos2i, which this method uses internally, is an extension in many GL implementations. Ctalk checks for the function when building the Ctalk libraries. If glWindowPos2i is not present in the machine’s GL libraries, then programs that try to use these methods display an error message on the terminal and exit.

extensions (void)

Returns the supported GLX extensions from the display server as a String object.

frameRate (void)

Returns the rate that the program updates the display, in frames per second. The algorithm that calculates the frame rate measures frames over a five-second interval.

freeFTFont (void)

Releases the Freetype font in use.

freeXFont (void)

Frees the font data that was allocated by a previous call to useXFont. Programs should call this method when cleaning up before program exit, or when switching fonts by a subsequent call to useXFont.

initialize (Integer x, Integer y, Integer width, Integer height, Integer geomFlags)
initialize (Integer x, Integer y, Integer width, Integer height)
initialize (Integer width, Integer height

Creates the receiver pane’s window and configures the window for display. The initialize method also fills in the receiver’s visualInfoPtr instance variable with a pointer the X visual info structure specified by the receiver, which is provided by the receiver’s instance variables.

With two arguments, the method initializes the receiver window with the width and height given as arguments.

With four arguments, the method initializes the receiver window with the window’s x and y origin and the width and height given as arguments.

With five arguments, the geom_flags argument provides placement hints for the window’s initial position. It has the format provided by the parseX11Geometry method in Application class. See parseX11Geometry.

When used, the x and y parameters can be given directly if the program sets the window position itself. If these arguments are zero, then the window manager or the user supplied window geometry determines the window placement.

hasExtension (String extensionName)

Returns a Boolean value of true if the system’s OpenGL library supports the GLX extension extensionName, false otherwise.

map (void)

Maps the GLXCanvasPane's window to the display, and internally creates a GLXContext for the window, and makes the GLXContext current.

This method fills in the receiver’s glxContextPtr instance method.

namedColorFT (String colorName, Float redOut, Float greenOut, Float blueOut)

Return the GLX compatible color values for colorName; i.e., the red, green, and blue values are Floats between 0.0 and 1.0. The colorName argument can be any of the colors supported by the X11 display server. Refer to showrgb(1) for a list of colors.

onAnimation (String animationHandlerName)

Installs the callback method that the program calls 24 times a second. The method needs to have the prototype:


GLXCanvasPane instanceMethod <methodName> (void);

onButtonPress (String buttonPressHandlerName)

Installs the callback method that handles ButtonPress events from the display. The callback method needs to have this prototype.


GLXCanvasPane instanceMethod <methodName> (Integer winX, Integer winY,
                                           Integer screenX, Integer screenY,
                                           Integer buttonState,
                                           Integer eventTime);

The parameters winX and winY give the position of the pointer relative to the window’s origin. The parameters screenX and screenY give the pointer’s position relative to the upper left-hand corner of the root window.

Note this does not generally mean that the program can receive events when a button is pressed outside of the program’s window. This depends on how the desktop GUI interprets button presses; with many desktop programs, the program doesn’t receive events when a button is clicked outside of the program’s window.

The buttonState parameter’s value records which buttons are pressed at the time of the event. Note that many systems interpret a multiple button click (a “chord”) as a unique button. For example, pressing the left and right buttons of a two-button mouse at the same time results in a buttonState that indicates button 2 is pressed, not that button 1 and button 3 are pressed simultaneously.

The time parameter is the time that the event occurred, so programs can interpret a series of ButtonPress events as multiple mouse clicks if necessary.

To install a buttonPress callback method, the program needs to include an expression like this one in its initialization code.


myGLXPane onButtonPress "myButtonPressHandler";

onExpose (String exposeHandlerName)

Installs the callback method to handle Expose events received from the display. The callback method should have the following prototype.


GLXCanvasPane instanceMethod <methodName> (Integer nEvents);

To install the callback method, the program’s initialization should contain an expression like this one.


myPane onExpose "myExposeHandler";

The parameter nEvents contains the number of Expose events that the window is waiting to receive. This allows programs to execute the handler’s statements once per group of Expose events; that is, when nEvents reaches 0.

This handler is important because it updates the window in coordination with other display events. If a callback method is not installed, then the run method calls the swapBuffers method.

onIdle (String callbackMethodName)

Installs a callback method that the program executes when it is not processing events from the display.

The callback method has the prototype:


GLXCanvasPane instanceMethod <idleHandler> (void);

To install the handler, the program’s initialization needs to contain an expression like this.


myPane onIdle "myIdleCallback";

onKeyPress (String callbackMethodName)

Configures the receiver’s keyPressHandler instance variable to refer to the application’s actual KeyPress handler method, which is called when the program’s window receives a KeyPress event from the display.

The actual callback method has the prototype:


GLXCanvasPane instanceMethod <methodName> (Integer xKeySym,
                                           Integer keyCode,
                                           Integer shiftState);

This example shows a simple KeyPress handler that closes the window and exits the program when the Escape key is pressed.


/* This definition comes from the machine's X11/keysymdef.h file. */
#define XK_Escape 0xff1b

GLXCanvasPane instanceMethod myKeyPressMethod (Integer xKeySym,
					       Integer keyCode,
					       Integer shiftState) {
  if (xKeySym == XK_Escape) {
    self deleteAndClose;
    exit (0);
  }
}


The first parameter is the X Window System symbol for the key, which is specific to the machine’s keyboard configuration. The complete set of X key symbols is located in the machine’s X11/keysymdef.h file.

The second parameter is the ASCII value of alphanumeric keys and punctuation keys. In the case of alphabetic characters, the value is the same whether the keypress is shifted or unshifted. That means that pressing A and a both result in the keyCode argument having the value 97.

The third parameter, shiftState, indicates whether a modifier key is currently being pressed. The parameter is the receiver’s shiftState instance variable. The variable’s description describes how to interpret its value.

Then, during the program’s initialization the program’s code should include an expression like the following.


myProgram onKeyPress "myKeyPressMethod";

There is a more detailed description of how to configure callback methods in section that discusses Method class. See CallbackSetup.

onPointerMotion (String callbackMethodName)

Installs the callback method that handles pointer motion events from the display. The callback method must have the prototype:


GLXCanvasPane instanceMethod <methodName> (Integer winX,
                                           Integer winY,
                                           Integer screenX,
                                           Integer screenY);

The program’s initialization should contain an expression like this one:


myPane onPointerMotion "myPointerMotionMethod";

onResize (String callbackMethodName)

Installs the callback method that handles resize notifications from the display. The callback method needs to have the prototype:


GLXCanvasPane instanceMethod <methodName> (Integer width,
                                           Integer height);

The program’s initialization code should contain an expression like this one.


myPane onResize "myResizeMethod";

onTimerTick (String callbackMethodName)

Installs the callback method to be executed when the classes’ interval timer reaches zero. The callback method needs to have the following prototype.


GLXCanvasPane instanceMethod <methodName> (void);

The interval in milliseconds between the callback method’s execution is set in the timerMSec instance variable,

pixelHeightFT (Integer pxHeight)

Set the pixel height of the selected font to the argument. The default height for rendering fonts with the Freetype libraries is 18 pixels.

refreshRate (void)

Returns a Float with the display’s refresh rate. If the machine’s OpenGL does not support reporting the refresh rate, returns -1.

run (void)

Runs the event loop that receives X events from the display server, and sends them to the callback methods that are configured for the application.

Without any callback methods defined, the run method handles only ‘Expose’ events (by calling swapBuffers), and ‘ClientMessage’ events, which check for the WM_DELETE_WINDOW Atom and if present, delete the pane’s window and GLX context, and exit the program.

swapBuffers (void)

Swaps the pane window’s offscreen rendering buffer with the window’s visible buffer.

syncSwap (Integer interval)

If interval > 0, sets the swap interval to 1/interval, which enables swap synchronization with the display’s vertical refresh rate if the machine’s OpenGL installation supports the GLX_MESA_swap_control extension.

An interval value of 0 disables swap synchronization.

Returns 0 on sucess, or -1 if the extension is not supported.

textWidth (String text)

Returns an Integer with the width of text in pixels in the currently selected X font. If no font is selected, the method returns ‘-1’.

textWidthFT (String text)

Returns a Float with the width of text in matrix coordinates for the currently selected Freetype font.

title (String title_string)

Set’s the window’s title. This method should be called as soon as possible after the program calls the initialize method.

useFTFont (String fontFileName)

Load a TrueType, FreeType or Type 1 font. Also initializes the font and GLEW libraries if needed.

The method uses the font’s file name as its argument. To use a system’s font aliasing and lookup, refer to See X11FreeTypeFont.

useXFont (String fontName)

Register a X font for use with drawing text in the receiver pane. The argument, fontname, is th X Logical Font Descriptor of a X font that is available on the system - refer to xlsfonts(1) or xfontsel(1) for more information.

This method should be called during OpenGL initialization (that is, after the GLXCanvasPane object has been created and the GLX context established).

xpmToTexture (Symbol xpmdata, Integer widthout, Integer heightout, Symbol texeldataout)
xpmToTexture (Symbol xpmdata, Integer alpha Integer widthout, Integer heightout, Symbol texeldataout)

Translates a XPM pixmap into an OpenGL texture. The argument xpm_data is the pixmap’s char *pixmap_name[] declaration. If no alpha argument is given, then ‘1.0’ is used to create an opaque texture.

Alpha values can range from 0 (completely transparent) - 0xffff (completely opaque), although in practice, the alpha channel’s effect might not be apparent, because OpenGL has its own set of functions that perform texture blending.

The method sets the arguments width_out, height_out, and texel_data_out with the height, width and data of the texture.

Mesa OpenGL textures, used with Linux systems, internally have the format GL_RGBA and the data type GL_UNSIGNED_INT_8_8_8_8, so you can create a 2D texture from a pixmap with statements like these.


Integer new xpmWidth;
Integer new xpmHeight;
Symbol new texData;

/*
 *  Note that the xpm_data argument should not normally need a
 *  translation from C.
 */
myGLUTApp xpmToTexture xpm_data, xpmWidth, xpmHeight, texData;
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, xpmWidth, xpmHeight, 0,
              GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, texData);

Apple OpenGL implementations use a different internal format, so a program would create the equivalent texture like this.


Integer new xpmWidth;
Integer new xpmHeight;
Symbol new texData;

myGLUTApp xpmToTexture xpm_data, xpmWidth, xpmHeight, texData;
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, xpmWidth, xpmHeight, 0,
              GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);

The xpmToTexture method does not do any setup of the OpenGL texture environment. For basic textures, OpenGL works better with textures that have a geometry that is an even multiple of 2; e.g., 128x128 or 256x256 pixels.

Individual applications can add parameters for interpolation, blending, mipmap creation, and material rendering based on the program’s requirements, though.

The Ctalk library only stores the data for one texture at a time, so if a program uses multiple textures, it should save the texture data to a separate Symbol, in orderq to avoid regenerating the texture each time it’s used. Many OpenGL implementations also provide API functions for texture caching.

For an example of how to draw with textures, refer to the glxtexture.ca program in the Ctalk distribution’s demos/glx subdirectory.

Sample GLXCanvasPane Application


#include <X11/Xlib.h>
#include <GL/glx.h>

#define DEFAULT_WIDTH 500
#define DEFAULT_HEIGHT 500

float face1[3][3] = {{0.0f, 2.0f, 0.0f},
		     {-2.0f, -2.0f, 2.0f},
		     {2.0f, -2.0f, 2.0f}};
float face2[3][3] = {{0.0f, 2.0f, 0.0f},
		     {2.0f, -2.0f, 2.0f},
		     {2.0f, -2.0f, -2.0f}};
float face3[3][3] = {{0.0f, 2.0f, 0.0f},
		     {2.0f, -2.0f, -2.0f},
		     {-2.0f, -2.0f, -2.0f}};
float face4[3][3] = {{0.0f, 2.0f, 0.0f},
		     {-2.0f, -2.0f, -2.0f},
		     {-2.0f, -2.0f, 2.0f}};

float base[4][3] = {{2.0f, -2.0f, 2.0f},
		    {2.0f, -2.0f, -2.0f},
		    {-2.0f, -2.0f, -2.0f},
		    {-2.0f, -2.0f, 2.0f}};

float angle = 20.0;

GLXCanvasPane instanceMethod draw (void) {
  glEnable (GL_NORMALIZE);
  glEnable(GL_DEPTH_TEST);
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glLineWidth (1.0f);

  glLoadIdentity ();
  glColor4f (1.0f, 1.0f, 1.0f, 1.0f);

  glRotatef (angle, 0.0f, 1.0f, 0.0f);
  glRotatef (10.0f, 0.0f, 0.0f, 1.0f);

  glBegin (GL_TRIANGLES);
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3fv (face1[0]);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3fv (face1[1]);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3fv (face1[2]);

  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3fv (face2[0]);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3fv (face2[1]);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3fv (face2[2]);
			
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3fv (face3[0]);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3fv (face3[1]);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3fv (face3[2]);
			
  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3fv (face4[0]);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3fv (face4[1]);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3fv (face4[2]);
  glEnd ();

  glBegin (GL_QUADS);

  glColor3f (1.0f, 0.0f, 0.0f);
  glVertex3fv (base[0]);
  glColor3f (0.0f, 1.0f, 0.0f);
  glVertex3fv (base[1]);
  glColor3f (0.0f, 0.0f, 1.0f);
  glVertex3fv (base[2]);
  glColor3f (1.0f, 0.0f, 1.0f);
  glVertex3fv (base[3]);

  glEnd ();

  glRotatef (20.0, 0.0f, 0.0f, 1.0f);
  glRotatef (angle, 0.0f, 1.0f, 0.0f);

  self swapBuffers;
}

GLXCanvasPane instanceMethod initGL (void) {
  glViewport (0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glLineWidth (1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glEnable (GL_LINE_SMOOTH);
  glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  if (DEFAULT_WIDTH <= DEFAULT_HEIGHT) {
    glOrtho (-5.0, 5.0,
	     -5.0 * ((float)DEFAULT_HEIGHT / (float)DEFAULT_WIDTH),
	     5.0 * ((float)DEFAULT_HEIGHT / (float)DEFAULT_WIDTH),
	     -5.0, 5.0);
  } else {
    glOrtho (-5.0, 5.0,
	     -5.0 * ((float)DEFAULT_WIDTH / (float)DEFAULT_HEIGHT),
	     5.0 * ((float)DEFAULT_WIDTH / (float)DEFAULT_HEIGHT),
	     -5.0, 5.0);
  }
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
}

GLXCanvasPane instanceMethod myTimerTickHandler (void) {
  angle += 1.0;
  self draw;
}

/* This definition comes from the machine's X11/keysymdef.h file. */
#define XK_Escape 0xff1b

GLXCanvasPane instanceMethod myKeyPressMethod (Integer xKeySym,
					       Integer keyCode,
					       Integer shiftState) {
  if (xKeySym == XK_Escape) {
    self deleteAndClose;
    exit (0);
  }
}

GLXCanvasPane instanceMethod myExposeMethod (Integer nEvents) {
  if (nEvents == 0)
    self draw;
}

GLXCanvasPane instanceMethod myResizeMethod (Integer width,
					     Integer height) {
  float ar;

  glViewport (0, 0, width, height);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  if (width <= height)
    ar = (float)height / (float)width;
  else
    ar = (float)width / (float)height;
  glOrtho (-5.0, 5.0, -5.0 * ar, 5.0 * ar, -5.0, 5.0);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
}

int main () {
  GLXCanvasPane new pane;

  pane initialize (1, 150, 500, 500);
  pane title "GLXCanvasPane Demonstration";
  pane map;
  pane raiseWindow;

  pane onKeyPress "myKeyPressMethod";
  pane onExpose "myExposeMethod";
  pane onTimerTick "myTimerTickHandler";
  pane onResize "myResizeMethod";

  pane initGL;
  
  pane run;

}


Next: , Previous: , Up: Classes   [Index]