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" 50static int surfcount = 0; 51static oglTrimNurbs* otn = NULL; 52nurbSurf* tempNurb = NULL; 53oglTrimLoops* tempTrim = NULL; 54#endif 55 56 57//for LOD 58extern "C" {void glu_LOD_eval_list(GLUnurbs *nurb, int level);} 59 60void glu_LOD_eval_list(GLUnurbs *nurb, int level) 61{ 62 nurb->LOD_eval_list(level); 63} 64 65GLUnurbs * GLAPIENTRY 66gluNewNurbsRenderer(void) 67{ 68 GLUnurbs *t; 69 70 t = new GLUnurbs(); 71 return t; 72} 73 74void GLAPIENTRY 75gluDeleteNurbsRenderer(GLUnurbs *r) 76{ 77 delete r; 78} 79 80extern "C" 81void GLAPIENTRY 82 83gluDeleteNurbsTessellatorEXT(GLUnurbsObj *r) 84{ 85 delete r; 86} 87 88void GLAPIENTRY 89gluBeginSurface(GLUnurbs *r) 90{ 91#ifdef DOWN_LOAD_NURBS 92surfcount++; 93tempTrim = OTL_make(10,10); 94#endif 95 r->bgnsurface(0); 96} 97 98void GLAPIENTRY 99gluBeginCurve(GLUnurbs *r) 100{ 101 r->bgncurve(0); 102} 103 104void GLAPIENTRY 105gluEndCurve(GLUnurbs *r) 106{ 107 r->endcurve(); 108} 109 110void GLAPIENTRY 111gluEndSurface(GLUnurbs *r) 112{ 113#ifdef DOWN_LOAD_NURBS 114if(surfcount == 1) 115 otn = OTN_make(1); 116OTN_insert(otn, tempNurb, tempTrim); 117if(surfcount >= 1) 118{ 119#ifdef DEBUG 120printf("write file\n"); 121#endif 122OTN_write(otn, "out.otn"); 123 124} 125#endif 126 127 r->endsurface(); 128} 129 130void GLAPIENTRY 131gluBeginTrim(GLUnurbs *r) 132{ 133#ifdef DOWN_LOAD_NURBS 134OTL_bgnTrim(tempTrim); 135#endif 136 137 r->bgntrim(); 138} 139 140void GLAPIENTRY 141gluEndTrim(GLUnurbs *r) 142{ 143#ifdef DOWN_LOAD_NURBS 144OTL_endTrim(tempTrim); 145#endif 146 r->endtrim(); 147} 148 149void GLAPIENTRY 150gluPwlCurve(GLUnurbs *r, GLint count, INREAL array[], 151 GLint stride, GLenum type) 152{ 153#ifdef DOWN_LOAD_NURBS 154OTL_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 172void GLAPIENTRY 173gluNurbsCurve(GLUnurbs *r, GLint nknots, INREAL knot[], GLint stride, 174 INREAL ctlarray[], GLint order, GLenum type) 175{ 176#ifdef DOWN_LOAD_NURBS 177OTL_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 198void GLAPIENTRY 199gluNurbsSurface(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 } 219tempNurb = 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 234void GLAPIENTRY 235gluLoadSamplingMatrices(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 242void GLAPIENTRY 243gluNurbsProperty(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 358void GLAPIENTRY 359gluGetNurbsProperty(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 429extern "C" void GLAPIENTRY 430gluNurbsCallback(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 457extern "C" 458void GLAPIENTRY 459gluNurbsCallbackDataEXT(GLUnurbs* r, void* userData) 460{ 461 r->setNurbsCallbackData(userData); 462} 463 464extern "C" 465void GLAPIENTRY 466gluNurbsCallbackData(GLUnurbs* r, void* userData) 467{ 468 gluNurbsCallbackDataEXT(r,userData); 469} 470