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