Anhang

Typische OpenGL-Programmstruktur

Ein typisches Programm, das OpenGL verwendet, beginnt damit, ein Fenster im Frame Buffer zu öffnen, um darin zu zeichnen. Dann wird ein GL Kontext erzeugt, und mit diesem Fenster assoziiert. Sobald dies erfolgt ist, können in dem Programm OpenGL Befehle verwendet werden. Einige Befehle werden verwendet, um einfache Geometrische Objekte zu zeichnen (z.B. Punkte, Liniensegmente und Polygone). Andere Befehle beeinflussen wie diese Primitive gerendert werden. Dies beinhaltet die Beleuchtung, Färbung dieser Objekte, und wie sie von dem 2- oder 3-Dimensionalen Modelbereich auf den 2-Dimensionalen/flachen Bildschirm abgebildet werden. Es ist auch möglich einzelne Pixel aus dem Frame Buffer auszulesen bzw. in den Frame Buffer hineinzuschreiben.

Ein Programm in Pseudocode könnte folgendermaßen aussehen:

Main()

Fensterattribute festlegen (Größe, Position, Grafik Modi, Frame Buffer) und das Fenster erzeugen.

GL Status initialisieren (z.B. Ansichtspunkt, Färbung, Beleuchtung)

Display Liste initialisieren

Wiederhole

Ereignisse abfragen

Wenn Fenster Ereignis (Fenster wurde bewegt, freigelegt, in der Größe geändert, usw.) Dann

Falls erforderlich den viewport modifizieren

Neuzeichnen()

Ansonsten wenn Maus oder Tastatur Ereignis Dann

Entsprechend darauf reagieren, und ggf. GL Status ändern und Neuzeichnen()

Neuzeichnen()

Bildschirm löschen (Hintergrundfarbe)

Falls erforderlich GL Status ändern

Einige Grafiken rendern

Weitere GL Statuse ändern

Weitere Teile der Grafiken rendern

...

Frame Buffer tauschen (sofern mit doppeltem Frame Buffer gearbeitet wird.)

Reihenfolge der OpenGL Operationen

Die Reihenfolge der OpenGL Operationen in der Render Pipeline ist nicht fest vorgegeben. Die hier angegebene Reihenfolge soll nur zum Verständnis beitragen was mit den Daten passiert, bis das fertige Bild im Frame Buffer vorliegt. Die jeweilige OpenGL Implementation kann auch anders funktionieren, solange das Ergebnis dasselbe ist.

Alle Daten (geometrische oder Pixeldaten) können direkt (immediate mode) verarbeitet werden, oder in Display Listen gespeichert werden. Diese Display Listen können dann später verarbeitet werden. Dies ist dann nützlich, wenn die Daten öfters gebraucht werden, z.B. bei Animationen und wenn ein Objekt (z.B. ein Reifen) mehrmals im selben Bild vorkommt.

Beim Verarbeiten, wird zwischen Geometrischen- und Pixeldaten unterschieden. Pixeldaten werden zuerst in das richtige Format konvertiert, danach werden Pixel Operationen auf sie angewendet. Dazu gehört u.a. skalieren. Das Ergebnis wird entweder an den Rasterizer übergeben, oder in dem Texturspeicher abgelegt. Aus dem Texturspeicher können die Pixeldaten auf Geometrische Objekte gelegt werden, damit diese realistischer aussehen.

Geometrische Daten werden Ausgewertet/Konvertiert. Danach werden Primitiven erzeugt. Hier werden auch Koordinatenumrechnungen vorgenommen. Werden Texturen verwendet, werden hier zusätzlich noch die Texturkoordinaten berechnet. Auch die Beleuchtungsdaten werden hier berechnet. Anschließend werden die Daten dem Rasterizer übergeben. Dieser verwendet ggf. die Pixeldaten aus dem Texturspeicher.

Bibliotheksunterlagen

/*
** Nano Window Toolkit.
** Version 1.1
*/

/**********************************************************************/
/* Diese Funktionen sind neu in libtk Version 1.1 */
/**********************************************************************/

void tkInitDisplayModePolicy( GLenum type) 

Setzt die policy zu: TK_EXACT_MATCH, TK_MINIMUM_CRITERIA oder TK_USE_ID.

Die Standard policy TK_MINIMUM_CRITERIA erzeugt ein Fenster das die gleichen oder mehr Eigenschaften hat, als die des aktuell gewählten Anzeige Modus (siehe auch tkInitDisplayMode()). Dies war die Art und Weise, wie es bereits in libtk Version 1.0 funktioniert hat. Wenn TK_EXACT_MATCH gewählt wird, wird ein Fenster ausgewählt, das, sofern möglich, genau dem angegebenen anzeige Modus entspricht. (Wenn keine genaue Übereinstimmung erreicht werden kann, so liefert die Funktion das Ergebnis GL_FALSE.) Wenn TK_USE_ID gewählt wird, dann wird die Anzeige Modus i.d. verwendet, um das Fenster zu erzeugen.

GLenum tkGetDisplayModePolicy (void)

Liefert die aktuelle Anzeige Modus policy zurück.

GLenum tkInitDisplayModeID (GLint id)

Setzt die Anzeige Modus id

Die Anzeige Modus id wird beim Erzeugen eines Fensters verwendet, wenn die policy TK_USE_ID ist. (Für X und OS2 ist dies eine sichtbare id; unter Windows NT ist dies ein Pixelformat.) Die Anzeige Modus id ist maschinenabhängig.

GLint tkGetDisplayModeID (void)

Liefert die Anzeige Modus id des Haupt Fensters.

GLenum tkGetDisplayMode (void)

Liefert den Anzeige Modus id des Fensters.

Fenster Attribute, wie TK_RGB und TK_INDIRECT werden ver-odert und als ein Wert zurückgeliefert.

TkGetSystem() wurde erweitert, um die Rückgabewerte X screen und den Rendering Kontext zurückzuliefern. (Ausführliche Beschreibung siehe unten.)

