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 * backend.c++ 37 * 38 */ 39 40 /* Bezier surface backend 41 - interprets display mode (wireframe,shaded,...) 42 */ 43 #include <stdio.h> 44 #include "glimports.h" 45 #include "mystdio.h" 46 #include "backend.h" 47 #include "basiccrveval.h" 48 #include "basicsurfeval.h" 49 50 #define NOWIREFRAME 51 52 53 /*------------------------------------------------------------------------- 54 * bgnsurf - preamble to surface definition and evaluations 55 *------------------------------------------------------------------------- 56 */ 57 void 58 Backend::bgnsurf( int wiretris, int wirequads, long nuid ) 59 { 60 /*#ifndef NOWIREFRAME*/ //need this for old version 61 wireframetris = wiretris; 62 wireframequads = wirequads; 63 /*#endif*/ 64 65 /*in the spec, GLU_DISPLAY_MODE is either 66 * GLU_FILL 67 * GLU_OUTLINE_POLY 68 * GLU_OUTLINE_PATCH. 69 *In fact, GLU_FLL is has the same effect as 70 * set GL_FRONT_AND_BACK to be GL_FILL 71 * and GLU_OUTLINE_POLY is the same as set 72 * GL_FRONT_AND_BACK to be GL_LINE 73 *It is more efficient to do this once at the beginning of 74 *each surface than to do it for each primitive. 75 * The internal has more options: outline_triangle and outline_quad 76 *can be seperated. But since this is not in spec, and more importantly, 77 *this is not so useful, so we don't need to keep this option. 78 */ 79 80 surfaceEvaluator.bgnmap2f( nuid ); 81 82 if(wiretris) 83 surfaceEvaluator.polymode(N_MESHLINE); 84 else 85 surfaceEvaluator.polymode(N_MESHFILL); 86 } 87 88 void 89 Backend::patch( REAL ulo, REAL uhi, REAL vlo, REAL vhi ) 90 { 91 surfaceEvaluator.domain2f( ulo, uhi, vlo, vhi ); 92 } 93 94 void 95 Backend::surfbbox( long type, REAL *from, REAL *to ) 96 { 97 surfaceEvaluator.range2f( type, from, to ); 98 } 99 100 /*------------------------------------------------------------------------- 101 * surfpts - pass a desription of a surface map 102 *------------------------------------------------------------------------- 103 */ 104 void 105 Backend::surfpts( 106 long type, /* geometry, color, texture, normal */ 107 REAL *pts, /* control points */ 108 long ustride, /* distance to next point in u direction */ 109 long vstride, /* distance to next point in v direction */ 110 int uorder, /* u parametric order */ 111 int vorder, /* v parametric order */ 112 REAL ulo, /* u lower bound */ 113 REAL uhi, /* u upper bound */ 114 REAL vlo, /* v lower bound */ 115 REAL vhi ) /* v upper bound */ 116 { 117 surfaceEvaluator.map2f( type,ulo,uhi,ustride,uorder,vlo,vhi,vstride,vorder,pts ); 118 surfaceEvaluator.enable( type ); 119 } 120 121 /*------------------------------------------------------------------------- 122 * surfgrid - define a lattice of points with origin and offset 123 *------------------------------------------------------------------------- 124 */ 125 void 126 Backend::surfgrid( REAL u0, REAL u1, long nu, REAL v0, REAL v1, long nv ) 127 { 128 surfaceEvaluator.mapgrid2f( nu, u0, u1, nv, v0, v1 ); 129 } 130 131 /*------------------------------------------------------------------------- 132 * surfmesh - evaluate a mesh of points on lattice 133 *------------------------------------------------------------------------- 134 */ 135 void 136 Backend::surfmesh( long u, long v, long n, long m ) 137 { 138 #ifndef NOWIREFRAME 139 if( wireframequads ) { 140 long v0, v1; 141 long u0f = u, u1f = u+n; 142 long v0f = v, v1f = v+m; 143 long parity = (u & 1); 144 145 for( v0 = v0f, v1 = v0f++ ; v0<v1f; v0 = v1, v1++ ) { 146 surfaceEvaluator.bgnline(); 147 for( long u = u0f; u<=u1f; u++ ) { 148 if( parity ) { 149 surfaceEvaluator.evalpoint2i( u, v0 ); 150 surfaceEvaluator.evalpoint2i( u, v1 ); 151 } else { 152 surfaceEvaluator.evalpoint2i( u, v1 ); 153 surfaceEvaluator.evalpoint2i( u, v0 ); 154 } 155 parity = 1 - parity; 156 } 157 surfaceEvaluator.endline(); 158 } 159 } else { 160 surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); 161 } 162 #else 163 if( wireframequads ) { 164 165 surfaceEvaluator.mapmesh2f( N_MESHLINE, u, u+n, v, v+m ); 166 } else { 167 168 surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); 169 } 170 #endif 171 } 172 173 /*------------------------------------------------------------------------- 174 * endsurf - postamble to surface 175 *------------------------------------------------------------------------- 176 */ 177 void 178 Backend::endsurf( void ) 179 { 180 surfaceEvaluator.endmap2f(); 181 } 182 183 /***************************************/ 184 void 185 Backend::bgntfan( void ) 186 { 187 surfaceEvaluator.bgntfan(); 188 /* 189 if(wireframetris) 190 surfaceEvaluator.polymode( N_MESHLINE ); 191 else 192 surfaceEvaluator.polymode( N_MESHFILL ); 193 */ 194 } 195 196 void 197 Backend::endtfan( void ) 198 { 199 surfaceEvaluator.endtfan(); 200 } 201 202 void 203 Backend::bgnqstrip( void ) 204 { 205 surfaceEvaluator.bgnqstrip(); 206 /* 207 if(wireframequads) 208 surfaceEvaluator.polymode( N_MESHLINE ); 209 else 210 surfaceEvaluator.polymode( N_MESHFILL ); 211 */ 212 } 213 214 void 215 Backend::endqstrip( void ) 216 { 217 surfaceEvaluator.endqstrip(); 218 } 219 220 void 221 Backend::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, 222 int n_lower, REAL v_lower, REAL* lower_val 223 ) 224 { 225 surfaceEvaluator.evalUStrip(n_upper, v_upper, upper_val, 226 n_lower, v_lower, lower_val); 227 } 228 229 void 230 Backend::evalVStrip(int n_left, REAL u_left, REAL* left_val, 231 int n_right, REAL u_right, REAL* right_val 232 ) 233 { 234 surfaceEvaluator.evalVStrip(n_left, u_left, left_val, 235 n_right, u_right, right_val); 236 } 237 238 /***************************************/ 239 240 241 /*------------------------------------------------------------------------- 242 * bgntmesh - preamble to a triangle mesh 243 *------------------------------------------------------------------------- 244 */ 245 void 246 Backend::bgntmesh( const char * ) 247 { 248 #ifndef NOWIREFRAME 249 250 meshindex = 0; /* I think these need to be initialized to zero */ 251 npts = 0; 252 253 if( !wireframetris ) { 254 surfaceEvaluator.bgntmesh(); 255 } 256 #else 257 258 if( wireframetris ) { 259 surfaceEvaluator.bgntmesh(); 260 surfaceEvaluator.polymode( N_MESHLINE ); 261 } else { 262 surfaceEvaluator.bgntmesh(); 263 surfaceEvaluator.polymode( N_MESHFILL ); 264 } 265 #endif 266 } 267 268 void 269 Backend::tmeshvert( GridTrimVertex *v ) 270 { 271 if( v->isGridVert() ) { 272 tmeshvert( v->g ); 273 } else { 274 tmeshvert( v->t ); 275 } 276 } 277 278 void 279 Backend::tmeshvertNOGE(TrimVertex *t) 280 { 281 // surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], temp, ttt); 282 #ifdef USE_OPTTT 283 surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], t->cache_point, t->cache_normal); 284 #endif 285 } 286 287 //opt for a line with the same u. 288 void 289 Backend::tmeshvertNOGE_BU(TrimVertex *t) 290 { 291 #ifdef USE_OPTTT 292 surfaceEvaluator.inDoEvalCoord2NOGE_BU( t->param[0], t->param[1], t->cache_point, t->cache_normal); 293 #endif 294 } 295 296 //opt for a line with the same v. 297 void 298 Backend::tmeshvertNOGE_BV(TrimVertex *t) 299 { 300 #ifdef USE_OPTTT 301 surfaceEvaluator.inDoEvalCoord2NOGE_BV( t->param[0], t->param[1], t->cache_point, t->cache_normal); 302 #endif 303 } 304 305 void 306 Backend::preEvaluateBU(REAL u) 307 { 308 surfaceEvaluator.inPreEvaluateBU_intfac(u); 309 } 310 311 void 312 Backend::preEvaluateBV(REAL v) 313 { 314 surfaceEvaluator.inPreEvaluateBV_intfac(v); 315 } 316 317 318 /*------------------------------------------------------------------------- 319 * tmeshvert - evaluate a point on a triangle mesh 320 *------------------------------------------------------------------------- 321 */ 322 void 323 Backend::tmeshvert( TrimVertex *t ) 324 { 325 326 #ifndef NOWIREFRAME 327 const long nuid = t->nuid; 328 #endif 329 const REAL u = t->param[0]; 330 const REAL v = t->param[1]; 331 332 #ifndef NOWIREFRAME 333 npts++; 334 if( wireframetris ) { 335 if( npts >= 3 ) { 336 surfaceEvaluator.bgnclosedline(); 337 if( mesh[0][2] == 0 ) 338 surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); 339 else 340 surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); 341 if( mesh[1][2] == 0 ) 342 surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); 343 else 344 surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); 345 surfaceEvaluator.evalcoord2f( nuid, u, v ); 346 surfaceEvaluator.endclosedline(); 347 } 348 mesh[meshindex][0] = u; 349 mesh[meshindex][1] = v; 350 mesh[meshindex][2] = 0; 351 mesh[meshindex][3] = nuid; 352 meshindex = (meshindex+1) % 2; 353 } else { 354 surfaceEvaluator.evalcoord2f( nuid, u, v ); 355 } 356 #else 357 358 surfaceEvaluator.evalcoord2f( 0, u, v ); 359 //for uninitial memory read surfaceEvaluator.evalcoord2f( nuid, u, v ); 360 #endif 361 } 362 363 //the same as tmeshvert(trimvertex), for efficiency purpose 364 void 365 Backend::tmeshvert( REAL u, REAL v ) 366 { 367 #ifndef NOWIREFRAME 368 const long nuid = 0; 369 370 npts++; 371 if( wireframetris ) { 372 if( npts >= 3 ) { 373 surfaceEvaluator.bgnclosedline(); 374 if( mesh[0][2] == 0 ) 375 surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); 376 else 377 surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); 378 if( mesh[1][2] == 0 ) 379 surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); 380 else 381 surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); 382 surfaceEvaluator.evalcoord2f( nuid, u, v ); 383 surfaceEvaluator.endclosedline(); 384 } 385 mesh[meshindex][0] = u; 386 mesh[meshindex][1] = v; 387 mesh[meshindex][2] = 0; 388 mesh[meshindex][3] = nuid; 389 meshindex = (meshindex+1) % 2; 390 } else { 391 surfaceEvaluator.evalcoord2f( nuid, u, v ); 392 } 393 #else 394 395 surfaceEvaluator.evalcoord2f( 0, u, v ); 396 #endif 397 } 398 399 /*------------------------------------------------------------------------- 400 * tmeshvert - evaluate a grid point of a triangle mesh 401 *------------------------------------------------------------------------- 402 */ 403 void 404 Backend::tmeshvert( GridVertex *g ) 405 { 406 const long u = g->gparam[0]; 407 const long v = g->gparam[1]; 408 409 #ifndef NOWIREFRAME 410 npts++; 411 if( wireframetris ) { 412 if( npts >= 3 ) { 413 surfaceEvaluator.bgnclosedline(); 414 if( mesh[0][2] == 0 ) 415 surfaceEvaluator.evalcoord2f( (long) mesh[0][3], mesh[0][0], mesh[0][1] ); 416 else 417 surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); 418 if( mesh[1][2] == 0 ) 419 surfaceEvaluator.evalcoord2f( (long) mesh[1][3], mesh[1][0], mesh[1][1] ); 420 else 421 surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); 422 surfaceEvaluator.evalpoint2i( u, v ); 423 surfaceEvaluator.endclosedline(); 424 } 425 mesh[meshindex][0] = u; 426 mesh[meshindex][1] = v; 427 mesh[meshindex][2] = 1; 428 meshindex = (meshindex+1) % 2; 429 } else { 430 surfaceEvaluator.evalpoint2i( u, v ); 431 } 432 #else 433 surfaceEvaluator.evalpoint2i( u, v ); 434 #endif 435 } 436 437 /*------------------------------------------------------------------------- 438 * swaptmesh - perform a swap of the triangle mesh pointers 439 *------------------------------------------------------------------------- 440 */ 441 void 442 Backend::swaptmesh( void ) 443 { 444 #ifndef NOWIREFRAME 445 if( wireframetris ) { 446 meshindex = 1 - meshindex; 447 } else { 448 surfaceEvaluator.swaptmesh(); 449 } 450 #else 451 surfaceEvaluator.swaptmesh(); 452 #endif 453 } 454 455 /*------------------------------------------------------------------------- 456 * endtmesh - postamble to triangle mesh 457 *------------------------------------------------------------------------- 458 */ 459 void 460 Backend::endtmesh( void ) 461 { 462 #ifndef NOWIREFRAME 463 if( ! wireframetris ) 464 surfaceEvaluator.endtmesh(); 465 #else 466 surfaceEvaluator.endtmesh(); 467 /* surfaceEvaluator.polymode( N_MESHFILL );*/ 468 #endif 469 } 470 471 472 /*------------------------------------------------------------------------- 473 * bgnoutline - preamble to outlined rendering 474 *------------------------------------------------------------------------- 475 */ 476 void 477 Backend::bgnoutline( void ) 478 { 479 surfaceEvaluator.bgnline(); 480 } 481 482 /*------------------------------------------------------------------------- 483 * linevert - evaluate a point on an outlined contour 484 *------------------------------------------------------------------------- 485 */ 486 void 487 Backend::linevert( TrimVertex *t ) 488 { 489 surfaceEvaluator.evalcoord2f( t->nuid, t->param[0], t->param[1] ); 490 } 491 492 /*------------------------------------------------------------------------- 493 * linevert - evaluate a grid point of an outlined contour 494 *------------------------------------------------------------------------- 495 */ 496 void 497 Backend::linevert( GridVertex *g ) 498 { 499 surfaceEvaluator.evalpoint2i( g->gparam[0], g->gparam[1] ); 500 } 501 502 /*------------------------------------------------------------------------- 503 * endoutline - postamble to outlined rendering 504 *------------------------------------------------------------------------- 505 */ 506 void 507 Backend::endoutline( void ) 508 { 509 surfaceEvaluator.endline(); 510 } 511 512 /*------------------------------------------------------------------------- 513 * triangle - output a triangle 514 *------------------------------------------------------------------------- 515 */ 516 void 517 Backend::triangle( TrimVertex *a, TrimVertex *b, TrimVertex *c ) 518 { 519 /* bgntmesh( "spittriangle" );*/ 520 bgntfan(); 521 tmeshvert( a ); 522 tmeshvert( b ); 523 tmeshvert( c ); 524 endtfan(); 525 /* endtmesh();*/ 526 } 527 528 void 529 Backend::bgncurv( void ) 530 { 531 curveEvaluator.bgnmap1f( 0 ); 532 } 533 534 void 535 Backend::segment( REAL ulo, REAL uhi ) 536 { 537 curveEvaluator.domain1f( ulo, uhi ); 538 } 539 540 void 541 Backend::curvpts( 542 long type, /* geometry, color, texture, normal */ 543 REAL *pts, /* control points */ 544 long stride, /* distance to next point */ 545 int order, /* parametric order */ 546 REAL ulo, /* lower parametric bound */ 547 REAL uhi ) /* upper parametric bound */ 548 549 { 550 curveEvaluator.map1f( type, ulo, uhi, stride, order, pts ); 551 curveEvaluator.enable( type ); 552 } 553 554 void 555 Backend::curvgrid( REAL u0, REAL u1, long nu ) 556 { 557 curveEvaluator.mapgrid1f( nu, u0, u1 ); 558 } 559 560 void 561 Backend::curvmesh( long from, long n ) 562 { 563 curveEvaluator.mapmesh1f( N_MESHFILL, from, from+n ); 564 } 565 566 void 567 Backend::curvpt(REAL u) 568 { 569 curveEvaluator.evalcoord1f( 0, u ); 570 } 571 572 void 573 Backend::bgnline( void ) 574 { 575 curveEvaluator.bgnline(); 576 } 577 578 void 579 Backend::endline( void ) 580 { 581 curveEvaluator.endline(); 582 } 583 584 void 585 Backend::endcurv( void ) 586 { 587 curveEvaluator.endmap1f(); 588 } 589