Introduction to GLUT tutorials

GLUT is a window system independent toolkit for writing OpenGL programs. It is very old and outdated, but still good to create OpenGL examples because the code is portable and easy to understand. There are projects that try to follow the GLUT API like Freeglut.

Main

The code to create a window to display OpenGL graphics is this simple:

int main(int argc, char** argv)
{
   glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA | GLUT_MULTISAMPLE );
   glutInitWindowPosition( 0, 0 );
   glutInitWindowSize( 640, 480 );
   glutInit( &argc, argv );
   glutCreateWindow("VideoMan with DirectShow");

After the call to glutCreateWindow the window is created and the OpenGL context is active. This is when we can initialize the VideoMan stuff. VideoMan will create a texture for each added input, this is why we need the context to be active. In the examples we will call a function initializeVideoman.

The other important part of GLUT are the callbacks. These are functions that will handle the GLUT events generated when you change the size of the window or press a key.

   glutReshapeFunc(glutResize);
   glutDisplayFunc(glutDisplay);
   glutIdleFunc(glutDisplay);
   glutKeyboardFunc(glutKeyboard);

After setting up the callbacks we will start the GLUT event processing loop calling glutMainLoop. Once called, this routine will never return until we finish the application.

   glutMainLoop();

Callbacks

The function glutResize handles the window resize event is something like this:

void glutResize(int width, int height)
{
   videoMan.changeScreenSize( 0, 0, width, height );
}

Here we just pass to VideoMan the new size of the window. This way, VideoMan can calculate the new positions and size of the inputs in the window.

The function passed to glutIdleFunc is the idle callback that will be executed repitedly. In most of the tutorials we use the same callback for glutIdleFunc and glutDisplayFunc. The gluDisplay callback will be something like this:

void glutDisplay(void)
{
   //Clear the opengl window
   glClear( GL_COLOR_BUFFER_BIT );
   //Get a new frame from input n
   char *image = videoMan.getFrame( inputID );
   if ( image != NULL )
   {
      //Update the texture of the renderer
      videoMan.updateTexture( inputID );
      //Release the frame
      videoMan.releaseFrame( inputID );
   }
   //render the image of input n in the screen
   videoMan.renderFrame( inputID );
    glutSwapBuffers();
}

First we clear the buffer to start a new render. Then we ask VideoMan if there is a new frame available from the input. If so, we update the renderer texture, release the frame and render the input. If we don't pass an image pointer to updateTexture, the texture will be updated we the last captured frame. We call releasFrame as soon as we don't need access to the image memory. The renderFrame function will use the recently updated texture, so we can call it before or after releaseFrame.  Note, that renderFrame is called outside the if in order to avoid flickering. Finally glutSwapBuffers will tell OpenGL to show the new render in the window.