/****************************************************************************/
/* Die folgenden Funktionen waren bereits Bestandteil von libtk Version 1.0 */
/****************************************************************************/

/*
** Fenster Funktionen
*/

void tkInitDisplayMode(GLenum type);

Fenster Typ vordefinieren.

GLenum type:

TK_RGB or TK_INDEX

TK_SINGLE or TK_DOUBLE

TK_DIRECT or TK_INDIRECT

TK_ACCUM

TK_ALPHA

TK_DEPTH

TK_OVERLAY

TK_UNDERLAY

TK_STENCIL

void tkInitPosition(int x, int y, int w, int h);

Voreinstellung der Fenstergröße und Position der oberen linken Ecke.

GLenum tkInitWindow(char *titleStr);

Erzeugt neues Fenster.

Benutze tkInitDisplayMode um Werte zu setzten, die bestimmen, ob die Funktionen mit RGB oder COLOR_INDEX arbeiten, und was für eine Buffer Struktur vom Fenster verwendet werden soll.

Dies wird durch verodern der entsprechenden Werte für die gewünschten Modi erreicht. Die Werte sind unter tkInitDisplayMode (siehe oben) aufgeführt. tkInitPosition wird verwendet, um die Größe und Position des Fensters zu definieren. Die Eigenschaften, die von diesen Funktionen gesetzt wurden, werden von tkInitWindow benutzt, um das Fenster zu erzeugen. Falls das Fenster mit den angegebenen Parametern nicht erzeugt werden kann, so wird eine entsprechende Meldung ausgegeben.

void tkCloseWindow(void);

Schließt Fenster.

void tkQuit(void);

Beendet Applikation.

tkCloseWindow gibt den Speicher frei, der von einigen tk Funktionen verwendet wird, ruft glFinish auf, setzt die Ereignis Funktionen auf Null, und entfernt das Fenster. tkQuit ruft die Funktion tkCloseWindow auf und beendet das Programm.

GLenum tkSetWindowLevel(GLenum level);

Setzt Zeichen Ebene des Fensters.

GLenum level:

TK_RGB or TK_INDEX

TK_OVERLAY

TK_UNDERLAY

Falls das Fenster mit einer overlay Ebene erzeugt wurde, wird das Rendern auf die entsprechende Ebene umgeleitet. TK_UNDERLAY wird momentan nicht verwendet.

void tkSwapBuffers(void);

Tauschen des Zeichen-/Ansicht- Buffers in einem doppelt gepufferten Fenster.

Wenn das Fenster doppel Pufferung unterstützt, wird der Inhalt des hinteren Puffers sichtbar, die Funktion glFlush() wird implizit aufgerufen. Der Inhalt des hinteren Puffers ist nach diesem Aufruf nicht definiert.

/*
** Ereignis Funktionen.
*/

Der Benutzer kann callback Funktionen für bestimmte Ereignisse zuweisen. Diese werden aufgerufen, wenn das Ereignis eintritt. Zu den Ereignissen zählen Expose (Teil des Fensters, das vorher verdeckt war, wird sichtbar), Reshape (Das Fenster wird in seiner Größe geändert), und Display (Der gesamte Fensterinhalt soll gezeichnet werden). Die tk Ereignis-Struktur ruft diese Funktionen auf. Manche dieser Ereignisse beziehen sich auf das Fenster, andere auf die Eingabe (Tastatur und Maus). Folgende Funktionen können verwendet werden, um die callback Funktionen zuzuweisen.

void tkExposeFunc(void (*Func)(int w, int h));

Setzt Fenster expose callback Funktion.

void (*Func)(int w, int h)

Callback Funktion erhält als Übergabeparameter die Fenstergröße und wird aufgerufen, wenn ein Teil des Fensters aufgedeckt wird.

void tkReshapeFunc(void (*Func)(int w, int h));

Setzt Fenster reshape callback Funktion.

void (*Func)(int w, int h)

Callback Funktion erhält als Übergabeparameter die Fenstergröße des Fensters, nachdem die Größe geändert wurde.

void tkDisplayFunc(void (*Func)(void));

Setzt Display callback Funktion.

Im Normalfall sollte diese Funktion das ganze Zeichnen erledigen. Es muß den gesamten Fensterinhalt zeichnen.

void tkKeyDownFunc(GLenum (*Func)(int key, GLenum states));

Setzt key event callback Funktion.

void (*Func)(int key, GLenum states)

Callback Funktion erhält als Übergabeparameter, welche Taste gedrückt wurde, und den Status der Umschalt- und Steuerungs- Tasten.

Callback Funktion gibt GL_TRUE zurück, wenn die Display callback Funktion aufgerufen werden sollte, bzw. GL_FALSE, wenn die Display callback Funktion nicht aufgerufen werden sollte.

int key:

TK_ESCAPE

TK_LEFT TK_UP TK_RIGHT TK_DOWN

TK_RETURN

TK_SPACE

TK_A through TK_Z

TK_a through TK_z

TK_0 through TK_9

GLenum states:

TK_SHIFT

TK_CONTROL

void tkMouseDownFunc(GLenum (*Func)(int x, int y, GLenum states));

Setzt mouse button down event callback Funktion. (Maus-Taste wird gedrückt)

void (*Func)(int x, int y, GLenum states)

Callback Funktion erhält als Übergabeparameter die x, y Position der Maus und den Status der Tasten zum Zeitpunkt, als das Maus Ereignis auftrat.

Callback Funktion liefert GL_TRUE zurück, wenn die Display callback Funktion aufgerufen werden soll, bzw. GL_FALSE, wenn die Display callback Funktion nicht aufgerufen werden soll.

GLenum states:

TK_LEFTBUTTON

TK_RIGHTBUTTON

TK_MIDDLEBUTTON

void tkMouseUpFunc(GLenum (*Func)(int x, int y, GLenum states));

Setzt mouse button up event callback Funktion. (Maus Taste wird losgelassen)

void (*Func)(int x, int y, GLenum states)

