Home | History | Annotate | Line # | Download | only in internals
      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