This note collects a bunch of portability issues that I've found in ensuring that GLUT example source code is truly portable. I encourage contributors to the GLUT source code distribution to review these guidelines: o Avoid variables, routines, or structure elements named "new" or "delete" to avoid these C++ keywords. o Avoid the "near" and "far" keywords introduced by Intel. Instead try using "nnear" and "ffar" since these are common names in graphics programming. o Do not assume the defines M_PI. Instead, after including , say the following: ----------------------------------------------------------------------- /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif ----------------------------------------------------------------------- o If you use the GLU tessellator, when you define or declare callback functions, use the "CALLBACK" calling convention identifier. This is required for the callbacks to work correctly under Win32. After including , say the following: ----------------------------------------------------------------------- /* Win32 calling conventions. */ #ifndef CALLBACK #define CALLBACK #endif ----------------------------------------------------------------------- Then using a GLU tessellator begin callback as an example say: ----------------------------------------------------------------------- static void CALLBACK begin(GLenum type, void *polyData) { glBegin(type); } ----------------------------------------------------------------------- When registering the callback, say: gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) &begin); o Avoid the floating point trig and exponential functions such as "sinf", "cosf", "expf", etc. These functions are reserved by ANSI C but not mandated. Instead use the double precision mandated functions "sin", "cos", "exp", etc. Some systems also support "fcos", "fsin", etc; definitely avoid these. o Do not use the EXIT_FAILURE and EXIT_SUCCESS constants defined by ANSI C. Some old systems do not define these in stdlib.h but are otherwise ANSI C compliant. Instead use "exit(1);" for failure and "exit(0);" for success. o Use "rand" to generate random number. Do not use "random" or "drand48" since they are not supported under Win32. o Avoid using "gettimeofday" or other system dependent routines to determine a timestamp. Instead use timestamp = glutGet(GLUT_ELAPSED_TIME); o If you need to read a directory, check out the "win32_direct.h" file used in progs/demos/walker/walker.c o Try to avoid including since it is not in Win32. o If your program runs in single buffered mode, be sure to call glFlush() at the end of your display callback. Some OpenGL implementations need a glFlush for pending graphics commands to fully execute. Note that glutSwapBuffers performs an implicit glFlush operation. o Avoid using strdup because strdup is not an actual ANSI C or POSIX required routine. Indeed, OpenVMS does not support it. And standard Linux libc only advertises strdup in string.h if BSD or SVID routines are requested. Instead, directly include the routine below: ----------------------------------------------------------------------- static char * stralloc(const char *string) { char *copy; copy = malloc(strlen(string) + 1); if (copy == NULL) return NULL; strcpy(copy, string); return copy; } ----------------------------------------------------------------------- o Do not #include ; some platforms like IBM's AIX do not have a getopt.h header file. Instead, you can portabily rely on getopt() to be declared in on Unix machines. Still, Win32 does not have a builtin getopt. o IBM's AIX defines "quad" to be a 64-bit type in . Avoid using quad as a variable name. - Mark Kilgard November 11, 1997