1
/* $Id: glu.c,v 1.2 2003-08-22 20:11:43 brianp Exp $ */
4
* Mesa 3-D graphics library
6
* Copyright (C) 1995-2001 Brian Paul
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Library General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Library General Public License for more details.
18
* You should have received a copy of the GNU Library General Public
19
* License along with this library; if not, write to the Free
20
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37
* Miscellaneous utility functions
42
#define M_PI 3.1415926536
46
#ifndef GLU_INCOMPATIBLE_GL_VERSION
47
#define GLU_INCOMPATIBLE_GL_VERSION 100903
52
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
53
GLdouble centerx, GLdouble centery, GLdouble centerz,
54
GLdouble upx, GLdouble upy, GLdouble upz)
57
GLfloat x[3], y[3], z[3];
60
/* Make rotation matrix */
63
z[0] = eyex - centerx;
64
z[1] = eyey - centery;
65
z[2] = eyez - centerz;
66
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
67
if (mag) { /* mpichler, 19950515 */
78
/* X vector = Y cross Z */
79
x[0] = y[1] * z[2] - y[2] * z[1];
80
x[1] = -y[0] * z[2] + y[2] * z[0];
81
x[2] = y[0] * z[1] - y[1] * z[0];
83
/* Recompute Y = Z cross X */
84
y[0] = z[1] * x[2] - z[2] * x[1];
85
y[1] = -z[0] * x[2] + z[2] * x[0];
86
y[2] = z[0] * x[1] - z[1] * x[0];
88
/* mpichler, 19950515 */
89
/* cross product gives area of parallelogram, which is < 1.0 for
90
* non-perpendicular unit-length vectors; so normalize x, y here
93
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
100
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
107
#define M(row,col) m[col*4+row]
127
/* Translate Eye to Origin */
128
glTranslatef(-eyex, -eyey, -eyez);
135
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
137
glOrtho(left, right, bottom, top, -1.0, 1.0);
143
frustum(GLfloat left, GLfloat right,
144
GLfloat bottom, GLfloat top,
145
GLfloat nearval, GLfloat farval)
147
GLfloat x, y, a, b, c, d;
150
x = (2.0 * nearval) / (right - left);
151
y = (2.0 * nearval) / (top - bottom);
152
a = (right + left) / (right - left);
153
b = (top + bottom) / (top - bottom);
154
c = -(farval + nearval) / ( farval - nearval);
155
d = -(2.0 * farval * nearval) / (farval - nearval);
157
#define M(row,col) m[col*4+row]
158
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
159
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
160
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
161
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
169
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
171
GLfloat xmin, xmax, ymin, ymax;
173
ymax = zNear * tan(fovy * M_PI / 360.0);
175
xmin = ymin * aspect;
176
xmax = ymax * aspect;
178
/* don't call glFrustum() because of error semantics (covglu) */
179
frustum(xmin, xmax, ymin, ymax, zNear, zFar);
185
gluPickMatrix(GLdouble x, GLdouble y,
186
GLdouble width, GLdouble height, GLint viewport[4])
192
sx = viewport[2] / width;
193
sy = viewport[3] / height;
194
tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
195
ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
197
#define M(row,col) m[col*4+row]
221
const GLubyte *GLAPIENTRY
222
gluErrorString(GLenum errorCode)
224
static char *tess_error[] = {
225
"missing gluBeginPolygon",
226
"missing gluBeginContour",
227
"missing gluEndPolygon",
228
"missing gluEndContour",
229
"misoriented or self-intersecting loops",
230
"coincident vertices",
232
"FIST recovery process fatal error"
234
static char *nurbs_error[] = {
235
"spline order un-supported",
237
"valid knot range is empty",
238
"decreasing knot sequence knot",
239
"knot multiplicity greater than order of spline",
240
"endcurve() must follow bgncurve()",
241
"bgncurve() must precede endcurve()",
242
"missing or extra geometric data",
243
"can't draw pwlcurves",
244
"missing bgncurve()",
245
"missing bgnsurface()",
246
"endtrim() must precede endsurface()",
247
"bgnsurface() must precede endsurface()",
248
"curve of improper type passed as trim curve",
249
"bgnsurface() must precede bgntrim()",
250
"endtrim() must follow bgntrim()",
251
"bgntrim() must precede endtrim()",
252
"invalid or missing trim curve",
253
"bgntrim() must precede pwlcurve()",
254
"pwlcurve referenced twice",
255
"pwlcurve and nurbscurve mixed",
256
"improper usage of trim data type",
257
"nurbscurve referenced twice",
258
"nurbscurve and pwlcurve mixed",
259
"nurbssurface referenced twice",
261
"endsurface() must follow bgnsurface()",
262
"misoriented trim curves",
263
"intersecting trim curves",
265
"unconnected trim curves",
266
"unknown knot error",
267
"negative vertex count encountered",
268
"negative byte-stride encountered",
269
"unknown type descriptor",
270
"null control array or knot vector",
271
"duplicate point on pwlcurve"
275
if (errorCode == GL_NO_ERROR) {
276
return (GLubyte *) "no error";
278
else if (errorCode == GL_INVALID_VALUE) {
279
return (GLubyte *) "invalid value";
281
else if (errorCode == GL_INVALID_ENUM) {
282
return (GLubyte *) "invalid enum";
284
else if (errorCode == GL_INVALID_OPERATION) {
285
return (GLubyte *) "invalid operation";
287
else if (errorCode == GL_STACK_OVERFLOW) {
288
return (GLubyte *) "stack overflow";
290
else if (errorCode == GL_STACK_UNDERFLOW) {
291
return (GLubyte *) "stack underflow";
293
else if (errorCode == GL_OUT_OF_MEMORY) {
294
return (GLubyte *) "out of memory";
297
else if (errorCode == GLU_NO_ERROR) {
298
return (GLubyte *) "no error";
300
else if (errorCode == GLU_INVALID_ENUM) {
301
return (GLubyte *) "invalid enum";
303
else if (errorCode == GLU_INVALID_VALUE) {
304
return (GLubyte *) "invalid value";
306
else if (errorCode == GLU_OUT_OF_MEMORY) {
307
return (GLubyte *) "out of memory";
309
else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
310
return (GLubyte *) "incompatible GL version";
312
else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
313
return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
315
else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
316
return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
329
const GLubyte *GLAPIENTRY
330
gluGetString(GLenum name)
332
static char *extensions = "GL_EXT_abgr";
333
static char *version = "1.1 Mesa 3.5";
337
return (GLubyte *) extensions;
339
return (GLubyte *) version;
347
#if 0 /* gluGetProcAddressEXT not finalized yet! */
351
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
353
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
361
static struct proc procTable[] = {
362
{"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT}, /* me! */
364
/* new 1.1 functions */
365
{"gluGetString", (void *) gluGetString},
367
/* new 1.2 functions */
368
{"gluTessBeginPolygon", (void *) gluTessBeginPolygon},
369
{"gluTessBeginContour", (void *) gluTessBeginContour},
370
{"gluTessEndContour", (void *) gluTessEndContour},
371
{"gluTessEndPolygon", (void *) gluTessEndPolygon},
372
{"gluGetTessProperty", (void *) gluGetTessProperty},
374
/* new 1.3 functions */
380
for (i = 0; procTable[i].address; i++) {
381
if (strcmp((const char *) procName, procTable[i].name) == 0)
382
return (void (GLAPIENTRY *) ()) procTable[i].address;
395
#ifdef GLU_VERSION_1_3
397
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
402
const int len = strlen((const char *) extName);
403
const char *start = (const char *) extString;
406
const char *c = strstr(start, (const char *) extName);
410
if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))