Department of Engineering

IT Services

Using GLUT

GLUT is a facility to make OpenGL graphics easier to use. Here's a short example followed by an explanation of selected commands. The See Also section leads to full documentation.

Example 1

/* Copyright (c) Mark J. Kilgard, 1996. */

/* This program is freely distributable without licensing fees 
   and is provided without guarantee or warrantee expressed or 
   implied. This program is -not- in the public domain. */

#include <glut.h>

void reshape(int w, int h)
{
  /* This short bit of code sets up the coordinate
     system to correspond to actual window coordinates.  This code
     wouldn't be required if you chose a (more typical in 3D) abstract
     coordinate system. */

  glViewport(0, 0, w, h);       /* Establish viewing area to cover entire window. */
  glMatrixMode(GL_PROJECTION);  /* Start modifying the projection matrix. */
  glLoadIdentity();             /* Reset project matrix. */
  glOrtho(0, w, 0, h, -1, 1);   /* Map abstract coords directly to window coords. */
  glScalef(1, -1, 1);           /* Invert Y axis so increasing Y goes down. */
  glTranslatef(0, -h, 0);       /* Shift origin up to upper-left corner. */
}

void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLES);
    glColor3f(0.0, 0.0, 1.0);  /* blue */
    glVertex2i(0, 0);
    glColor3f(0.0, 1.0, 0.0);  /* green */
    glVertex2i(200, 200);
    glColor3f(1.0, 0.0, 0.0);  /* red */
    glVertex2i(20, 200);
  glEnd();
  glFlush();  /* Single buffered, so needs a flush. */
}

int main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB);
  if (! glutGet(GLUT_DISPLAY_MODE_POSSIBLE))
     glutInitDisplayMode(GLUT_INDEX);
  glutCreateWindow("single triangle");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutMainLoop();
  return 0;           
}

If you call this file simple.cc then it can be compiled on CUED's machines using g++ -I/usr/include/GL -o simple simple.cc -lglut -lGLU -lGL

Comments about example 1

The compile line is long, but on Unix you can use Makefiles or Shell scripts to save on typing.

The source code displays a triangle (a colourful one on sufficiently good hardware). It's about as simple as graphics code gets, but it's still far from trivial.

The main function

In main the system's initialised, a window is created, then functions are defined to specify what to display and how to respond to window resizing. After that the program goes into a loop, responding to events until the program's killed. Such a structure is typical for modern graphics programs.

  • glutInitDisplayMode - this takes a single argument which is made up of various integers OR'd together. It's important to get these options right. The glutInitDisplayMode reference page has full details. Amongst the options are
    • GLUT_INDEX - There's more than one way to specify colours on computers. Some systems offer a choice of ways. This option requests a "color index mode" window. The default is GLUT_RGBA ("RGBA mode")
    • GLUT_DOUBLE - Request double-buffering (a way to reduce flicker which is provided on some screens). GLUT_SINGLE is the default.

    If you request an option that the hardware can't support, the program won't run. On the Teaching System, older terminals need GLUT_SINGLE and GLUT_INDEX, the twn terminals in the DPO support GLUT_RGBA (and in consequence the colours work better) and the EIE terminals support GLUT_DOUBLE.

    If you want your program to run as well as it can on the available hardware, the int glutGet(GLUT_DISPLAY_MODE_POSSIBLE) is useful. It returns 1 if the current display mode is possible. So

      glutInitDisplayMode(GLUT_RGB);
      if (! glutGet(GLUT_DISPLAY_MODE_POSSIBLE))
         glutInitDisplayMode(GLUT_INDEX);
    
    will use the best colour display mode that the terminal can support.

The display function

This is called whenever the window needs to be redrawn

  • glClear - "clears" the window. Details are on the glClear() manual page.
  • glBegin - This marks the start of some points that are going to form an object or set of objects. Possible arguments include GL_POLYGON, GL_LINES, GL_POINTS, etc. Details are on the glBegin() manual page. glEnd() marks the end of the list.
  • glColor3f - There are various color-setting commands. This one takes 3 floats (hence 3f). Details are on the glcolor() manual page
  • glVertex2i - There are various vertex-setting commands. This one takes 2 integers (hence 2i). Details are on the glvertex() manual page

The reshape function

This is called whenever the window is moved or reshaped.

  • void glMatrixMode(GLenum mode) - mode can be GL_MODELVIEW (the initial value), GL_PROJECTION, or GL_TEXTURE.
  • void glLoadIdentity(void) - replaces the current matrix with the identity matrix
  • void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) - When the mode is GL_PROJECTION, (left, bottom, zNear) and (right, top, zNear) specifies the points on the near clipping plane that are mapped to the lower left and upper right corners of the window, respectively, assuming that the eye is located at (0, 0, 0).
  • void glScalef(GLfloat x,GLfloat y,GLfloat z) - produces a nonuniform scaling along the x, y, and z axes.
  • void glTranslatef(GLfloat x, GLfloat y, GLfloat z) - produces a translation by (x, y, z ).

