Subversion Repositories shark

Rev

Rev 55 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
128 giacomo 1
/* $Id: glu.c,v 1.2 2003-04-23 09:05:11 giacomo Exp $ */
55 pj 2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  3.5
6
 * Copyright (C) 1995-2001  Brian Paul
7
 *
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.
12
 *
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.
17
 *
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.
21
 */
22
 
23
 
24
#ifdef PC_HEADER
25
#include "all.h"
26
#else
27
#include <assert.h>
28
#include <math.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include "gluP.h"
33
#endif
34
 
35
 
36
/*
37
 * Miscellaneous utility functions
38
 */
39
 
40
 
41
#ifndef M_PI
42
#define M_PI 3.1415926536
43
#endif
44
#define EPS 0.00001
45
 
46
#ifndef GLU_INCOMPATIBLE_GL_VERSION
47
#define GLU_INCOMPATIBLE_GL_VERSION     100903
48
#endif
49
 
50
 
51
void GLAPIENTRY
52
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
53
          GLdouble centerx, GLdouble centery, GLdouble centerz,
54
          GLdouble upx, GLdouble upy, GLdouble upz)
55
{
56
   GLdouble m[16];
57
   GLdouble x[3], y[3], z[3];
58
   GLdouble mag;
59
 
60
   /* Make rotation matrix */
61
 
62
   /* Z vector */
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 */
68
      z[0] /= mag;
69
      z[1] /= mag;
70
      z[2] /= mag;
71
   }
72
 
73
   /* Y vector */
74
   y[0] = upx;
75
   y[1] = upy;
76
   y[2] = upz;
77
 
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];
82
 
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];
87
 
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
91
    */
92
 
93
   mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
94
   if (mag) {
95
      x[0] /= mag;
96
      x[1] /= mag;
97
      x[2] /= mag;
98
   }
99
 
100
   mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
101
   if (mag) {
102
      y[0] /= mag;
103
      y[1] /= mag;
104
      y[2] /= mag;
105
   }
106
 
107
#define M(row,col)  m[col*4+row]
108
   M(0, 0) = x[0];
109
   M(0, 1) = x[1];
110
   M(0, 2) = x[2];
111
   M(0, 3) = 0.0;
112
   M(1, 0) = y[0];
113
   M(1, 1) = y[1];
114
   M(1, 2) = y[2];
115
   M(1, 3) = 0.0;
116
   M(2, 0) = z[0];
117
   M(2, 1) = z[1];
118
   M(2, 2) = z[2];
119
   M(2, 3) = 0.0;
120
   M(3, 0) = 0.0;
121
   M(3, 1) = 0.0;
122
   M(3, 2) = 0.0;
123
   M(3, 3) = 1.0;
124
#undef M
125
   glMultMatrixd(m);
126
 
127
   /* Translate Eye to Origin */
128
   glTranslated(-eyex, -eyey, -eyez);
129
 
130
}
131
 
132
 
133
 
134
void GLAPIENTRY
135
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
136
{
137
   glOrtho(left, right, bottom, top, -1.0, 1.0);
138
}
139
 
140
 
141
 
142
static void
143
frustum(GLdouble left, GLdouble right,
144
        GLdouble bottom, GLdouble top,
145
        GLdouble nearval, GLdouble farval)
146
{
147
   GLdouble x, y, a, b, c, d;
148
   GLdouble m[16];
149
 
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);
156
 
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;
162
#undef M
163
 
164
   glMultMatrixd(m);
165
}
166
 
167
 
168
void GLAPIENTRY
169
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
170
{
171
   GLdouble xmin, xmax, ymin, ymax;
172
 
173
   ymax = zNear * tan(fovy * M_PI / 360.0);
174
   ymin = -ymax;
175
   xmin = ymin * aspect;
176
   xmax = ymax * aspect;
177
 
178
   /* don't call glFrustum() because of error semantics (covglu) */
179
   frustum(xmin, xmax, ymin, ymax, zNear, zFar);
180
}
181
 
182
 
183
 
184
void GLAPIENTRY
185
gluPickMatrix(GLdouble x, GLdouble y,
186
              GLdouble width, GLdouble height, GLint viewport[4])
187
{
188
   GLfloat m[16];
189
   GLfloat sx, sy;
190
   GLfloat tx, ty;
191
 
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;
196
 
197
#define M(row,col)  m[col*4+row]
198
   M(0, 0) = sx;
199
   M(0, 1) = 0.0;
200
   M(0, 2) = 0.0;
201
   M(0, 3) = tx;
202
   M(1, 0) = 0.0;
203
   M(1, 1) = sy;
204
   M(1, 2) = 0.0;
205
   M(1, 3) = ty;
206
   M(2, 0) = 0.0;
207
   M(2, 1) = 0.0;
208
   M(2, 2) = 1.0;
209
   M(2, 3) = 0.0;
210
   M(3, 0) = 0.0;
211
   M(3, 1) = 0.0;
212
   M(3, 2) = 0.0;
213
   M(3, 3) = 1.0;
214
#undef M
215
 
216
   glMultMatrixf(m);
217
}
218
 
