Rev 128 | 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 |