| /* |
| ** License Applicability. Except to the extent portions of this file are |
| ** made subject to an alternative license as permitted in the SGI Free |
| ** Software License B, Version 1.1 (the "License"), the contents of this |
| ** file are subject only to the provisions of the License. You may not use |
| ** this file except in compliance with the License. You may obtain a copy |
| ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 |
| ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: |
| ** |
| ** http://oss.sgi.com/projects/FreeB |
| ** |
| ** Note that, as provided in the License, the Software is distributed on an |
| ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS |
| ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND |
| ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A |
| ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. |
| ** |
| ** Original Code. The Original Code is: OpenGL Sample Implementation, |
| ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, |
| ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. |
| ** Copyright in any portions created by third parties is as indicated |
| ** elsewhere herein. All Rights Reserved. |
| ** |
| ** Additional Notice Provisions: The application programming interfaces |
| ** established by SGI in conjunction with the Original Code are The |
| ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released |
| ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version |
| ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X |
| ** Window System(R) (Version 1.3), released October 19, 1998. This software |
| ** was created using the OpenGL(R) version 1.2.1 Sample Implementation |
| ** published by SGI, but has not been independently verified as being |
| ** compliant with the OpenGL(R) version 1.2.1 Specification. |
| */ |
| |
| /* |
| * backend.c++ |
| * |
| * $Date: 2012/03/29 17:22:17 $ $Revision: 1.1.1.1 $ |
| * $Header: /cvs/bao-parsec/pkgs/libs/mesa/src/src/glu/sgi/libnurbs/internals/backend.cc,v 1.1.1.1 2012/03/29 17:22:17 uid42307 Exp $ |
| */ |
| |
| /* Bezier surface backend |
| - interprets display mode (wireframe,shaded,...) |
| */ |
| #include <stdio.h> |
| #include "glimports.h" |
| #include "mystdio.h" |
| #include "backend.h" |
| #include "basiccrveval.h" |
| #include "basicsurfeval.h" |
| #include "nurbsconsts.h" |
| |
| #define NOWIREFRAME |
| |
| |
| /*------------------------------------------------------------------------- |
| * bgnsurf - preamble to surface definition and evaluations |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::bgnsurf( int wiretris, int wirequads, long nuid ) |
| { |
| /*#ifndef NOWIREFRAME*/ //need this for old version |
| wireframetris = wiretris; |
| wireframequads = wirequads; |
| /*#endif*/ |
| |
| /*in the spec, GLU_DISPLAY_MODE is either |
| * GLU_FILL |
| * GLU_OUTLINE_POLY |
| * GLU_OUTLINE_PATCH. |
| *In fact, GLU_FLL is has the same effect as |
| * set GL_FRONT_AND_BACK to be GL_FILL |
| * and GLU_OUTLINE_POLY is the same as set |
| * GL_FRONT_AND_BACK to be GL_LINE |
| *It is more efficient to do this once at the beginning of |
| *each surface than to do it for each primitive. |
| * The internal has more options: outline_triangle and outline_quad |
| *can be seperated. But since this is not in spec, and more importantly, |
| *this is not so useful, so we don't need to keep this option. |
| */ |
| |
| surfaceEvaluator.bgnmap2f( nuid ); |
| |
| if(wiretris) |
| surfaceEvaluator.polymode(N_MESHLINE); |
| else |
| surfaceEvaluator.polymode(N_MESHFILL); |
| } |
| |
| void |
| Backend::patch( REAL ulo, REAL uhi, REAL vlo, REAL vhi ) |
| { |
| surfaceEvaluator.domain2f( ulo, uhi, vlo, vhi ); |
| } |
| |
| void |
| Backend::surfbbox( long type, REAL *from, REAL *to ) |
| { |
| surfaceEvaluator.range2f( type, from, to ); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * surfpts - pass a desription of a surface map |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::surfpts( |
| long type, /* geometry, color, texture, normal */ |
| REAL *pts, /* control points */ |
| long ustride, /* distance to next point in u direction */ |
| long vstride, /* distance to next point in v direction */ |
| int uorder, /* u parametric order */ |
| int vorder, /* v parametric order */ |
| REAL ulo, /* u lower bound */ |
| REAL uhi, /* u upper bound */ |
| REAL vlo, /* v lower bound */ |
| REAL vhi ) /* v upper bound */ |
| { |
| surfaceEvaluator.map2f( type,ulo,uhi,ustride,uorder,vlo,vhi,vstride,vorder,pts ); |
| surfaceEvaluator.enable( type ); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * surfgrid - define a lattice of points with origin and offset |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::surfgrid( REAL u0, REAL u1, long nu, REAL v0, REAL v1, long nv ) |
| { |
| surfaceEvaluator.mapgrid2f( nu, u0, u1, nv, v0, v1 ); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * surfmesh - evaluate a mesh of points on lattice |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::surfmesh( long u, long v, long n, long m ) |
| { |
| #ifndef NOWIREFRAME |
| if( wireframequads ) { |
| long v0, v1; |
| long u0f = u, u1f = u+n; |
| long v0f = v, v1f = v+m; |
| long parity = (u & 1); |
| |
| for( v0 = v0f, v1 = v0f++ ; v0<v1f; v0 = v1, v1++ ) { |
| surfaceEvaluator.bgnline(); |
| for( long u = u0f; u<=u1f; u++ ) { |
| if( parity ) { |
| surfaceEvaluator.evalpoint2i( u, v0 ); |
| surfaceEvaluator.evalpoint2i( u, v1 ); |
| } else { |
| surfaceEvaluator.evalpoint2i( u, v1 ); |
| surfaceEvaluator.evalpoint2i( u, v0 ); |
| } |
| parity = 1 - parity; |
| } |
| surfaceEvaluator.endline(); |
| } |
| } else { |
| surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); |
| } |
| #else |
| if( wireframequads ) { |
| |
| surfaceEvaluator.mapmesh2f( N_MESHLINE, u, u+n, v, v+m ); |
| } else { |
| |
| surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); |
| } |
| #endif |
| } |
| |
| /*------------------------------------------------------------------------- |
| * endsurf - postamble to surface |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::endsurf( void ) |
| { |
| surfaceEvaluator.endmap2f(); |
| } |
| |
| /***************************************/ |
| void |
| Backend::bgntfan( void ) |
| { |
| surfaceEvaluator.bgntfan(); |
| /* |
| if(wireframetris) |
| surfaceEvaluator.polymode( N_MESHLINE ); |
| else |
| surfaceEvaluator.polymode( N_MESHFILL ); |
| */ |
| } |
| |
| void |
| Backend::endtfan( void ) |
| { |
| surfaceEvaluator.endtfan(); |
| } |
| |
| void |
| Backend::bgnqstrip( void ) |
| { |
| surfaceEvaluator.bgnqstrip(); |
| /* |
| if(wireframequads) |
| surfaceEvaluator.polymode( N_MESHLINE ); |
| else |
| surfaceEvaluator.polymode( N_MESHFILL ); |
| */ |
| } |
| |
| void |
| Backend::endqstrip( void ) |
| { |
| surfaceEvaluator.endqstrip(); |
| } |
| |
| void |
| Backend::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, |
| int n_lower, REAL v_lower, REAL* lower_val |
| ) |
| { |
| surfaceEvaluator.evalUStrip(n_upper, v_upper, upper_val, |
| n_lower, v_lower, lower_val); |
| } |
| |
| void |
| Backend::evalVStrip(int n_left, REAL u_left, REAL* left_val, |
| int n_right, REAL u_right, REAL* right_val |
| ) |
| { |
| surfaceEvaluator.evalVStrip(n_left, u_left, left_val, |
| n_right, u_right, right_val); |
| } |
| |
| /***************************************/ |
| |
| |
| /*------------------------------------------------------------------------- |
| * bgntmesh - preamble to a triangle mesh |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::bgntmesh( const char * ) |
| { |
| #ifndef NOWIREFRAME |
| |
| meshindex = 0; /* I think these need to be initialized to zero */ |
| npts = 0; |
| |
| if( !wireframetris ) { |
| surfaceEvaluator.bgntmesh(); |
| } |
| #else |
| |
| if( wireframetris ) { |
| surfaceEvaluator.bgntmesh(); |
| surfaceEvaluator.polymode( N_MESHLINE ); |
| } else { |
| surfaceEvaluator.bgntmesh(); |
| surfaceEvaluator.polymode( N_MESHFILL ); |
| } |
| #endif |
| } |
| |
| void |
| Backend::tmeshvert( GridTrimVertex *v ) |
| { |
| if( v->isGridVert() ) { |
| tmeshvert( v->g ); |
| } else { |
| tmeshvert( v->t ); |
| } |
| } |
| |
| void |
| Backend::tmeshvertNOGE(TrimVertex *t) |
| { |
| // surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], temp, ttt); |
| #ifdef USE_OPTTT |
| surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], t->cache_point, t->cache_normal); |
| #endif |
| } |
| |
| //opt for a line with the same u. |
| void |
| Backend::tmeshvertNOGE_BU(TrimVertex *t) |
| { |
| #ifdef USE_OPTTT |
| surfaceEvaluator.inDoEvalCoord2NOGE_BU( t->param[0], t->param[1], t->cache_point, t->cache_normal); |
| #endif |
| } |
| |
| //opt for a line with the same v. |
| void |
| Backend::tmeshvertNOGE_BV(TrimVertex *t) |
| { |
| #ifdef USE_OPTTT |
| surfaceEvaluator.inDoEvalCoord2NOGE_BV( t->param[0], t->param[1], t->cache_point, t->cache_normal); |
| #endif |
| } |
| |
| void |
| Backend::preEvaluateBU(REAL u) |
| { |
| surfaceEvaluator.inPreEvaluateBU_intfac(u); |
| } |
| |
| void |
| Backend::preEvaluateBV(REAL v) |
| { |
| surfaceEvaluator.inPreEvaluateBV_intfac(v); |
| } |
| |
| |
| /*------------------------------------------------------------------------- |
| * tmeshvert - evaluate a point on a triangle mesh |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::tmeshvert( TrimVertex *t ) |
| { |
| |
| #ifndef NOWIREFRAME |
| const long nuid = t->nuid; |
| #endif |
| const REAL u = t->param[0]; |
| const REAL v = t->param[1]; |
| |
| #ifndef NOWIREFRAME |
| npts++; |
| if( wireframetris ) { |
| if( npts >= 3 ) { |
| surfaceEvaluator.bgnclosedline(); |
| if( mesh[0][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); |
| if( mesh[1][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); |
| surfaceEvaluator.evalcoord2f( nuid, u, v ); |
| surfaceEvaluator.endclosedline(); |
| } |
| mesh[meshindex][0] = u; |
| mesh[meshindex][1] = v; |
| mesh[meshindex][2] = 0; |
| mesh[meshindex][3] = nuid; |
| meshindex = (meshindex+1) % 2; |
| } else { |
| surfaceEvaluator.evalcoord2f( nuid, u, v ); |
| } |
| #else |
| |
| surfaceEvaluator.evalcoord2f( 0, u, v ); |
| //for uninitial memory read surfaceEvaluator.evalcoord2f( nuid, u, v ); |
| #endif |
| } |
| |
| //the same as tmeshvert(trimvertex), for efficiency purpose |
| void |
| Backend::tmeshvert( REAL u, REAL v ) |
| { |
| #ifndef NOWIREFRAME |
| const long nuid = 0; |
| |
| npts++; |
| if( wireframetris ) { |
| if( npts >= 3 ) { |
| surfaceEvaluator.bgnclosedline(); |
| if( mesh[0][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); |
| if( mesh[1][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); |
| surfaceEvaluator.evalcoord2f( nuid, u, v ); |
| surfaceEvaluator.endclosedline(); |
| } |
| mesh[meshindex][0] = u; |
| mesh[meshindex][1] = v; |
| mesh[meshindex][2] = 0; |
| mesh[meshindex][3] = nuid; |
| meshindex = (meshindex+1) % 2; |
| } else { |
| surfaceEvaluator.evalcoord2f( nuid, u, v ); |
| } |
| #else |
| |
| surfaceEvaluator.evalcoord2f( 0, u, v ); |
| #endif |
| } |
| |
| /*------------------------------------------------------------------------- |
| * tmeshvert - evaluate a grid point of a triangle mesh |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::tmeshvert( GridVertex *g ) |
| { |
| const long u = g->gparam[0]; |
| const long v = g->gparam[1]; |
| |
| #ifndef NOWIREFRAME |
| npts++; |
| if( wireframetris ) { |
| if( npts >= 3 ) { |
| surfaceEvaluator.bgnclosedline(); |
| if( mesh[0][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( (long) mesh[0][3], mesh[0][0], mesh[0][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); |
| if( mesh[1][2] == 0 ) |
| surfaceEvaluator.evalcoord2f( (long) mesh[1][3], mesh[1][0], mesh[1][1] ); |
| else |
| surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); |
| surfaceEvaluator.evalpoint2i( u, v ); |
| surfaceEvaluator.endclosedline(); |
| } |
| mesh[meshindex][0] = u; |
| mesh[meshindex][1] = v; |
| mesh[meshindex][2] = 1; |
| meshindex = (meshindex+1) % 2; |
| } else { |
| surfaceEvaluator.evalpoint2i( u, v ); |
| } |
| #else |
| surfaceEvaluator.evalpoint2i( u, v ); |
| #endif |
| } |
| |
| /*------------------------------------------------------------------------- |
| * swaptmesh - perform a swap of the triangle mesh pointers |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::swaptmesh( void ) |
| { |
| #ifndef NOWIREFRAME |
| if( wireframetris ) { |
| meshindex = 1 - meshindex; |
| } else { |
| surfaceEvaluator.swaptmesh(); |
| } |
| #else |
| surfaceEvaluator.swaptmesh(); |
| #endif |
| } |
| |
| /*------------------------------------------------------------------------- |
| * endtmesh - postamble to triangle mesh |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::endtmesh( void ) |
| { |
| #ifndef NOWIREFRAME |
| if( ! wireframetris ) |
| surfaceEvaluator.endtmesh(); |
| #else |
| surfaceEvaluator.endtmesh(); |
| /* surfaceEvaluator.polymode( N_MESHFILL );*/ |
| #endif |
| } |
| |
| |
| /*------------------------------------------------------------------------- |
| * bgnoutline - preamble to outlined rendering |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::bgnoutline( void ) |
| { |
| surfaceEvaluator.bgnline(); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * linevert - evaluate a point on an outlined contour |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::linevert( TrimVertex *t ) |
| { |
| surfaceEvaluator.evalcoord2f( t->nuid, t->param[0], t->param[1] ); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * linevert - evaluate a grid point of an outlined contour |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::linevert( GridVertex *g ) |
| { |
| surfaceEvaluator.evalpoint2i( g->gparam[0], g->gparam[1] ); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * endoutline - postamble to outlined rendering |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::endoutline( void ) |
| { |
| surfaceEvaluator.endline(); |
| } |
| |
| /*------------------------------------------------------------------------- |
| * triangle - output a triangle |
| *------------------------------------------------------------------------- |
| */ |
| void |
| Backend::triangle( TrimVertex *a, TrimVertex *b, TrimVertex *c ) |
| { |
| /* bgntmesh( "spittriangle" );*/ |
| bgntfan(); |
| tmeshvert( a ); |
| tmeshvert( b ); |
| tmeshvert( c ); |
| endtfan(); |
| /* endtmesh();*/ |
| } |
| |
| void |
| Backend::bgncurv( void ) |
| { |
| curveEvaluator.bgnmap1f( 0 ); |
| } |
| |
| void |
| Backend::segment( REAL ulo, REAL uhi ) |
| { |
| curveEvaluator.domain1f( ulo, uhi ); |
| } |
| |
| void |
| Backend::curvpts( |
| long type, /* geometry, color, texture, normal */ |
| REAL *pts, /* control points */ |
| long stride, /* distance to next point */ |
| int order, /* parametric order */ |
| REAL ulo, /* lower parametric bound */ |
| REAL uhi ) /* upper parametric bound */ |
| |
| { |
| curveEvaluator.map1f( type, ulo, uhi, stride, order, pts ); |
| curveEvaluator.enable( type ); |
| } |
| |
| void |
| Backend::curvgrid( REAL u0, REAL u1, long nu ) |
| { |
| curveEvaluator.mapgrid1f( nu, u0, u1 ); |
| } |
| |
| void |
| Backend::curvmesh( long from, long n ) |
| { |
| curveEvaluator.mapmesh1f( N_MESHFILL, from, from+n ); |
| } |
| |
| void |
| Backend::curvpt(REAL u) |
| { |
| curveEvaluator.evalcoord1f( 0, u ); |
| } |
| |
| void |
| Backend::bgnline( void ) |
| { |
| curveEvaluator.bgnline(); |
| } |
| |
| void |
| Backend::endline( void ) |
| { |
| curveEvaluator.endline(); |
| } |
| |
| void |
| Backend::endcurv( void ) |
| { |
| curveEvaluator.endmap1f(); |
| } |