Callback Funktion erhält als Übergabeparameter die x, y Position der Maus und den Status der Tasten zum Zeitpunkt, als das Maus Ereignis auftrat.

Callback Funktion liefert GL_TRUE zurück, wenn die Display callback Funktion aufgerufen werden soll, bzw. GL_FALSE, wenn die Display callback Funktion nicht aufgerufen werden soll.

GLenum states:

TK_LEFTBUTTON

TK_RIGHTBUTTON

TK_MIDDLEBUTTON

void tkMouseMoveFunc(GLenum (*Func)(int x, int y, GLenum states));

Setzt mouse move event callback Funktion. (Ein Maus Ereignis tritt auf)

void (*Func)(int x, int y, GLenum states)

Callback Funktion erhält als Übergabeparameter die x, y Position der Maus und den Status der Tasten zum Zeitpunkt, als das Maus Ereignis auftrat.

Callback Funktion liefert GL_TRUE zurück, wenn die Display callback Funktion aufgerufen werden soll, bzw. GL_FALSE, wenn die Display callback Funktion nicht aufgerufen werden soll.

GLenum states:

TK_LEFTBUTTON

TK_RIGHTBUTTON

TK_MIDDLEBUTTON

void tkIdleFunc(void (*Func)(void));

Setzt idle event callback Funktion. (Kein Ereignis aufgetreten)

      void tkExec(void)

tk Ereignisbehandlungs Funktionen werden ausgeführt.

/*
** Get Funktionen.
*/

int tkGetColorMapSize(void);

liefert die Größe der color map.

void tkGetMouseLoc(int *x, int *y);

liefert die aktuelle x, y Position der Maus.

void tkGetSystem(GLenum type, void *ptr)

liefert entweder die X display, X window, X screen oder rendering context Werte, abhängig von dem Typ (Anmerkung: die X display, X window und X screen Werte werden nur von den Bibliotheken unterstützt, die unter X-Windows laufen)

/*
** Set Funktionen.
*/

Diese Funktionen setzen color maps für den Gebrauch des Fenster Systems.

void tkSetOneColor(int ci, float r, float g, float b);

Setzt color index zu den r, g, b Werten.

void tkSetFogRamp(int density, int size);

Setzt eine fog ramp in der color map. Beginnt mit dem Eintrag 0 und der Länge 2^size.

void tkSetGreyRamp(void);

Setzt die gesamte color map zu einer grau Stufen ramp.

void tkSetRGBMap(int size, float *rgb);

Setzt die color map des Hauptfensters. Die rgb Werte werden in folgender Form übergeben: r[size] gefolgt von g[size] gefolgt von b[size].

void tkSetOverlayMap(int, float *);

Setzt die color map der overlay Ebene. Die rgb Werte werden in folgender Form übergeben: r[size] gefolgt von g[size] gefolgt von b[size].

/*
** Cursor Funktionen.
*/

void tkNewCursor(GLint id, GLubyte *shape, GLubyte *mask, GLenum fgColor,
                 GLenum bgColor, GLint hotX, GLint hotY);

Definiere und initialisiere einen Cursor.

GLenum fgColor, bgColor:

TK_BLACK

TK_RED

TK_GREEN

TK_YELLOW

TK_BLUE

TK_MAGENTA

TK_CYAN

TK_WHITE

void tkSetCursor(GLint id);

Cursor wird aktiv.

/*
** Einfache Objekt Funktionen.
*/

void tkWireSphere(GLuint base, float radius);
void tkSolidSphere(GLuint base, float radius);
void tkWireCube(GLuint base, float size);
void tkSolidCube(GLuint base, float size);
void tkWireBox(GLuint base, float width, float height, float depth);
void tkSolidBox(GLuint base, float width, float height, float depth);
void tkWireTorus(GLuint base, float innerRadius, float outerRadius);
void tkSolidTorus(GLuint base, float innerRadius, float outerRadius);
void tkWireCylinder(GLuint base, float radius, float height);
void tkSolidCylinder(GLuint base, float radius, float height);
void tkWireCone(GLuint base, float b, float h);
void tkSolidCone(GLuint base, float b, float h);

Erzeugt diverse Display Listen Formen, beginnend bei der angegebenen base.

/*
** Hilfreiche Maskierungs Funktionen.
*/

#define TK_IS_RGB(x) (((x) & TK_INDEX) == 0)
#define TK_IS_INDEX(x) (((x) & TK_INDEX) != 0)
#define TK_IS_SINGLE(x) (((x) & TK_DOUBLE) == 0)
#define TK_IS_DOUBLE(x) (((x) & TK_DOUBLE) != 0)
#define TK_IS_DIRECT(x) (((x) & TK_INDIRECT) == 0)
#define TK_IS_INDIRECT(x) (((x) & TK_INDIRECT) != 0)
#define TK_HAS_ACCUM(x) (((x) & TK_ACCUM) != 0)
#define TK_HAS_ALPHA(x) (((x) & TK_ALPHA) != 0)
#define TK_HAS_DEPTH(x) (((x) & TK_DEPTH) != 0)
#define TK_HAS_OVERLAY(x) (((x) & TK_OVERLAY) != 0)
#define TK_HAS_UNDERLAY(x) (((x) & TK_UNDERLAY) != 0)
#define TK_HAS_STENCIL(x) (((x) & TK_STENCIL) != 0)

/*
** Hilfreiches Farbmakro.
*/

#define TK_SETCOLOR(windType, color) (TK_IS_RGB((windType)) ? \
glColor3fv(tkRGBMap[(color)]) : \
glIndexf((color)))

GLenum windType:

TK_RGB or TK_INDEX

GLenum color:

TK_BLACK

TK_RED

TK_GREEN

TK_YELLOW

TK_BLUE

TK_MAGENTA

TK_CYAN

TK_WHITE

Bekannte Fehler: Die X Implementierung setzt manche der X- Eigenschaften nicht. Es kann leicht zu Namenskonflikten kommen (Diese Bibliothek verwendet u.a. 'xDisplay', 'xScreen', and 'w', die sehr wahrscheinlich auch in anderen Bibliotheken eingesetzt werden).

