Transmission Zero

Using freeglut or GLUT with MinGW



Introduction

OpenGL is a popular and widely implemented graphics specification, and is often a good choice when you need to write programs featuring 2D or 3D graphics. However, OpenGL defines how graphics should be drawn, and it is up to the programmer to handle things such as window definition and input from the mouse and keyboard. This can be performed using API specific to the windowing system, which of course requires that the programmer have a good knowledge of that API. Alternatively, libraries such as GLUT or SDL may be used. These provide an abstraction layer from the windowing system, with the added advantage that programs may be written which are independent of architecture and operating system (assuming of course that appropriate libraries are available on that platform).

This tutorial focuses on GLUT, and explains how to develop OpenGL applications for Windows using the C or C++ languages with MinGW. MinGW was chosen because it is freely available for download, and because its usage will be familiar to anyone who has used GCC.

I will cover the setting up of both freeglut and GLUT for Win32 in this tutorial, as these are the two most widely used versions of GLUT (there is OpenGLUT too, but this isn’t actively developed). I’ve created packages of both freeglut and GLUT for Win32 which you can download and use with MinGW.

Setting Up MinGW

It is assumed that you already have MinGW installed on your PC. If not, this is covered very well in the MinGW “Getting Started” Wiki. When setting up MinGW, the C compiler will be installed by default. No other MinGW components are needed in order to build freeglut applications, but you’ll probably want to install the C++ compiler as well if you intend to use C++.

Setting Up freeglut With MinGW

freeglut is intended to be a 100% compatible replacement for the original GLUT libraries. Unlike GLUT for Win32, freeglut is an up to date and actively maintained project, so I would recommend using freeglut if you have the choice. You can download my freeglut MinGW package (with checksums), which contains import libraries, headers, and a Windows DLL. Using this, you can either dynamically link against the freeglut DLL, or statically link the library into your application.

Once you have downloaded the freeglut MinGW package, create a folder on your PC which is readable by all users, for example “C:\Program Files\Common Files\MinGW\freeglut\”. Copy the “lib\” and “include\” folders from the zip archive to that location.

The freeglut DLL should either be placed in the same folder as your application, or can be installed in a system-wide folder which appears in your %PATH% environment variable. On a 32 bit Windows system this is typically “C:\Windows\System32\”, and on a 64 bit Windows system this is typically “C:\Windows\SysWOW64\”.

Compiling freeglut Applications With MinGW

To keep your applications compatible with GLUT, you should “#include <GL/glut.h>”. If you want to use freeglut specific extensions, you can “#include <GL/freeglut.h>” instead (bear in mind that if you’re using freeglut specific extensions, your code will likely need to be modified in order to build with a different GLUT implementation).

When compiling a freeglut application, it’s necessary to pass the path of the “include\” folder you created to the compiler using the “-I” option. Similarly when linking, it’s necessary to pass the path of the “lib\” folder to the linker using the “-L” option. In order to link to the freeglut and OpenGL libraries, you should additionally specify “-lfreeglut -lopengl32” during the link stage.

Given a source file “example.c”, which you want to compile to an application “example.exe”, you can compile and link it with the following commands (replacing the include and lib paths with the ones you created above if necessary):

gcc -c -o example.o example.c -I"C:\Program Files\Common Files\MinGW\freeglut\include"

gcc -o example.exe example.o -L"C:\Program Files\Common Files\MinGW\freeglut\lib" -lfreeglut -lopengl32 -Wl,--subsystem,windows
[Windows 7 Command Prompt showing the compile and link commands being executed.]

The “-Wl,--subsystem,windows” on the command line ensures the executable runs as a Windows GUI application rather than a console application. If you’re using GLU functions, you’ll also need to additionally specify “-lglu32” on the linker command line.

When distributing your application, don’t forget to include the freeglut DLL, or at least provide your users with some method of obtaining a copy.

Statically Linking freeglut

It’s possible statically link freeglut into your applications, instead of dynamically linking against the DLL as detailed above. The main disadvantage of static linking is that when an updated version of freeglut becomes available, the application must be recompiled in order to use the newer version. This is much more effort than when using dynamic linking, where it’s only necessary to deploy the newer version of the DLL—if your user has freeglut knowledge, they could even do this for their self! In any case, if you do want to use static linking it’s fairly simple.

The compilation step is almost the same as before, except that you need to define “FREEGLUT_STATIC” before any freeglut headers are included. This is best done by adding “-D FREEGLUT_STATIC” to the compiler command line. The linker step is also slightly different, as you must specify the static version of the freeglut library rather than the dynamic import library. It’s additionally necessary to link against the Windows multimedia library and GDI libraries, as freeglut uses functions from both of these libraries.

Given a source file “example.c”, which you want to compile to an application “example.exe”, you can compile and link it with the static freeglut library using following commands:

