1 /*
2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9 **
10 ** http://oss.sgi.com/projects/FreeB
11 **
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17 **
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
23 **
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
33 **
34 */
35 /*
36 */
37 
38 #include "gluos.h"
39 #include <GL/gl.h>
40 #include <GL/glu.h>
41 #include <stdio.h>
42 #include "glimports.h"
43 #include "glrenderer.h"
44 #include "nurbsconsts.h"
45 
46 //#define DOWN_LOAD_NURBS
47 #ifdef DOWN_LOAD_NURBS
48 
49 #include "oglTrimNurbs.h"
50 static int surfcount = 0;
51 static oglTrimNurbs* otn = NULL;
52 nurbSurf* tempNurb = NULL;
53 oglTrimLoops* tempTrim = NULL;
54 #endif
55 
56 
57 //for LOD
58 extern "C" {void glu_LOD_eval_list(GLUnurbs *nurb, int level);}
59 
glu_LOD_eval_list(GLUnurbs * nurb,int level)60 void glu_LOD_eval_list(GLUnurbs *nurb, int level)
61 {
62 	nurb->LOD_eval_list(level);
63 }
64 
65 GLUnurbs * GLAPIENTRY
gluNewNurbsRenderer(void)66 gluNewNurbsRenderer(void)
67 {
68   GLUnurbs *t;
69 
70   t = new GLUnurbs();
71   return t;
72 }
73 
74 void GLAPIENTRY
gluDeleteNurbsRenderer(GLUnurbs * r)75 gluDeleteNurbsRenderer(GLUnurbs *r)
76 {
77     delete r;
78 }
79 
80 extern "C"
81 void GLAPIENTRY
82 
gluDeleteNurbsTessellatorEXT(GLUnurbsObj * r)83 gluDeleteNurbsTessellatorEXT(GLUnurbsObj *r)
84 {
85   delete r;
86 }
87 
88 void GLAPIENTRY
gluBeginSurface(GLUnurbs * r)89 gluBeginSurface(GLUnurbs *r)
90 {
91 #ifdef DOWN_LOAD_NURBS
92 surfcount++;
93 tempTrim = OTL_make(10,10);
94 #endif
95     r->bgnsurface(0);
96 }
97 
98 void GLAPIENTRY
gluBeginCurve(GLUnurbs * r)99 gluBeginCurve(GLUnurbs *r)
100 {
101     r->bgncurve(0);
102 }
103 
104 void GLAPIENTRY
gluEndCurve(GLUnurbs * r)105 gluEndCurve(GLUnurbs *r)
106 {
107     r->endcurve();
108 }
109 
110 void GLAPIENTRY
gluEndSurface(GLUnurbs * r)111 gluEndSurface(GLUnurbs *r)
112 {
113 #ifdef DOWN_LOAD_NURBS
114 if(surfcount == 1)
115   otn = OTN_make(1);
116 OTN_insert(otn, tempNurb, tempTrim);
117 if(surfcount  >= 1)
118 {
119 #ifdef DEBUG
120 printf("write file\n");
121 #endif
122 OTN_write(otn, "out.otn");
123 
124 }
125 #endif
126 
127     r->endsurface();
128 }
129 
130 void GLAPIENTRY
gluBeginTrim(GLUnurbs * r)131 gluBeginTrim(GLUnurbs *r)
132 {
133 #ifdef DOWN_LOAD_NURBS
134 OTL_bgnTrim(tempTrim);
135 #endif
136 
137     r->bgntrim();
138 }
139 
140 void GLAPIENTRY
gluEndTrim(GLUnurbs * r)141 gluEndTrim(GLUnurbs *r)
142 {
143 #ifdef DOWN_LOAD_NURBS
144 OTL_endTrim(tempTrim);
145 #endif
146     r->endtrim();
147 }
148 
149 void GLAPIENTRY
gluPwlCurve(GLUnurbs * r,GLint count,INREAL array[],GLint stride,GLenum type)150 gluPwlCurve(GLUnurbs *r, GLint count, INREAL array[],
151 		GLint stride, GLenum type)
152 {
153 #ifdef DOWN_LOAD_NURBS
154 OTL_pwlCurve(tempTrim, count, array, stride, type);
155 #endif
156 
157     int realType;
158     switch(type) {
159       case GLU_MAP1_TRIM_2:
160 	realType = N_P2D;
161 	break;
162       case GLU_MAP1_TRIM_3:
163 	realType = N_P2DR;
164 	break;
165       default:
166 	realType = type;
167 	break;
168     }
169     r->pwlcurve(count, array, sizeof(INREAL) * stride, realType);
170 }
171 
172 void GLAPIENTRY
gluNurbsCurve(GLUnurbs * r,GLint nknots,INREAL knot[],GLint stride,INREAL ctlarray[],GLint order,GLenum type)173 gluNurbsCurve(GLUnurbs *r, GLint nknots, INREAL knot[], GLint stride,
174 		  INREAL ctlarray[], GLint order, GLenum type)
175 {
176 #ifdef DOWN_LOAD_NURBS
177 OTL_nurbsCurve(tempTrim, nknots, knot, stride, ctlarray, order, type);
178 #endif
179 
180     int realType;
181 
182     switch(type) {
183       case GLU_MAP1_TRIM_2:
184 	realType = N_P2D;
185 	break;
186       case GLU_MAP1_TRIM_3:
187 	realType = N_P2DR;
188 	break;
189       default:
190 	realType = type;
191 	break;
192     }
193 
194     r->nurbscurve(nknots, knot, sizeof(INREAL) * stride, ctlarray, order,
195 	    realType);
196 }
197 
198 void GLAPIENTRY
gluNurbsSurface(GLUnurbs * r,GLint sknot_count,GLfloat * sknot,GLint tknot_count,GLfloat * tknot,GLint s_stride,GLint t_stride,GLfloat * ctlarray,GLint sorder,GLint torder,GLenum type)199 gluNurbsSurface(GLUnurbs *r, GLint sknot_count, GLfloat *sknot,
200 			    GLint tknot_count, GLfloat *tknot,
201 			    GLint s_stride, GLint t_stride,
202 			    GLfloat *ctlarray, GLint sorder, GLint torder,
203 			    GLenum type)
204 {
205 #ifdef DOWN_LOAD_NURBS
206   {
207     int dimension;
208     switch(type){
209     case GL_MAP2_VERTEX_3:
210       dimension = 3;
211       break;
212     case GL_MAP2_VERTEX_4:
213       dimension = 4;
214       break;
215     default:
216       fprintf(stderr, "error in glinterface.c++, type no implemented\n");
217       exit(1);
218     }
219 tempNurb = nurbSurfMake(sknot_count, sknot,
220 			tknot_count, tknot,
221 			sorder, torder,
222 			dimension,
223 			ctlarray,
224 			s_stride, t_stride);
225 
226   }
227 #endif
228 
229     r->nurbssurface(sknot_count, sknot, tknot_count, tknot,
230 	    sizeof(INREAL) * s_stride, sizeof(INREAL) * t_stride,
231 	    ctlarray, sorder, torder, type);
232 }
233 
234 void GLAPIENTRY
gluLoadSamplingMatrices(GLUnurbs * r,const GLfloat modelMatrix[16],const GLfloat projMatrix[16],const GLint viewport[4])235 gluLoadSamplingMatrices(GLUnurbs *r, const GLfloat modelMatrix[16],
236 			    const GLfloat projMatrix[16],
237 			    const GLint viewport[4])
238 {
239     r->useGLMatrices(modelMatrix, projMatrix, viewport);
240 }
241 
242 void GLAPIENTRY
gluNurbsProperty(GLUnurbs * r,GLenum property,GLfloat value)243 gluNurbsProperty(GLUnurbs *r, GLenum property, GLfloat value)
244 {
245     GLfloat nurbsValue;
246 
247     switch (property) {
248       case GLU_AUTO_LOAD_MATRIX:
249         r->setautoloadmode(value);
250 	return;
251 
252       case GLU_CULLING:
253 	if (value != 0.0) {
254 	    nurbsValue = N_CULLINGON;
255 	} else {
256 	    nurbsValue = N_NOCULLING;
257 	}
258 	r->setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, nurbsValue);
259 	r->setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLING, nurbsValue);
260 	r->setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLING, nurbsValue);
261 	r->setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLING, nurbsValue);
262         return;
263 
264       case GLU_SAMPLING_METHOD:
265 	if (value == GLU_PATH_LENGTH) {
266 	    nurbsValue = N_PATHLENGTH;
267 	} else if (value == GLU_PARAMETRIC_ERROR) {
268 	    nurbsValue = N_PARAMETRICDISTANCE;
269 	} else if (value == GLU_DOMAIN_DISTANCE) {
270 	    nurbsValue = N_DOMAINDISTANCE;
271             r->set_is_domain_distance_sampling(1); //optimzing untrimmed case
272 
273 	} else if (value == GLU_OBJECT_PARAMETRIC_ERROR) {
274 	    nurbsValue = N_OBJECTSPACE_PARA;
275 	    r->setautoloadmode( 0.0 );
276 	    r->setSamplingMatrixIdentity();
277 	} else if (value == GLU_OBJECT_PATH_LENGTH) {
278 	    nurbsValue = N_OBJECTSPACE_PATH;
279 	    r->setautoloadmode( 0.0 );
280 	    r->setSamplingMatrixIdentity();
281 	} else {
282             r->postError(GLU_INVALID_VALUE);
283             return;
284         }
285 
286 	r->setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue);
287 	r->setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue);
288 	r->setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue);
289 	r->setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue);
290 	return;
291 
292       case GLU_SAMPLING_TOLERANCE:
293 	r->setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value);
294 	r->setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, value);
295 	r->setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, value);
296 	r->setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, value);
297 	return;
298 
299       case GLU_PARAMETRIC_TOLERANCE:
300 	r->setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value);
301         r->setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, value);
302         r->setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, value);
303         r->setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, value);
304         return;
305 
306 
307       case GLU_DISPLAY_MODE:
308 
309 	if (value == GLU_FILL) {
310 	  nurbsValue = N_FILL;
311 	} else if (value == GLU_OUTLINE_POLYGON) {
312 	  nurbsValue = N_OUTLINE_POLY;
313 	} else if (value == GLU_OUTLINE_PATCH) {
314 	  nurbsValue = N_OUTLINE_PATCH;
315 	} else {
316 	  r->postError(GLU_INVALID_VALUE);
317 	  return;
318 	}
319 	r->setnurbsproperty(N_DISPLAY, nurbsValue);
320 
321 	break;
322 
323       case GLU_U_STEP:
324     	r->setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, value);
325     	r->setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, value);
326     	r->setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value);
327     	r->setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, value);
328 
329 	//added for optimizing untrimmed case
330         r->set_domain_distance_u_rate(value);
331 	break;
332 
333       case GLU_V_STEP:
334         r->setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, value);
335         r->setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, value);
336         r->setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value);
337         r->setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, value);
338 
339 	//added for optimizing untrimmed case
340         r->set_domain_distance_v_rate(value);
341 	break;
342 
343       case GLU_NURBS_MODE:
344 	if(value == GLU_NURBS_RENDERER)
345 	  r->put_callbackFlag(0);
346 	else if(value == GLU_NURBS_TESSELLATOR)
347 	  r->put_callbackFlag(1);
348 	else
349 	  r->postError(GLU_INVALID_ENUM);
350 	break;
351 
352       default:
353 	r->postError(GLU_INVALID_ENUM);
354 	return;
355     }
356 }
357 
358 void GLAPIENTRY
gluGetNurbsProperty(GLUnurbs * r,GLenum property,GLfloat * value)359 gluGetNurbsProperty(GLUnurbs *r, GLenum property, GLfloat *value)
360 {
361     GLfloat nurbsValue;
362 
363     switch(property) {
364       case GLU_AUTO_LOAD_MATRIX:
365 	if (r->getautoloadmode()) {
366 	    *value = GL_TRUE;
367 	} else {
368 	    *value = GL_FALSE;
369 	}
370 	break;
371       case GLU_CULLING:
372 	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, &nurbsValue);
373 	if (nurbsValue == N_CULLINGON) {
374 	    *value = GL_TRUE;
375 	} else {
376 	    *value = GL_FALSE;
377 	}
378 	break;
379       case GLU_SAMPLING_METHOD:
380 	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, value);
381 	if(*value == N_PATHLENGTH)
382 	  *value = GLU_PATH_LENGTH;
383 	else if(*value == N_PARAMETRICDISTANCE)
384 	  *value = GLU_PARAMETRIC_ERROR;
385 	else if(*value == N_DOMAINDISTANCE)
386 	  *value = GLU_DOMAIN_DISTANCE;
387 	else if(*value == N_OBJECTSPACE_PATH)
388 	  *value = GLU_OBJECT_PATH_LENGTH;
389 	else if(*value == N_OBJECTSPACE_PARA)
390 	  *value = GLU_OBJECT_PARAMETRIC_ERROR;
391 	break;
392       case GLU_SAMPLING_TOLERANCE:
393 	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value);
394 	break;
395       case GLU_PARAMETRIC_TOLERANCE:
396 	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value);
397         break;
398 
399       case GLU_U_STEP:
400     	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value);
401 	break;
402       case GLU_V_STEP:
403     	r->getnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value);
404 	break;
405       case GLU_DISPLAY_MODE:
406 	r->getnurbsproperty(N_DISPLAY, &nurbsValue);
407 	if (nurbsValue == N_FILL) {
408 	    *value = GLU_FILL;
409 	} else if (nurbsValue == N_OUTLINE_POLY) {
410 	    *value = GLU_OUTLINE_POLYGON;
411 	} else {
412 	    *value = GLU_OUTLINE_PATCH;
413 	}
414 	break;
415 
416       case GLU_NURBS_MODE:
417 	if(r->is_callback())
418 	  *value = GLU_NURBS_TESSELLATOR;
419 	else
420 	  *value = GLU_NURBS_RENDERER;
421 	break;
422 
423       default:
424 	r->postError(GLU_INVALID_ENUM);
425 	return;
426     }
427 }
428 
429 extern "C" void GLAPIENTRY
gluNurbsCallback(GLUnurbs * r,GLenum which,_GLUfuncptr fn)430 gluNurbsCallback(GLUnurbs *r, GLenum which, _GLUfuncptr fn )
431 {
432     switch (which) {
433     case GLU_NURBS_BEGIN:
434     case GLU_NURBS_END:
435     case GLU_NURBS_VERTEX:
436     case GLU_NURBS_NORMAL:
437     case GLU_NURBS_TEXTURE_COORD:
438     case GLU_NURBS_COLOR:
439     case GLU_NURBS_BEGIN_DATA:
440     case GLU_NURBS_END_DATA:
441     case GLU_NURBS_VERTEX_DATA:
442     case GLU_NURBS_NORMAL_DATA:
443     case GLU_NURBS_TEXTURE_COORD_DATA:
444     case GLU_NURBS_COLOR_DATA:
445 	r->putSurfCallBack(which, fn);
446 	break;
447 
448     case GLU_NURBS_ERROR:
449 	r->errorCallback = (void (APIENTRY *)( GLenum e )) fn;
450 	break;
451     default:
452 	r->postError(GLU_INVALID_ENUM);
453 	return;
454     }
455 }
456 
457 extern "C"
458 void GLAPIENTRY
gluNurbsCallbackDataEXT(GLUnurbs * r,void * userData)459 gluNurbsCallbackDataEXT(GLUnurbs* r, void* userData)
460 {
461   r->setNurbsCallbackData(userData);
462 }
463 
464 extern "C"
465 void GLAPIENTRY
gluNurbsCallbackData(GLUnurbs * r,void * userData)466 gluNurbsCallbackData(GLUnurbs* r, void* userData)
467 {
468   gluNurbsCallbackDataEXT(r,userData);
469 }
470