Links

Man Pages

ManPages für OpenGL- Befehle werden durch Digital Equipment gepflegt und können unter http://www.digital.com/pub/doc/opengl/opengl_index_alpha.html gefunden werden.

Glossar

rasterazation

Prozeß der Konvertierung mathematischer Beschreibungen von Objekten und deren verknüpften Farbinformationen in Pixel auf dem Bildschirms.

rendering

Prozeß, mit welchem ein Computer Bilder aus Modellen (Objekten) erstellt.

geometric primitives, vertices

Modelle bzw. Objekte bestehen aus geometrischen Grundformen (geometric primitives), Punkten (points) Linien (lines), Vielecken (polygons) und sind durch ihre Scheitelpunkte (vertices) bestimmt.

rendered image

Das abschließend gerenderte Bild besteht aus Pixeln, die auf den Bildschirm gezeichnet werden; ein Pixel ist das kleinste sichtbare Element, das von der Grafik Hardware auf dem Bildschirm dargestellt werden kann.

bitplane

Eine Bitfläche (Bitplane) ist ein Speicherbereich, der für jedes Pixel auf dem Bildschirm genau ein Bit Information enthält.

framebuffer

Bitplanes selbst werden in einem Puffer (framebuffer) verwaltet, der alle Informationen enthält, die die grafische Anzeige benötigt. Er enthält auch die Farbe und Intensität aller Pixel des Bildschirms.

Quellcode

Hello_World.c

// OpenGL Tutorial
// Hello_World.c

/*************************************************************************
This program essentially opens a window, clears it, sets the drawing
color, draws the object, and flushes the drawing buffer. It then goes
into an infinite loop accepting events and calling the appropriate
functions.
*************************************************************************/

// gcc -o Hello_World Hello_World.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void expose(int width, int height) {
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

