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 */ 57void 58Backend::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 88void 89Backend::patch( REAL ulo, REAL uhi, REAL vlo, REAL vhi ) 90{ 91 surfaceEvaluator.domain2f( ulo, uhi, vlo, vhi ); 92} 93 94void 95Backend::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 */ 104void 105Backend::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 */ 125void 126Backend::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 */ 135void 136Backend::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 */ 177void 178Backend::endsurf( void ) 179{ 180 surfaceEvaluator.endmap2f(); 181} 182 183/***************************************/ 184void 185Backend::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 196void 197Backend::endtfan( void ) 198{ 199 surfaceEvaluator.endtfan(); 200} 201 202void 203Backend::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 214void 215Backend::endqstrip( void ) 216{ 217 surfaceEvaluator.endqstrip(); 218} 219 220void 221Backend::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 229void 230Backend::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 */ 245void 246Backend::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 268void 269Backend::tmeshvert( GridTrimVertex *v ) 270{ 271 if( v->isGridVert() ) { 272 tmeshvert( v->g ); 273 } else { 274 tmeshvert( v->t ); 275 } 276} 277 278void 279Backend::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. 288void 289Backend::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. 297void 298Backend::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 305void 306Backend::preEvaluateBU(REAL u) 307{ 308 surfaceEvaluator.inPreEvaluateBU_intfac(u); 309} 310 311void 312Backend::preEvaluateBV(REAL v) 313{ 314 surfaceEvaluator.inPreEvaluateBV_intfac(v); 315} 316 317 318/*------------------------------------------------------------------------- 319 * tmeshvert - evaluate a point on a triangle mesh 320 *------------------------------------------------------------------------- 321 */ 322void 323Backend::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 364void 365Backend::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 */ 403void 404Backend::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 */ 441void 442Backend::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 */ 459void 460Backend::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 */ 476void 477Backend::bgnoutline( void ) 478{ 479 surfaceEvaluator.bgnline(); 480} 481 482/*------------------------------------------------------------------------- 483 * linevert - evaluate a point on an outlined contour 484 *------------------------------------------------------------------------- 485 */ 486void 487Backend::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 */ 496void 497Backend::linevert( GridVertex *g ) 498{ 499 surfaceEvaluator.evalpoint2i( g->gparam[0], g->gparam[1] ); 500} 501 502/*------------------------------------------------------------------------- 503 * endoutline - postamble to outlined rendering 504 *------------------------------------------------------------------------- 505 */ 506void 507Backend::endoutline( void ) 508{ 509 surfaceEvaluator.endline(); 510} 511 512/*------------------------------------------------------------------------- 513 * triangle - output a triangle 514 *------------------------------------------------------------------------- 515 */ 516void 517Backend::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 528void 529Backend::bgncurv( void ) 530{ 531 curveEvaluator.bgnmap1f( 0 ); 532} 533 534void 535Backend::segment( REAL ulo, REAL uhi ) 536{ 537 curveEvaluator.domain1f( ulo, uhi ); 538} 539 540void 541Backend::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 554void 555Backend::curvgrid( REAL u0, REAL u1, long nu ) 556{ 557 curveEvaluator.mapgrid1f( nu, u0, u1 ); 558} 559 560void 561Backend::curvmesh( long from, long n ) 562{ 563 curveEvaluator.mapmesh1f( N_MESHFILL, from, from+n ); 564} 565 566void 567Backend::curvpt(REAL u) 568{ 569 curveEvaluator.evalcoord1f( 0, u ); 570} 571 572void 573Backend::bgnline( void ) 574{ 575 curveEvaluator.bgnline(); 576} 577 578void 579Backend::endline( void ) 580{ 581 curveEvaluator.endline(); 582} 583 584void 585Backend::endcurv( void ) 586{ 587 curveEvaluator.endmap1f(); 588} 589