Next: X11PaneDispatcher, Previous: X11Pane, Up: Classes [Index]
GLXCanvasPane ClassThe 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.
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;
}
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
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.
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.
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.
animationHandlerDefines the callback method that is called 24 times a second to perform animation.
buttonPressHandlerA Method object that defines the callback method that is executed
when a mouse button is pressed.
buttonStateAn 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");
}
colormapAn Integer that contains the X resource ID of the default
colormap of the current display and screen.
displayPtrA 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.
exposeHandlerDefines 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.
glxContextPtrA 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.
idleHandlerA Method that contains the callback that the program
executes when not processing events from the display.
keyPressHandlerA 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.
pointerMotionHandlerA Method that is called whenever the window receives a
MotionNotify event.
resizeHandlerA 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.
shiftStateAn 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");
timerMSecAn Integer that defines the time in milliseconds between
onTimerTick handler calls. The default is 1 millisecond.
timerTickHandlerA Method that defines the callback that is executed when the
classes’ interval timer reaches 0.
visualAuxBuffersAn Integer that, in combination with visualSetAuxBuffers,
defines the minimum number of auxiliary buffers that the selected visual
must have.
visualBufferSizeAn Integer that defines the desired color index buffer size. The
instance variable visualSetBufferSize must also be set to true.
visualDepthSizeAn 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.
visualDoubleBufferA Boolean that selects a double-buffered GLX visual if true,
or a single-buffered visual if false.
visualInfoPtrA 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.
visualRedSizevisualGreenSizevisualBlueSizevisualAlphaSizeInteger 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.
visualRedAccumSizevisualGreenAccumSizevisualBlueAccumSizevisualAlphaAccumSizeInteger 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.
visualRGBAA 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.
visualStencilPlanesAn 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.
visualStereoA Boolean value that selects a stereo visual if true.
xLineHeightAn Integer that contains the line height in pixels of a font
that has been selected by the useXFont method. This variable is
read only.
xMaxCharWidthAn 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.
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 heightCreates 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.
#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: X11PaneDispatcher, Previous: X11Pane, Up: Classes [Index]