Other Commands

This is just a small selection of available commands. More can be seen in the examples and documentation of the See Also section

Windows

  • glutInitWindowSize(int width, int height) - The window size will be 300x300 pixels unless you choose otherwise

Text

  • void glutBitmapCharacter(void *font, int character); - display a character. Options for font are GLUT_BITMAP_8_BY_13 , GLUT_BITMAP_9_BY_15 , GLUT_BITMAP_TIMES_ROMAN_10 , GLUT_BITMAP_TIMES_ROMAN_24 , GLUT_BITMAP_HELVETICA_10 , GLUT_BITMAP_HELVETICA_12 , GLUT_BITMAP_HELVETICA_18,
  • void glutStrokeCharacter(void *font, int character); - display a character. 'stroke' characters (unlike bitmap characters) scale well but may be slower. Options for font are GLUT_STROKE_ROMAN, GLUT_STROKE_MONO_ROMAN
  • void glutSetCursor(int cursor); - set the cursor shape. See the manual page for a list of cursors.
  • glRasterPos2f(x, y); - set the current position (which will determine for example where the next piece of text will be drawn). This version of the function takes 2 floats.

Menus

  • int msg_submenu=glutCreateMenu(selectMessage); - selectMessage is a callback routine (i.e. called when the menu is clicked on) of the type void selectMessage(int msg)
  • glutAddMenuEntry("abc", 1); - add an entry labelled "abc" to the current menu. If this option is chosen by the user, the callback routine will be given "1" as the argument.
  • glutAddSubMenu("Messages", msg_submenu); - add the menu to the window.

Coordinates

  • void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) - produces a rotation of angle degrees around the vector (x, y, z)

3D shapes

  • glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); - Renders a sphere centered at the modeling coordinates origin of the specified radius. The sphere is subdivided around the Z axis into slices and along the Z axis into stacks.
  • void glutSolidCube(GLdouble size); - The cube is centered at the modeling coordinates origin with sides of length size.

Callbacks

  • void glutIdleFunc(void(*func)() - this runs when the program has nothing else to do.

Example 2

This example add a key-event handler and does some error checking.

#include <iostream>
#include <glut.h>

void reshape(int w, int h)
{
  std::cout  << "calling reshape, dimensions " << w << " and " << h << std::endl;
  glViewport(0, 0, w, h);       /* Establish viewing area to cover entire window. */

  glMatrixMode(GL_PROJECTION);  /* Start modifying the projection matrix. */
  glLoadIdentity();      /* Reset project matrix. */       
  glOrtho(0, w, 0, h, -1, 1);   /* Map abstract coords directly to window coords. */
  glScalef(1, -1, 1);           /* Invert Y axis so increasing Y goes down. */
  glTranslatef(0, -h, 0);       /* Shift origin up to upper-left corner. */
  GLenum e;
  while ((e=glGetError()) != GL_NO_ERROR)
    std::cout  << "Error " << e << std::endl;
}

void display(void)
{
  std::cout << "calling display" << std::endl;
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLES);
    glColor3f(0.0, 0.0, 1.0);  /* blue */
    glVertex2i(0, 0);
    glColor3f(0.0, 1.0, 0.0);  /* green */
    glVertex2i(200, 200);
    glColor3f(1.0, 0.0, 0.0);  /* red */
    glVertex2i(20, 200);
  glEnd();
  glFlush();  /* Single buffered, so needs a flush. */
  GLenum e;
  while ((e=glGetError()) != GL_NO_ERROR)
    std::cout << "Error " << e << std::endl;
}

void keyboard (unsigned char key, int x, int y )
{
  switch ( key ) 
  {
  case 'q':
      exit ( 0 );
      break;
  case 'f':
      glutFullScreen ();
      break;
  case 'w':
      glutReshapeWindow (300,300 );
      break;
  default:
      break;
  }
}

using namespace std;

int main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB);
  cout << glutGet(GLUT_DISPLAY_MODE_POSSIBLE) << endl;
  if (! glutGet(GLUT_DISPLAY_MODE_POSSIBLE))
     glutInitDisplayMode(GLUT_INDEX);

  glutInitWindowSize(600,600);
  glutCreateWindow((char*)"single triangle");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutKeyboardFunc (keyboard);
  glutMainLoop();
  return 0;
}

See Also