219
 
220
 
221
const GLubyte *GLAPIENTRY
222
gluErrorString(GLenum errorCode)
223
{
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",
231
      "colinear vertices",
232
      "FIST recovery process fatal error"
233
   };
234
   static char *nurbs_error[] = {
235
      "spline order un-supported",
236
      "too few knots",
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",
260
      "invalid property",
261
      "endsurface() must follow bgnsurface()",
262
      "misoriented trim curves",
263
      "intersecting trim curves",
264
      "UNUSED",
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"
272
   };
273
 
274
   /* GL Errors */
275
   if (errorCode == GL_NO_ERROR) {
276
      return (GLubyte *) "no error";
277
   }
278
   else if (errorCode == GL_INVALID_VALUE) {
279
      return (GLubyte *) "invalid value";
280
   }
281
   else if (errorCode == GL_INVALID_ENUM) {
282
      return (GLubyte *) "invalid enum";
283
   }
284
   else if (errorCode == GL_INVALID_OPERATION) {
285
      return (GLubyte *) "invalid operation";
286
   }
287
   else if (errorCode == GL_STACK_OVERFLOW) {
288
      return (GLubyte *) "stack overflow";
289
   }
290
   else if (errorCode == GL_STACK_UNDERFLOW) {
291
      return (GLubyte *) "stack underflow";
292
   }
293
   else if (errorCode == GL_OUT_OF_MEMORY) {
294
      return (GLubyte *) "out of memory";
295
   }
296
   /* GLU Errors */
297
   else if (errorCode == GLU_NO_ERROR) {
298
      return (GLubyte *) "no error";
299
   }
300
   else if (errorCode == GLU_INVALID_ENUM) {
301
      return (GLubyte *) "invalid enum";
302
   }
303
   else if (errorCode == GLU_INVALID_VALUE) {
304
      return (GLubyte *) "invalid value";
305
   }
306
   else if (errorCode == GLU_OUT_OF_MEMORY) {
307
      return (GLubyte *) "out of memory";
308
   }
309
   else if (errorCode == GLU_INCOMPATIBLE_GL_VERSION) {
310
      return (GLubyte *) "incompatible GL version";
311
   }
312
   else if (errorCode >= GLU_TESS_ERROR1 && errorCode <= GLU_TESS_ERROR8) {
313
      return (GLubyte *) tess_error[errorCode - GLU_TESS_ERROR1];
314
   }
315
   else if (errorCode >= GLU_NURBS_ERROR1 && errorCode <= GLU_NURBS_ERROR37) {
316
      return (GLubyte *) nurbs_error[errorCode - GLU_NURBS_ERROR1];
317
   }
318
   else {
319
      return NULL;
320
   }
321
}
322
 
323
 
324
 
325
/*
326
 * New in GLU 1.1
327
 */
328
 
329
const GLubyte *GLAPIENTRY
330
gluGetString(GLenum name)
331
{
332
   static char *extensions = "GL_EXT_abgr";
333
   static char *version = "1.1 Mesa 3.5";
334
 
335
   switch (name) {
336
   case GLU_EXTENSIONS:
337
      return (GLubyte *) extensions;
338
   case GLU_VERSION:
339
      return (GLubyte *) version;
340
   default:
341
      return NULL;
342
   }
343
}
344
 
345
 
346
 
347
#if 0                           /* gluGetProcAddressEXT not finalized yet! */
348
 
349
#ifdef __cplusplus
350
   /* for BeOS R4.5 */
351
void GLAPIENTRY(*gluGetProcAddressEXT(const GLubyte * procName)) (...)
352
#else
353
void (GLAPIENTRY * gluGetProcAddressEXT(const GLubyte * procName)) ()
354
#endif
355
{
356
   struct proc
357
   {
358
      const char *name;
359
      void *address;
360
   };
361
   static struct proc procTable[] = {
362
      {"gluGetProcAddressEXT", (void *) gluGetProcAddressEXT},  /* me! */
363
 
364
      /* new 1.1 functions */
365
      {"gluGetString", (void *) gluGetString},
366
 
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},
373
 
374
      /* new 1.3 functions */
375
 
376
      {NULL, NULL}
377
   };
378
   GLuint i;
379
 
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;
383
   }
384
 
385
   return NULL;
386
}
387
 
388
#endif
389
 
390
 
391
 
392
/*
393
 * New in GLU 1.3
394
 */
395
#ifdef GLU_VERSION_1_3
396
GLboolean GLAPIENTRY
397
gluCheckExtension(const GLubyte *extName, const GLubyte * extString)
398
{
399
   assert(extName);
400
   assert(extString);
128 giacomo 401
 
402
   return GL_TRUE;
403
 
55 pj 404
}
405
#endif