1 #include "gl.h"
2 #include <limits.h>
3 
4 #define constDoubleToFloat(a, size) \
5     GLfloat s[size];                \
6     int i;                          \
7     for (i = 0; i < size; i++) {    \
8         s[i] = a[i];                \
9     }
10 
11 // naive wrappers
12 
13 #ifdef USE_ES2
glCompileShaderARB(GLuint shader)14 void glCompileShaderARB(GLuint shader) {
15     glCompileShader(shader);
16     GLint status;
17     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
18     if (status == GL_FALSE) {
19         GLint log_length;
20         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
21         GLchar *log = malloc(sizeof(GLchar) * log_length);
22         glGetShaderInfoLog(shader, log_length, NULL, log);
23         printf("Shader compile failed: %s\n", log);
24         free(log);
25     }
26 }
glCreateShaderObjectARB(GLenum shaderType)27 GLuint glCreateShaderObjectARB(GLenum shaderType) {
28     return glCreateShader(shaderType);
29 }
glShaderSourceARB(GLuint shader,GLsizei count,const GLchar ** string,const GLint * length)30 void glShaderSourceARB(GLuint shader, GLsizei count, const GLchar **string, const GLint *length) {
31     glShaderSource(shader, count, string, length);
32 }
glGetObjectParameterivARB(GLuint shader,GLenum pname,GLint * params)33 void glGetObjectParameterivARB(GLuint shader, GLenum pname, GLint *params) {
34     glGetShaderiv(shader, pname, params);
35 }
36 #endif
37 
glActiveTextureARB(GLenum texture)38 void glActiveTextureARB(GLenum texture) {
39     glActiveTexture(texture);
40 }
glClearDepth(GLdouble depth)41 void glClearDepth(GLdouble depth) {
42     glClearDepthf(depth);
43 }
glClientActiveTextureARB(GLenum texture)44 void glClientActiveTextureARB(GLenum texture) {
45 #ifndef USE_ES2
46     glClientActiveTexture(texture);
47 #endif
48 }
glClipPlane(GLenum plane,const GLdouble * equation)49 void glClipPlane(GLenum plane, const GLdouble *equation) {
50     constDoubleToFloat(equation, 4);
51     glClipPlanef(plane, s);
52 }
glDepthRange(GLdouble nearVal,GLdouble farVal)53 void glDepthRange(GLdouble nearVal, GLdouble farVal) {
54     glDepthRangef(nearVal, farVal);
55 }
glFogi(GLenum pname,GLint param)56 void glFogi(GLenum pname, GLint param) {
57     glFogf(pname, param);
58 }
glFogiv(GLenum pname,GLint * iparams)59 void glFogiv(GLenum pname, GLint *iparams) {
60     switch (pname) {
61         case GL_FOG_DENSITY:
62         case GL_FOG_START:
63         case GL_FOG_END:
64         case GL_FOG_INDEX: {
65             glFogf(pname, *iparams);
66             break;
67         }
68         case GL_FOG_MODE:
69         case GL_FOG_COLOR: {
70             GLfloat params[4];
71             for (int i = 0; i < 4; i++) {
72                 params[i] = iparams[i];
73             }
74             glFogfv(pname, params);
75             break;
76         }
77     }
78 }
glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far)79 void glFrustum(GLdouble left, GLdouble right, GLdouble bottom,
80              GLdouble top, GLdouble near, GLdouble far) {
81     glFrustumf(left, right, bottom, top, near, far);
82 }
glLighti(GLenum light,GLenum pname,GLint param)83 void glLighti(GLenum light, GLenum pname, GLint param) {
84     glLightf(light, pname, param);
85 }
glLightiv(GLenum light,GLenum pname,GLint * iparams)86 void glLightiv(GLenum light, GLenum pname, GLint *iparams) {
87     switch (pname) {
88         case GL_AMBIENT:
89         case GL_DIFFUSE:
90         case GL_SPECULAR:
91         case GL_POSITION: {
92             GLfloat params[4];
93             for (int i = 0; i < 4; i++) {
94                 params[i] = iparams[i];
95             }
96             glLightfv(light, pname, params);
97             break;
98         }
99         case GL_SPOT_DIRECTION: {
100             GLfloat params[3];
101             for (int i = 0; i < 4; i++) {
102                 params[i] = iparams[i];
103             }
104             glLightfv(light, pname, params);
105             break;
106         }
107         case GL_SPOT_EXPONENT:
108         case GL_SPOT_CUTOFF:
109         case GL_CONSTANT_ATTENUATION:
110         case GL_LINEAR_ATTENUATION:
111         case GL_QUADRATIC_ATTENUATION: {
112             glLightf(light, pname, *iparams);
113             break;
114         }
115     }
116 }
117 #ifndef USE_ES2
glLightModeli(GLenum pname,GLint param)118 void glLightModeli(GLenum pname, GLint param) {
119     glLightModelf(pname, param);
120 }
glLightModeliv(GLenum pname,GLint * iparams)121 void glLightModeliv(GLenum pname, GLint *iparams) {
122     switch (pname) {
123         case GL_LIGHT_MODEL_AMBIENT: {
124             GLfloat params[4];
125             for (int i = 0; i < 4; i++) {
126                 params[i] = iparams[i];
127             }
128             glLightModelfv(pname, params);
129             break;
130         }
131         case GL_LIGHT_MODEL_LOCAL_VIEWER:
132         case GL_LIGHT_MODEL_TWO_SIDE: {
133             glLightModelf(pname, *iparams);
134             break;
135         }
136     }
137 }
138 #endif
glMateriali(GLenum face,GLenum pname,GLint param)139 void glMateriali(GLenum face, GLenum pname, GLint param) {
140     glMaterialf(face, pname, param);
141 }
glMultiTexCoord2f(GLenum target,GLfloat s,GLfloat t)142 void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) {
143     glMultiTexCoord4f(target, s, t, 0.0f, 0.0f);
144 }
glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far)145 void glOrtho(GLdouble left, GLdouble right, GLdouble bottom,
146              GLdouble top, GLdouble near, GLdouble far) {
147     glOrthof(left, right, bottom, top, near, far);
148 }
149 
150 // OES wrappers
151 
glClearDepthfOES(GLfloat depth)152 void glClearDepthfOES(GLfloat depth) {
153     glClearDepthf(depth);
154 }
glClipPlanefOES(GLenum plane,const GLfloat * equation)155 void glClipPlanefOES(GLenum plane, const GLfloat *equation) {
156     glClipPlanef(plane, equation);
157 }
glDepthRangefOES(GLclampf near,GLclampf far)158 void glDepthRangefOES(GLclampf near, GLclampf far) {
159     glDepthRangef(near, far);
160 }
glFrustumfOES(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat near,GLfloat far)161 void glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom,
162                    GLfloat top, GLfloat near, GLfloat far) {
163     glFrustumf(left, right, bottom, top, near, far);
164 }
glGetClipPlanefOES(GLenum pname,GLfloat equation[4])165 void glGetClipPlanefOES(GLenum pname, GLfloat equation[4]) {
166     glGetClipPlanef(pname, equation);
167 }
glOrthofOES(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat near,GLfloat far)168 void glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom,
169                  GLfloat top, GLfloat near, GLfloat far) {
170     glOrthof(left, right, bottom, top, near, far);
171 }
172 
173 // glRect
174 
175 #define GL_RECT(suffix, type)                                 \
176     void glRect##suffix(type x1, type y1, type x2, type y2) { \
177         glBegin(GL_POLYGON);                                  \
178         glVertex2##suffix(x1, y1);                            \
179         glVertex2##suffix(x2, y1);                            \
180         glVertex2##suffix(x2, y2);                            \
181         glVertex2##suffix(x1, y2);                            \
182     }                                                         \
183     void glRect##suffix##v(const type *v) {                   \
184         glRect##suffix(v[0], v[1], v[2], v[3]);               \
185     }
186 
GL_RECT(d,GLdouble)187 GL_RECT(d, GLdouble)
188 GL_RECT(f, GLfloat)
189 GL_RECT(i, GLint)
190 GL_RECT(s, GLshort)
191 #undef GL_RECT
192 
193 // basic thunking
194 
195 #define THUNK(suffix, type, max)                            \
196 /* colors */                                                \
197 void glColor3##suffix(type r, type g, type b) {             \
198     glColor4f(r/max, g/max, b/max, 1.0f);                   \
199 }                                                           \
200 void glColor4##suffix(type r, type g, type b, type a) {     \
201     glColor4f(r/max, g/max, b/max, a/max);                  \
202 }                                                           \
203 void glColor3##suffix##v(const type *v) {                   \
204     glColor4f(v[0]/max, v[1]/max, v[2]/max, 1.0f);          \
205 }                                                           \
206 void glColor4##suffix##v(const type *v) {                   \
207     glColor4f(v[0]/max, v[1]/max, v[2]/max, v[3]/max);      \
208 }                                                           \
209 void glSecondaryColor3##suffix(type r, type g, type b) {    \
210     glSecondaryColor3f(r/max, g/max, b/max);                \
211 }                                                           \
212 void glSecondaryColor3##suffix##v(const type *v) {          \
213     glSecondaryColor3f(v[0]/max, v[1]/max, v[2]/max);       \
214 }                                                           \
215 /* index */                                                 \
216 void glIndex##suffix(type c) {                              \
217     glIndexf(c);                                            \
218 }                                                           \
219 void glIndex##suffix##v(const type *c) {                    \
220     glIndexf(c[0]);                                         \
221 }                                                           \
222 /* normal */                                                \
223 void glNormal3##suffix(type x, type y, type z) {            \
224     glNormal3f(x, y, z);                                    \
225 }                                                           \
226 void glNormal3##suffix##v(const type *v) {                  \
227     glNormal3f(v[0], v[1], v[2]);                           \
228 }                                                           \
229 /* raster */                                                \
230 void glRasterPos2##suffix(type x, type y) {                 \
231     glRasterPos3f(x, y, 0);                                 \
232 }                                                           \
233 void glRasterPos2##suffix##v(type *v) {                     \
234     glRasterPos3f(v[0], v[1], 0);                           \
235 }                                                           \
236 void glRasterPos3##suffix(type x, type y, type z) {         \
237     glRasterPos3f(x, y, z);                                 \
238 }                                                           \
239 void glRasterPos3##suffix##v(type *v) {                     \
240     glRasterPos3f(v[0], v[1], v[2]);                        \
241 }                                                           \
242 void glRasterPos4##suffix(type x, type y, type z, type w) { \
243     glRasterPos4f(x, y, z, w);                              \
244 }                                                           \
245 void glRasterPos4##suffix##v(type *v) {                     \
246     glRasterPos4f(v[0], v[1], v[2], v[3]);                  \
247 }                                                           \
248 /* vertex */                                                \
249 void glVertex2##suffix(type x, type y) {                    \
250     glVertex2f(x, y);                                       \
251 }                                                           \
252 void glVertex2##suffix##v(type *v) {                        \
253     glVertex2f(v[0], v[1]);                                 \
254 }                                                           \
255 void glVertex3##suffix(type x, type y, type z) {            \
256     glVertex3f(x, y, z);                                    \
257 }                                                           \
258 void glVertex3##suffix##v(type *v) {                        \
259     glVertex3f(v[0], v[1], v[2]);                           \
260 }                                                           \
261 void glVertex4##suffix(type r, type g, type b, type w) {    \
262     glVertex4f(r, g, b, w);                                 \
263 }                                                           \
264 void glVertex4##suffix##v(type *v) {                        \
265     glVertex4f(v[0], v[1], v[2], v[3]);                     \
266 }                                                           \
267 /* texture */                                               \
268 void glTexCoord1##suffix(type s) {                          \
269     glTexCoord2f(s, 0);                                     \
270 }                                                           \
271 void glTexCoord1##suffix##v(type *t) {                      \
272     glTexCoord2f(t[0], 0);                                  \
273 }                                                           \
274 void glTexCoord2##suffix(type s, type t) {                  \
275     glTexCoord2f(s, t);                                     \
276 }                                                           \
277 void glTexCoord2##suffix##v(type *t) {                      \
278     glTexCoord2f(t[0], t[1]);                               \
279 }                                                           \
280 void glTexCoord3##suffix(type s, type t, type r) {          \
281     glTexCoord2f(s, t);                                     \
282 }                                                           \
283 void glTexCoord3##suffix##v(type *t) {                      \
284     glTexCoord2f(t[0], t[1]);                               \
285 }                                                           \
286 void glTexCoord4##suffix(type s, type t, type r, type q) {  \
287     glTexCoord2f(s, t);                                     \
288 }                                                           \
289 void glTexCoord4##suffix##v(type *t) {                      \
290     glTexCoord2f(t[0], t[1]);                               \
291 }
292 
293 THUNK(b, GLbyte, (float)CHAR_MAX)
294 THUNK(d, GLdouble, 1.0f)
295 THUNK(i, GLint, (float)INT_MAX)
296 THUNK(s, GLshort, (float)SHRT_MAX)
297 THUNK(ub, GLubyte, (float)UCHAR_MAX)
298 THUNK(ui, GLuint, (float)UINT_MAX)
299 THUNK(us, GLushort, (float)USHRT_MAX)
300 
301 #undef THUNK
302 
303 // glGet
304 
305 #define THUNK(suffix, type)                              \
306 void glGet##suffix##v(GLenum pname, type *params) {      \
307     int i, n = 1;                                        \
308     switch (pname) {                                     \
309         /* two values */                                 \
310         case GL_ALIASED_POINT_SIZE_RANGE:                \
311         case GL_ALIASED_LINE_WIDTH_RANGE:                \
312         case GL_MAX_VIEWPORT_DIMS:                       \
313             n = 2;                                       \
314             break;                                       \
315         /* three values */                               \
316         case GL_CURRENT_NORMAL:                          \
317         case GL_POINT_DISTANCE_ATTENUATION:              \
318             n = 3;                                       \
319             break;                                       \
320         /* four values */                                \
321         case GL_COLOR_CLEAR_VALUE:                       \
322         case GL_COLOR_WRITEMASK:                         \
323         case GL_CURRENT_COLOR:                           \
324         case GL_CURRENT_TEXTURE_COORDS:                  \
325         case GL_DEPTH_RANGE:                             \
326         case GL_FOG_COLOR:                               \
327         case GL_LIGHT_MODEL_AMBIENT:                     \
328         case GL_SCISSOR_BOX:                             \
329         case GL_SMOOTH_LINE_WIDTH_RANGE:                 \
330         case GL_SMOOTH_POINT_SIZE_RANGE:                 \
331         case GL_VIEWPORT:                                \
332             n = 4;                                       \
333             break;                                       \
334         /* GL_NUM_COMPRESSED_TEXTURE_FORMATS values */   \
335         case GL_COMPRESSED_TEXTURE_FORMATS:              \
336             n = GL_NUM_COMPRESSED_TEXTURE_FORMATS;       \
337             break;                                       \
338         /* sixteen values */                             \
339         case GL_MODELVIEW_MATRIX:                        \
340         case GL_PROJECTION_MATRIX:                       \
341         case GL_TEXTURE_MATRIX:                          \
342             n = 16;                                      \
343             break;                                       \
344     }                                                    \
345     GLfloat *p = (GLfloat *)malloc(sizeof(GLfloat) * n); \
346     glGetFloatv(pname, p);                               \
347     for (i = 0; i < n; i++) {                            \
348         params[i] = (type)p[i];                          \
349     }                                                    \
350     free(p);                                             \
351 }
352 
353 THUNK(Double, GLdouble)
354 // THUNK(Integer, GLint)
355 
356 #undef THUNK
357 
358 // manually defined float wrappers, because we don't autowrap float functions
359 
360 // color
361 void glColor3f(GLfloat r, GLfloat g, GLfloat b) {
362     glColor4f(r, g, b, 1.0f);
363 }
glColor3fv(GLfloat * c)364 void glColor3fv(GLfloat *c) {
365     glColor4f(c[0], c[1], c[2], 1.0f);
366 }
glColor4fv(GLfloat * c)367 void glColor4fv(GLfloat *c) {
368     glColor4f(c[0], c[1], c[2], c[3]);
369 }
glIndexfv(const GLfloat * c)370 void glIndexfv(const GLfloat *c) {
371     glIndexf(*c);
372 }
glSecondaryColor3fv(const GLfloat * v)373 void glSecondaryColor3fv(const GLfloat *v) {
374     glSecondaryColor3f(v[0], v[1], v[2]);
375 }
376 
377 // raster
glRasterPos2f(GLfloat x,GLfloat y)378 void glRasterPos2f(GLfloat x, GLfloat y) {
379     glRasterPos3f(x, y, 0);
380 }
glRasterPos2fv(const GLfloat * v)381 void glRasterPos2fv(const GLfloat *v) {
382     glRasterPos2i(v[0], v[1]);
383 }
glRasterPos3fv(const GLfloat * v)384 void glRasterPos3fv(const GLfloat *v) {
385     glRasterPos3f(v[0], v[1], v[2]);
386 }
glRasterPos4f(GLfloat x,GLfloat y,GLfloat z,GLfloat w)387 void glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
388     glRasterPos3f(x/w, y/w, z/w);
389 }
glRasterPos4fv(const GLfloat * v)390 void glRasterPos4fv(const GLfloat *v) {
391     glRasterPos4f(v[0], v[1], v[2], v[3]);
392 }
393 
394 // eval
glEvalCoord1d(GLdouble u)395 void glEvalCoord1d(GLdouble u) {
396     glEvalCoord1f(u);
397 }
398 
glEvalCoord2d(GLdouble u,GLdouble v)399 void glEvalCoord2d(GLdouble u, GLdouble v) {
400     glEvalCoord2f(u, v);
401 }
402 
glEvalCoord1fv(GLfloat * v)403 void glEvalCoord1fv(GLfloat *v) {
404     glEvalCoord1f(v[0]);
405 }
406 
glEvalCoord1dv(GLdouble * v)407 void glEvalCoord1dv(GLdouble *v) {
408     glEvalCoord1d(v[0]);
409 }
410 
glEvalCoord2fv(GLfloat * v)411 void glEvalCoord2fv(GLfloat *v) {
412     glEvalCoord2f(v[0], v[1]);
413 }
414 
glEvalCoord2dv(GLdouble * v)415 void glEvalCoord2dv(GLdouble *v) {
416     glEvalCoord2d(v[0], v[1]);
417 }
418 
glMapGrid1d(GLint un,GLdouble u1,GLdouble u2)419 void glMapGrid1d(GLint un, GLdouble u1, GLdouble u2) {
420     glMapGrid1f(un, u1, u2);
421 }
422 
glMapGrid2d(GLint un,GLdouble u1,GLdouble u2,GLint vn,GLdouble v1,GLdouble v2)423 void glMapGrid2d(GLint un, GLdouble u1, GLdouble u2,
424                  GLint vn, GLdouble v1, GLdouble v2) {
425     glMapGrid2f(un, u1, u2, vn, v1, v2);
426 }
427 
428 // matrix
glLoadMatrixd(const GLdouble * m)429 void glLoadMatrixd(const GLdouble *m) {
430     constDoubleToFloat(m, 16);
431     glLoadMatrixf(s);
432 }
glMultMatrixd(const GLdouble * m)433 void glMultMatrixd(const GLdouble *m) {
434     constDoubleToFloat(m, 16);
435     glMultMatrixf(s);
436 }
437 
438 // normal
glNormal3fv(GLfloat * v)439 void glNormal3fv(GLfloat *v) {
440     glNormal3f(v[0], v[1], v[2]);
441 }
442 
443 // textures
glTexCoord1f(GLfloat s)444 void glTexCoord1f(GLfloat s) {
445     glTexCoord2f(s, 0);
446 }
glTexCoord1fv(GLfloat * t)447 void glTexCoord1fv(GLfloat *t) {
448     glTexCoord2f(t[0], 0);
449 }
glTexCoord2fv(GLfloat * t)450 void glTexCoord2fv(GLfloat *t) {
451     glTexCoord2f(t[0], t[1]);
452 }
glTexCoord3f(GLfloat s,GLfloat t,GLfloat r)453 void glTexCoord3f(GLfloat s, GLfloat t, GLfloat r) {
454     glTexCoord2f(s, t);
455 }
glTexCoord3fv(GLfloat * t)456 void glTexCoord3fv(GLfloat *t) {
457     glTexCoord2f(t[0], t[1]);
458 }
glTexCoord4f(GLfloat s,GLfloat t,GLfloat r,GLfloat q)459 void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
460     glTexCoord2f(s, t);
461 }
glTexCoord4fv(GLfloat * t)462 void glTexCoord4fv(GLfloat *t) {
463     glTexCoord2f(t[0], t[1]);
464 }
465 
466 // texgen
glTexGend(GLenum coord,GLenum pname,GLdouble param)467 void glTexGend(GLenum coord, GLenum pname, GLdouble param) {
468     glTexGeni(coord, pname, param);
469 }
glTexGenf(GLenum coord,GLenum pname,GLfloat param)470 void glTexGenf(GLenum coord, GLenum pname, GLfloat param) {
471     // TODO: this is gross/lossy.
472     glTexGeni(coord, pname, param);
473 }
glTexGendv(GLenum coord,GLenum pname,GLdouble * params)474 void glTexGendv(GLenum coord, GLenum pname, GLdouble *params) {
475     // TODO: stub
476     // glTexGenfv(coord, pname, thunked_params);
477 }
glTexGeniv(GLenum coord,GLenum pname,GLint * params)478 void glTexGeniv(GLenum coord, GLenum pname, GLint *params) {
479     // TODO: stub
480     // glTexGenfv(coord, pname, thunked_params);
481 }
482 
483 // transforms
glRotated(GLdouble angle,GLdouble x,GLdouble y,GLdouble z)484 void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) {
485     glRotatef(angle, x, y, z);
486 }
glScaled(GLdouble x,GLdouble y,GLdouble z)487 void glScaled(GLdouble x, GLdouble y, GLdouble z) {
488     glScalef(x, y, z);
489 }
glTranslated(GLdouble x,GLdouble y,GLdouble z)490 void glTranslated(GLdouble x, GLdouble y, GLdouble z) {
491     glTranslatef(x, y, z);
492 }
493 
494 // vertex
glVertex2f(GLfloat x,GLfloat y)495 void glVertex2f(GLfloat x, GLfloat y) {
496     glVertex3f(x, y, 0);
497 }
glVertex2fv(GLfloat * v)498 void glVertex2fv(GLfloat *v) {
499     glVertex3f(v[0], v[1], 0);
500 }
glVertex3fv(GLfloat * v)501 void glVertex3fv(GLfloat *v) {
502     glVertex3f(v[0], v[1], v[2]);
503 }
glVertex4f(GLfloat r,GLfloat g,GLfloat b,GLfloat w)504 void glVertex4f(GLfloat r, GLfloat g, GLfloat b, GLfloat w) {
505     glVertex3f(r/w, g/w, b/w);
506 }
glVertex4fv(GLfloat * v)507 void glVertex4fv(GLfloat *v) {
508     glVertex3f(v[0]/v[3], v[1]/v[3], v[2]/v[3]);
509 }
510 
511 #undef constDoubleToFloat
512