void draw(void) {
  // Set the drawing color
  glColor3f(1.0, 1.0, 1.0);
  // Specify which primitive type is to be drawn
  glBegin(GL_POLYGON);
  // Specify verticies in quad
  glVertex2f(-0.5, -0.5);
  glVertex2f(-0.5, 0.5);
  glVertex2f(0.5, 0.5);
  glVertex2f(0.5, -0.5);
  glEnd();
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void main(int argc, char **argv) {
  // Open a window, name it "Hello World"
  if (tkInitWindow("Hello World") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Assign expose() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(expose);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Events.c

// OpenGL Tutorial
// Events.c

/*************************************************************************
This example extends Hello_World.c to accept and handle events. The
user should try produce each of the following events: key press, mouse
movement, mouse button press, mouse button release, reshape window, and
expose window.
*************************************************************************/

// gcc -o Events Events.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void expose(int width, int height) {
  printf("Got an Expose Event");
  printf(":\t width = %d height = %d\n", width, height);
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {
  printf("Got a Reshape Event");
  printf(":\t width = %d height = %d\n", width, height);
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

GLenum key_down(int key, GLenum state) {
  printf("Got a Key Down Event");
  printf(":\t key = %d, state = %d\n", key, state);
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

GLenum mouse_down(int x, int y, GLenum state) {
  printf("Got a Mouse Down Event");
  printf(":\t x = %d, y = %d, button = ", x, y);
  switch (state) {
    case TK_LEFTBUTTON : printf("left\n");
      break;
    case TK_RIGHTBUTTON : printf("right\n");
      break;
    case TK_MIDDLEBUTTON : printf("middle\n");
      break;
    default : printf("none\n");
      break;
  }
}

GLenum mouse_up(int x, int y, GLenum state) {
  printf("Got a Mouse Up Event");
  printf(":\t x = %d, y = %d, button = ", x, y);
  switch (state) {
    case TK_LEFTBUTTON : printf("left\n");
      break;
    case TK_RIGHTBUTTON : printf("right\n");
      break;
    case TK_MIDDLEBUTTON : printf("middle\n");
      break;
    default : printf("none\n");
      break;
  }
}

GLenum mouse_move(int x, int y, GLenum state) {
  printf("Got a Mouse Move Event");
  printf(":\t x = %d, y = %d, button = ", x, y);
  switch (state) {
    case TK_LEFTBUTTON : printf("left\n");
      break;
    case TK_RIGHTBUTTON : printf("right\n");
      break;
    case TK_MIDDLEBUTTON : printf("middle\n");
      break;
    default : printf("none\n");
      break;
  }
}

void draw(void) {
  printf("Got a Display Event\n");
  // Set the drawing color
  glColor3f(1.0, 1.0, 1.0);
  // Specify which primitive type is to be drawn
  glBegin(GL_POLYGON);
  // Specify verticies in quad
  glVertex2f(-0.5, -0.5);
  glVertex2f(-0.5, 0.5);
  glVertex2f(0.5, 0.5);
  glVertex2f(0.5, -0.5);
  glEnd();
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void main(int argc, char **argv) {
  // Open a window and name it
  if (tkInitWindow("Events") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Assign expose() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(expose);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign mouse_down() to be the function called whenever
  // a mouse button is pressed
  tkMouseDownFunc(mouse_down);
  // Assign mouse_up() to be the function called whenever
  // a mouse button is released
  tkMouseUpFunc(mouse_up);
  // Assign mouse_move() to be the function called whenever
  // the mouse is moved
  tkMouseMoveFunc(mouse_move);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Assign idle() to be the function called whenever there 
  // are no events, NOT USED IN THIS EXAMPLE
  // tkIdleFunc(idle);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Primitives.c

// OpenGL Tutorial
// Primitives.c

/*************************************************************************
This example illustrates the different results of each of the primitive
types applied to the same set of verticies. Notice that the order in
which the verticies are declared is very important. Also notice that
some primitives, when given an incorrect number of verticies, will
ignore any extra verticies. For example, GL_TRIANGLES only draws the
triangle corresponding to verticies 1, 2, and 3. Verticies 4 and 5 are
ignored.
*************************************************************************/

// gcc -o Primitives Primitives.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void expose(int width, int height) {
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
  tkQuit();
}

void draw(void) {
  // Set the drawing color
  glColor3f(1.0, 1.0, 1.0);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate the object
  glTranslatef(-5.0, 5.0, 0.0);
  // Draw the verticies connected according to the GL_LINES primitive
  glBegin(GL_LINES);
  // Vertex 1
  glVertex2f(-1.0, 1.0);
  // Vertex 2
  glVertex2f(2.0, 2.0);
  // Vertex 3
  glVertex2f(0.0, 0.0);
  // Vertex 4
  glVertex2f(1.0, -1.0);
  // Vertex 5
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(0.0, 5.0, 0.0);
  glBegin(GL_LINE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(5.0, 5.0, 0.0);
  glBegin(GL_LINE_LOOP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(-5.0, 0.0, 0.0);
  glBegin(GL_POLYGON);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(0.0, 0.0, 0.0);
  glBegin(GL_QUADS);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(5.0, 0.0, 0.0);
  glBegin(GL_QUAD_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(-5.0, -5.0, 0.0);
  glBegin(GL_TRIANGLES);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  gl12f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(0.0, -5.0, 0.0);
  glBegin(GL_TRIANGLE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(5.0, -5.0, 0.0);
  glBegin(GL_TRIANGLE_FAN);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Open a window, name it "Primitives"
  if (tkInitWindow("Primitives") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Assign expose() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(expose);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Points_Lines.c

// OpenGL Tutorial
// Points_Lines.c

/*************************************************************************
This example illustrates the commands covered in the tutorial section
Changing the State.
*************************************************************************/

// gcc -o Points_Lines Points_Lines.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void expose(int width, int height) {
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-6.0, 6.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
  // Clear the window
  glClear(GL_COLOR_BUFFER_BIT);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate the object
  glTranslatef(-2.5, 5.0, 0.0);
  // Set the color
  glColor3f(1.0, 1.0, 0.0);
  // Draw aliased points
  glDisable(GL_POINT_SMOOTH);
  // Set the point size
  glPointSize(10.0);
  glBegin(GL_POINTS);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(2.5, 5.0, 0.0);
  glColor3f(1.0, 0.75, 0.0);
  // Draw filtered points
  glEnable(GL_POINT_SMOOTH);
  glBegin(GL_POINTS);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(-2.5, 0.0, 0.0);
  glColor3f(1.0, 1.0, 0.0);
  // Draw aliased lines
  glDisable(GL_LINE_SMOOTH);
  // Disable line stippling
  glDisable(GL_LINE_STIPPLE);
  // Set the line width
  glLineWidth(10.0);
  glBegin(GL_LINE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(2.5, 0.0, 0.0);
  glColor3f(1.0, 0.75, 0.0);
  // Draw filtered lines
  glEnable(GL_LINE_SMOOTH);
  glBegin(GL_LINE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(-2.5, -5.0, 0.0);
  glColor3f(0.0, 1.0, 0.0);
  // Set the line width
  glLineWidth(1.0);
  // Enable line stippling
  glEnable(GL_LINE_STIPPLE);
  // Set the stippling pattern
  glLineStipple(3, 0xAAAA);
  glBegin(GL_LINE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  glLoadIdentity();
  glTranslatef(2.5, -5.0, 0.0);
  // Set the stippling pattern
  glLineStipple(2, 0x0C0F);
  glBegin(GL_LINE_STRIP);
  glVertex2f(-1.0, 1.0);
  glVertex2f(2.0, 2.0);
  glVertex2f(0.0, 0.0);
  glVertex2f(1.0, -1.0);
  glVertex2f(-2.0, -2.0);
  glEnd();
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 300, 400);
  // Open a window, name it "Points_Lines"
  if (tkInitWindow("Points_Lines") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shading model
  glShadeModel(GL_FLAT);
  // Assign expose() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(expose);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Polygons.c

// OpenGL Tutorial
// Polygons.c

/*************************************************************************
This program illustrates the use of the depth buffer and depth testing.
*************************************************************************/

// gcc -o Polygons Polygons.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Clear the RGB buffer and the depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate and rotate the object
  glTranslatef(-2.5, 0.0, 0.0);
  glRotatef(-30, 1.0, 0.0, 0.0);
  glRotatef(30, 0.0, 1.0, 0.0);
  glRotatef(30, 0.0, 0.0, 1.0);
  glColor3f(1.0, 0.0, 1.0);
  // Draw the sides of the three-sided pyramid
  glBegin(GL_TRIANGLE_FAN);
  glVertex3d(0, 4, 0);
  glVertex3d(0, -4, -4);
  glVertex3d(-4, -4, 4);
  glVertex3d(4, -4, 4);
  glVertex3d(0, -4, -4);
  glEnd();
  glColor3f(0.0, 1.0, 1.0);
  // Draw the base of the pyramid
  glBegin(GL_TRIANGLES);
  glVertex3d(0, -4, -4);
  glVertex3d(-4, -4, 4);
  glVertex3d(4, -4, 4);
  glEnd();
  glLoadIdentity();
  glTranslatef(2.5, 0.0, 0.0);
  glRotatef(45, 1.0, 0.0, 0.0);
  glRotatef(45, 0.0, 1.0, 0.0);
  glRotatef(45, 0.0, 0.0, 1.0);
  glColor3f(0.0, 1.0, 0.0);
  // Draw the sides of the cube
  glBegin(GL_QUAD_STRIP);
  glVertex3d(3, 3, -3);
  glVertex3d(3, -3, -3);
  glVertex3d(-3, 3, -3);
  glVertex3d(-3, -3, -3);
  glVertex3d(-3, 3, 3);
  glVertex3d(-3, -3, 3);
  glVertex3d(3, 3, 3);
  glVertex3d(3, -3, 3);
  glVertex3d(3, 3, -3);
  glVertex3d(3, -3, -3);
  glEnd();
  glColor3f(0.0, 0.0, 1.0);
  // Draw the top and bottom of the cube
  glBegin(GL_QUADS);
  glVertex3d(-3, -3, -3);
  glVertex3d(3, -3, -3);
  glVertex3d(3, -3, 3);
  glVertex3d(-3, -3, 3);
  glVertex3d(-3, 3, -3);
  glVertex3d(3, 3, -3);
  glVertex3d(3, 3, 3);
  glVertex3d(-3, 3, 3);
  glEnd();
 
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Initialize the RGB and Depth buffers
  tkInitDisplayMode(TK_RGB | TK_DEPTH);
  // Open a window, name it "Polygons"
  if (tkInitWindow("Polygons") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shading model
  glShadeModel(GL_FLAT);
  // Set the polygon mode to fill
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  // Enable depth testing for hidden line removal
  glEnable(GL_DEPTH_TEST);
  // Assign reshape() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(reshape);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Polygons_List.c

// OpenGL Tutorial
// Polygons_List.c

/*************************************************************************
This example is a modification Polygons.c to use display lists.
*************************************************************************/

// gcc -o Polygons_List Polygons_List.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

#define PYRAMID 1
#define CUBE 2

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Clear the RGB buffer and the depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate and rotate the object
  glTranslatef(-2.5, 0.0, 0.0);
  glRotatef(-30, 1.0, 0.0, 0.0);
  glRotatef(30, 0.0, 1.0, 0.0);
  glRotatef(30, 0.0, 0.0, 1.0);
  // Draw pyramid
  glCallList(PYRAMID);
  glLoadIdentity();
  glTranslatef(2.5, 0.0, 0.0);
  glRotatef(45, 1.0, 0.0, 0.0);
  glRotatef(45, 0.0, 1.0, 0.0);
  glRotatef(45, 0.0, 0.0, 1.0);
  // Draw cube
  glCallList(CUBE);
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void make_pyramid() {
  glNewList(PYRAMID, GL_COMPILE);
  glColor3f(1.0, 0.0, 1.0);
  // Draw the sides of the three-sided pyramid
  glBegin(GL_TRIANGLE_FAN);
  glVertex3d(0, 4, 0);
  glVertex3d(0, -4, -4);
  glVertex3d(-4, -4, 4);
  glVertex3d(4, -4, 4);
  glVertex3d(0, -4, -4);
  glEnd();
  glColor3f(0.0, 1.0, 1.0);
  // Draw the base of the pyramid
  glBegin(GL_TRIANGLES);
  glVertex3d(0, -4, -4);
  glVertex3d(-4, -4, 4);
  glVertex3d(4, -4, 4);
  glEnd();
  glEndList();
}
 
void make_cube() {
  glNewList(CUBE, GL_COMPILE);
  glColor3f(0.0, 1.0, 0.0);
  // Draw the sides of the cube
  glBegin(GL_QUAD_STRIP);
  glVertex3d(3, 3, -3);
  glVertex3d(3, -3, -3);
  glVertex3d(-3, 3, -3);
  glVertex3d(-3, -3, -3);
  glVertex3d(-3, 3, 3);
  glVertex3d(-3, -3, 3);
  glVertex3d(3, 3, 3);
  glVertex3d(3, -3, 3);
  glVertex3d(3, 3, -3);
  glVertex3d(3, -3, -3);
  glEnd();
  glColor3f(0.0, 0.0, 1.0);
  // Draw the top and bottom of the cube
  glBegin(GL_QUADS);
  glVertex3d(-3, -3, -3);
  glVertex3d(3, -3, -3);
  glVertex3d(3, -3, 3);
  glVertex3d(-3, -3, 3);
  glVertex3d(-3, 3, -3);
  glVertex3d(3, 3, -3);
  glVertex3d(3, 3, 3);
  glVertex3d(-3, 3, 3);
  glEnd();
  glEndList();
}

void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Initialize the RGB and Depth buffers
  tkInitDisplayMode(TK_RGB | TK_DEPTH);
  // Open a window, name it "Polygons_List"
  if (tkInitWindow("Polygons_List") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shading model
  glShadeModel(GL_FLAT);
  // Set the polygon mode to fill
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  // Enable depth testing for hidden line removal
  glEnable(GL_DEPTH_TEST);
  // Create the display lists
  make_pyramid();
  make_cube();
  // Assign reshape() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(reshape);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Circle_List.c

// OpenGL Tutorial
// Circle_List.c

/*************************************************************************
This example illustrates the use of display lists.
*************************************************************************/

// gcc -o Circle_List Circle_List.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

#define My_Circle 1
#define PI 3.1415926535898

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Clear the the RGB buffer and the Depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate the object
  glTranslatef(-3.5, 3.5, 0.0);
  glScalef(2.0, 2.0, 1.0);
  glColor3f(1.0, 0.0, 1.0);
  // Draw the predefined circle
  glCallList(My_Circle);
  glLoadIdentity();
  glTranslatef(3.5, 3.5, 0.0);
  glRotatef(45, 1.0, 0.0, 0.0);
  glColor3f(0.0, 0.0, 1.0);
  // Draw the predefined circle
  glCallList(My_Circle);
  glLoadIdentity();
  glTranslatef(-3.5, -3.5, 0.0);
  glRotatef(45, 1.0, 0.0, 0.0);
  glRotatef(45, 0.0, 1.0, 0.0);
  glRotatef(45, 0.0, 0.0, 1.0);
  glScalef(2.0, 1.0, 1.0);
  glColor3f(0.0, 1.0, 0.0);
  // Draw the predefined circle
  glCallList(My_Circle);
  glLoadIdentity();
  glTranslatef(3.5, -3.5, 0.0);
  glScalef(1.0, 4.0, 1.0);
  glColor3f(0.0, 1.0, 1.0);
  // Draw the predefined circle
  glCallList(My_Circle);
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}
 
void make_circle() {
  GLuint i;
  GLfloat cosine, sine;
  // Create a display list for a circle
  glNewList(My_Circle, GL_COMPILE);
  glBegin(GL_POLYGON);
  // Generate the points of the circle
  for(i = 0; i < 100; i++) {
    cosine = cos(i * 2 * PI / 100.0);
    sine = sin(i * 2 * PI/100.0);
    glVertex2f(cosine, sine);
  }
  glEnd();
  // End definition of circle
  glEndList();
}
 
void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Initialize the RGB and Depth buffers
  tkInitDisplayMode(TK_RGB | TK_DEPTH);
  // Open a window, name it "Circle_List"
  if (tkInitWindow("Circle_List") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shade model
  glShadeModel(GL_FLAT);
  // Set the polygon mode to fill
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  // Enable depth testing for hidden line removal
  glEnable(GL_DEPTH_TEST);
  // Call procedure to create the display list for the circle
  make_circle();
  // Assign reshape() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(reshape);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Swing.c

// OpenGL Tutorial
// Swing.c

/*************************************************************************
This program demonstrates animation.
*************************************************************************/

// gcc -o Swing Swing.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

#define SWING 1
#define BAR 2

GLfloat angle; // angle of swing
int direction; // direction of swing

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-50.0, 50.0, -50.0, 50.0, -150.0, 150.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Clear the RGB buffer and the depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Rotate the bar and swing
  glRotatef(60.0, 0.0, 1.0, 0.0);
  // Draw the bar
  glCallList(BAR);
  // Translate and rotate the swing to make it `swing'
  glTranslatef(0.0, 30.0, 0.0);
  glRotatef(angle, 1.0, 0.0, 0.0);
  glTranslatef(0.0, -30.0, 0.0);
  // Draw the swing
  glCallList(SWING);
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
  // Swap the buffers
  tkSwapBuffers();
  // Make the it swing back or forth depending upon direction
  if (direction == 1)
    angle++;
  else
    angle--;
  // Change the direction if 40 or -40 is reached
  if (angle == -40.0) {
    direction = 1;
  }
  if (angle == 40.0) {
    direction = 0;
  }
}

void make_bar() {
  glNewList(BAR, GL_COMPILE);
  // Draw the pole
  glBegin(GL_QUADS);
  glColor3f(1.0, 1.0, 0.0);
  // Bottom
  glVertex3d(-50, 30, -1);
  glVertex3d(50, 30, -1);
  glVertex3d(50, 30, 1);
  glVertex3d(-50, 30, 1);
  // Top
  glVertex3d(-50, 33, -1);
  glVertex3d(50, 33, -1);
  glVertex3d(50, 33, 1);
  glVertex3d(-50, 33, 1);
  glColor3f(1.0, 0.65, 0.0);
  // Front
  glVertex3d(-50, 33, 1);
  glVertex3d(-50, 30, 1);
  glVertex3d(50, 30, 1);
  glVertex3d(50, 33, 1);
  // Back
  glVertex3d(50, 33, -1);
  glVertex3d(50, 30, -1);
  glVertex3d(-50, 30, -1);
  glVertex3d(-50, 33, -1);
  glColor3f(1.0, 0.0, 0.0);
  // Left
  glVertex3d(-50, 33, -1);
  glVertex3d(-50, 30, -1);
  glVertex3d(-50, 30, 1);
  glVertex3d(-50, 33, 1);
  // Right
  glVertex3d(50, 33, 1);
  glVertex3d(50, 30, 1);
  glVertex3d(50, 30, -1);
  glVertex3d(50, 33, -1);
  glEnd();
  glEndList();
}

void make_swing() {
  glNewList(SWING, GL_COMPILE);
  glColor3f(1.0, 0.0, 1.0);
  glLineWidth(5.0);
  // Draw the ropes
  glBegin(GL_LINES);
  glVertex3d(-20, 30, 0);
  glVertex3d(-20, -30, 0);
  glVertex3d(20, 30, 0);
  glVertex3d(20, -30, 0);
  glEnd();
  glColor3f(0.0, 1.0, 0.0);
  // Draw the sides of the seat
  glBegin(GL_QUAD_STRIP);
  glVertex3d(20, -30, -10);
  glVertex3d(20, -33, -10);
  glVertex3d(-20, -30, -10);
  glVertex3d(-20, -33, -10);
  glVertex3d(-20, -30, 10);
  glVertex3d(-20, -33, 10);
  glVertex3d(20, -30, 10);
  glVertex3d(20, -33, 10);
  glVertex3d(20, -30, -10);
  glVertex3d(20, -33, -10);
  glEnd();
  glColor3f(0.0, 0.0, 1.0);
  // Draw the top and bottom of the seat
  glBegin(GL_QUADS);
  glVertex3d(-20, -33, -10);
  glVertex3d(20, -33, -10);
  glVertex3d(20, -33, 10);
  glVertex3d(-20, -33, 10);
  glVertex3d(-20, -30, -10);
  glVertex3d(20, -30, -10);
  glVertex3d(20, -30, 10);
  glVertex3d(-20, -30, 10);
  glEnd();
  glEndList();
}

void main(int argc, char **argv) {
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Initialize the RGB and Depth buffers
  tkInitDisplayMode(TK_RGB | TK_DEPTH | TK_DOUBLE);
  // Open a window, name it "Swing"
  if (tkInitWindow("Swing") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shading model
  glShadeModel(GL_FLAT);
  // Set the polygon mode to fill
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  // Enable depth testing for hidden line removal
  glEnable(GL_DEPTH_TEST);
  // Create the display lists
  make_bar();
  make_swing();
  angle = -39.0;
  direction = 1;
  // Assign reshape() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(reshape);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Assign idle() to be the function called whenever there 
  // are no events
  tkIdleFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}

Light.c

// OpenGL Tutorial
// Light.c

/*************************************************************************
This example is a modification Polygons_List.c to use lighting. The
three sided sphere was changed to a four-sided sphere to make
calculating the normal vectors easier.
Notice in the source code the order in which normals are defined for
GL_QUAD_STRIP. In the GL_QUAD_STRIP section, Normal A applies to
vertices 1, 2, 3, and 4; Normal B applies to vertices 3, 4, 5, and 6;
Normal C applies to vertices 5, 6, 7, and 8; and Normal D applies to
vertices 7, 8, 9, and 10. Due to the way that OpenGL renders objects,
the correct normal value must be set before the last vertex in the
current object is specified so that the correct normal value is
assigned to that object.
*************************************************************************/

// gcc -o Light Light.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

#define SPHERE 1
#define CUBE 2

void reshape(int width, int height) {
  // Set the new viewport size
  glViewport(0, 0, (GLint)width, (GLint)height);
  // Choose the projection matrix to be the matrix 
  // manipulated by the following calls
  glMatrixMode(GL_PROJECTION);
  // Set the projection matrix to be the identity matrix
  glLoadIdentity();
  // Define the dimensions of the Orthographic Viewing Volume
  glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
  // Choose the modelview matrix to be the matrix
  // manipulated by further calls
  glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
    tkQuit();
}

void draw(void) {
  // Clear the RGB buffer and the depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set the modelview matrix to be the identity matrix
  glLoadIdentity();
  // Translate and rotate the object
  glTranslatef(-2.5, 0.0, 0.0);
  // Draw sphere
  glCallList(SPHERE);
  glLoadIdentity();
  glTranslatef(2.5, 0.0, 0.0);
  glRotatef(45, 1.0, 0.0, 0.0);
  glRotatef(45, 0.0, 1.0, 0.0);
  glRotatef(45, 0.0, 0.0, 1.0);
  // Draw cube
  glCallList(CUBE);
  // Flush the buffer to force drawing of all objects thus far
  glFlush();
}

void make_sphere() {
  GLint slices, stacks;
  GLUquadricObj *quadObj;
  quadObj = gluNewQuadric();
  slices = 16;
  stacks = 10;
  glNewList(SPHERE, GL_COMPILE);
  glColor3f(1.0, 0.0, 1.0);
  gluSphere(quadObj, 4.0, slices, stacks);
  glEndList();
}
 
void make_cube() {
  glNewList(CUBE, GL_COMPILE);
  glColor3f(0.0, 1.0, 0.0);
  // Draw the sides of the cube
  glBegin(GL_QUAD_STRIP);
  // Normal A
  glNormal3d(0.0, 0.0, -1.0);
  // Vertex 1
  glVertex3d(3, 3, -3);
  // Vertex 2
  glVertex3d(3, -3, -3);
  // Vertex 3
  glVertex3d(-3, 3, -3);
  // Vertex 4
  glVertex3d(-3, -3, -3);
  // Normal B
  glNormal3d(-1.0, 0.0, 0.0);
  // Vertex 5
  glVertex3d(-3, 3, 3);
  // Vertex 6
  glVertex3d(-3, -3, 3);
  // Normal C
  glNormal3d(0.0, 0.0, 1.0);
  // Vertex 7
  glVertex3d(3, 3, 3);
  // Vertex 8
  glVertex3d(3, -3, 3);
  // Normal D
  glNormal3d(1.0, 0.0, 0.0);
  // Vertex 9
  glVertex3d(3, 3, -3);
  // Vertex 10
  glVertex3d(3, -3, -3);
  glEnd();
  glColor3f(0.0, 0.0, 1.0);
  // Draw the top and bottom of the cube
  glBegin(GL_QUADS);
  glNormal3d(0.0, 1.0, 0.0);
  glVertex3d(-3, -3, -3);
  glVertex3d(3, -3, -3);
  glVertex3d(3, -3, 3);
  glVertex3d(-3, -3, 3);
  glNormal3d(0.0, 1.0, 0.0);
  glVertex3d(-3, 3, -3);
  glVertex3d(3, 3, -3);
  glVertex3d(3, 3, 3);
  glVertex3d(-3, 3, 3);
  glEnd();
  glEndList();
}

void main(int argc, char **argv) {
  GLfloat specular [] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat shininess [] = { 100.0 };
  GLfloat position [] = { 1.0, 1.0, 1.0, 0.0 };
  // Set top left corner of window to be at location (0, 0)
  // Set the window size to be 500x500 pixels
  tkInitPosition(0, 0, 500, 500);
  // Initialize the RGB and Depth buffers
  tkInitDisplayMode(TK_RGB | TK_DEPTH);
  // Open a window, name it "Light"
  if (tkInitWindow("Light") == GL_FALSE) {
    tkQuit();
  }
  // Set the clear color to black
  glClearColor(0.0, 0.0, 0.0, 0.0);
  // Set the shading model
  glShadeModel(GL_SMOOTH);
  // Set the polygon mode to fill
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  // Enable depth testing for hidden line removal
  glEnable(GL_DEPTH_TEST);
  // Define material properties of specular color and degree of 
  // shininess. Since this is only done once in this particular 
  // example, it applies to all objects. Material properties can 
  // be set for individual objects, individual faces of the objects,
  // individual vertices of the faces, etc... 
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  // Set the GL_AMBIENT_AND_DIFFUSE color state variable to be the
  // one referred to by all following calls to glColor
  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  glEnable(GL_COLOR_MATERIAL);
  // Create a Directional Light Source
  glLightfv(GL_LIGHT0, GL_POSITION, position);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  // Create the display lists
  make_sphere();
  make_cube();
  // Assign reshape() to be the function called whenever
  // an expose event occurs
  tkExposeFunc(reshape);
  // Assign reshape() to be the function called whenever 
  // a reshape event occurs
  tkReshapeFunc(reshape);
  // Assign key_down() to be the function called whenever
  // a key is pressed
  tkKeyDownFunc(key_down);
  // Assign draw() to be the function called whenever a display
  // event occurs, generally after a resize or expose event
  tkDisplayFunc(draw);
  // Pass program control to tk's event handling code
  // In other words, loop forever
  tkExec();
}