-
Notifications
You must be signed in to change notification settings - Fork 49
/
Portability.txt
139 lines (108 loc) · 5.54 KB
/
Portability.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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 <math.h> defines M_PI. Instead, after including
<math.h>, say the following:
-----------------------------------------------------------------------
/* Some <math.h> 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 <GL/glut.h>, 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 <unistd.h> 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 <getopt.h>; 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 <unistd.h> on Unix machines. Still,
Win32 does not have a builtin getopt.
o IBM's AIX defines "quad" to be a 64-bit type in <sys/type.h>.
Avoid using quad as a variable name.
o HP's HP-UX 10.20 may have a type or otherwise define "time".
Avoid using time as a variable name. XXX GLUT doesn't do this
well currently.
o GLU 1.2 introduced the types GLUquadric, GLUnurbs, and
GLUtesselator as aliases for the older GLUquadricObj, GLUnurbsObj,
and GLUtesselatorObj type names. Avoid the newer type names; use
the older names with the "Obj" suffix since all versions of GLU
support the Obj-suffixed types. (Note: yes, the GLU API has
GLUtesselatorObj is spelled incorrectly - tessellator should have
two l's.)
o Do not include <malloc.h> to get the standard C malloc/free
routines. Instead, include <stdlib.h>. FreeBSD and probably
other systems lack a <malloc.h>.
o Linux systems prototype a function called "idle" in <unistd.h>.
This can result in an error in GLUT programs that name their
idle callback "idle" and include <unistd.h>. Do no use a function
named idle if you include <unistd.h>.
o An early SunOS 5.6 version of <assert.h> requires that <stdio.h> also
be included because the assert() macro uses stderr. Be sure to
include <stdio.h> along with <assert.h> everywhere to avoid
build errors on SunOS 5.6.
o The DEC C V6.0 compiler will not allow routine names to have more
than 31 characters. The "/names=shortened" compiler option can
be used as a work-around when names exceed 31 characters.
- Mark Kilgard
August 13, 1999