gcc -c -o example.o example.c -D FREEGLUT_STATIC -I"C:\Program Files\Common Files\MinGW\freeglut\include"

gcc -o example.exe example.o -L"C:\Program Files\Common Files\MinGW\freeglut\lib" -lfreeglut_static -lopengl32 -lwinmm ^
-lgdi32 -Wl,--subsystem,windows
[Windows 7 Command Prompt showing the compile and link commands being executed.]

If you get undefined references to functions when trying to statically link freeglut into your application, check your preprocessor definition and linker flags—static linking will fail if you forget to define “FREEGLUT_STATIC”, or if you have defined it but are linking against wrong libraries.

Setting Up GLUT for Win32 With MinGW

GLUT for Win32 is a Windows port of the original GLUT library. It’s no longer maintained or supported, but it’s still a very popular GLUT package. The MinGW “w32api” package already comes with two GLUT import libraries, “libglut.a” and “libglut32.a”, but doesn’t come with a glut header file. If you’ve ever downloaded a GLUT header from the internet, and attempted to link an application against either of these import libraries, you likely would have seen it fail with various undefined references. This is because the import libraries are from an older version of GLUT for Win32, which doesn’t contain the “atexit hack” functions which appear in the newer header file. I have created an up to date GLUT MinGW package (with checksums) to fix all of these issues.

Once you have downloaded the GLUT MinGW package, create a folder on your PC which is readable by all users, for example “C:\Program Files\Common Files\MinGW\GLUT\”. Copy the “lib\” and “include\” folders from the zip archive to that location.

The GLUT DLL should either be placed in the same folder as your application, or can be installed in a system-wide folder which appears in your %PATH% environment variable. On a 32 bit Windows system this is typically “C:\Windows\System32\”, and on a 64 bit Windows system this is typically “C:\Windows\SysWOW64\”.

Compiling GLUT for Win32 Applications With MinGW

To use functions from the GLUT for Win32 library, you should “#include <GL/glut.h>” in your source code.

As when compiling GLUT applications, it’s necessary to pass the path of the “include\” folder you created to the compiler using the “-I” option, and the path of the “lib\” folder to the linker using the “-L” option. When linking a GLUT application, you should link against the GLUT for Win32 and OpenGL libraries with the flags “-lglut32 -lopengl32”. Again, adding the flag “-Wl,--subsystem,windows” will ensure it compiles as a Windows GUI application rather than a console application. The commands to compile and link a typical GLUT application would be:

gcc -c -o example.o example.c -I"C:\Program Files\Common Files\MinGW\GLUT\include"

gcc -o example.exe example.o -L"C:\Program Files\Common Files\MinGW\GLUT\lib" -lglut32 -lopengl32 -Wl,--subsystem,windows
[Windows 7 Command Prompt showing the compile and link commands being executed.]

As with freeglut, it’s necessary to redistribute the GLUT DLL with your application, or at least provide some method for your users to obtain a copy.

Example GLUT Application

Here is very basic example GLUT application written in C, which you can use for testing once you have configured GLUT.

#include <stdlib.h>
#include <GL/glut.h>

void keyboard(unsigned char key, int x, int y);
void display(void);


int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutCreateWindow("GLUT Test");
  glutKeyboardFunc(&keyboard);
  glutDisplayFunc(&display);
  glutMainLoop();

  return EXIT_SUCCESS;
}


void keyboard(unsigned char key, int x, int y)
{
  switch (key)
  {
    case '\x1B':
      exit(EXIT_SUCCESS);
      break;
  }
}


void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(1.0f, 0.0f, 0.0f);

  glBegin(GL_POLYGON);
    glVertex2f(-0.5f, -0.5f);
    glVertex2f( 0.5f, -0.5f);
    glVertex2f( 0.5f,  0.5f);
    glVertex2f(-0.5f,  0.5f);
  glEnd();

  glFlush();
}

Running the application should produce something very similar to this:

[Image of a window containing a red square in the middle]

Cross-Compiling GLUT Applications

Although this tutorial focused on compiling GLUT applications with the Windows version of MinGW, you can of course cross-compile them on non-Windows versions. Many Linux distributions have MinGW packages available, and you can build your applications using the instructions above—the only difference being that you’ll have different library and include paths.

Under Fedora 14, I placed the libraries and headers under “/usr/local/share/MinGW/freeglut/” and built the application like this:

[mpayne@martpc MinGWGLUT]$ i686-pc-mingw32-gcc -c -o example.o example.c -I/usr/local/share/MinGW/freeglut/include/
[mpayne@martpc MinGWGLUT]$ i686-pc-mingw32-gcc -o example.exe example.o -L/usr/local/share/MinGW/freeglut/lib/ \
-lfreeglut -lopengl32 -Wl,--subsystem,windows
[Gnome Terminal on Fedora 12 showing the compile and link commands being executed.]