1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg*/
34f220fa62Smrg
35f220fa62Smrg/*
36f220fa62Smrg * coveandtiler.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include "glimports.h"
41f220fa62Smrg#include "myassert.h"
42f220fa62Smrg#include "mystdio.h"
43f220fa62Smrg#include "coveandtiler.h"
44f220fa62Smrg#include "gridvertex.h"
45f220fa62Smrg#include "gridtrimvertex.h"
46f220fa62Smrg#include "uarray.h"
47f220fa62Smrg#include "backend.h"
48f220fa62Smrg
49f220fa62Smrg
50f220fa62Smrgconst int CoveAndTiler::MAXSTRIPSIZE = 1000;
51f220fa62Smrg
52f220fa62SmrgCoveAndTiler::CoveAndTiler( Backend& b )
53f220fa62Smrg	    : backend( b )
54f220fa62Smrg{ }
55f220fa62Smrg
56f220fa62SmrgCoveAndTiler::~CoveAndTiler( void )
57f220fa62Smrg{ }
58f220fa62Smrg
59f220fa62Smrginline void
60f220fa62SmrgCoveAndTiler::output( GridVertex &gv )
61f220fa62Smrg{
62f220fa62Smrg    backend.tmeshvert( &gv );
63f220fa62Smrg}
64f220fa62Smrg
65f220fa62Smrginline void
66f220fa62SmrgCoveAndTiler::output( TrimVertex *tv )
67f220fa62Smrg{
68f220fa62Smrg    backend.tmeshvert( tv );
69f220fa62Smrg}
70f220fa62Smrg
71f220fa62Smrginline void
72f220fa62SmrgCoveAndTiler::output( GridTrimVertex& g )
73f220fa62Smrg{
74f220fa62Smrg    backend.tmeshvert( &g );
75f220fa62Smrg}
76f220fa62Smrg
77f220fa62Smrgvoid
78f220fa62SmrgCoveAndTiler::coveAndTile( void )
79f220fa62Smrg{
80f220fa62Smrg    long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart;
81f220fa62Smrg    long uend	= (top.uend <= bot.uend)     ? top.uend   : bot.uend;
82f220fa62Smrg    if( ustart <= uend ) {
83f220fa62Smrg	tile( bot.vindex, ustart, uend );
84f220fa62Smrg	if( top.ustart >= bot.ustart )
85f220fa62Smrg	    coveUpperLeft();
86f220fa62Smrg	else
87f220fa62Smrg	    coveLowerLeft();
88f220fa62Smrg
89f220fa62Smrg	if( top.uend <= bot.uend )
90f220fa62Smrg	    coveUpperRight();
91f220fa62Smrg	else
92f220fa62Smrg	    coveLowerRight();
93f220fa62Smrg    } else {
94f220fa62Smrg	TrimVertex blv, tlv, *bl, *tl;
95f220fa62Smrg	GridTrimVertex bllv, tllv;
96f220fa62Smrg	TrimVertex *lf = left.first();
97f220fa62Smrg	TrimVertex *ll = left.last();
98f220fa62Smrg	if( lf->param[0] >= ll->param[0] ) {
99f220fa62Smrg	    blv.param[0] = lf->param[0];
100f220fa62Smrg	    blv.param[1] = ll->param[1];
101f220fa62Smrg	    blv.nuid = 0; // XXX
102f220fa62Smrg	    assert( blv.param[1] == bot.vval );
103f220fa62Smrg	    bl = &blv;
104f220fa62Smrg	    tl = lf;
105f220fa62Smrg	    tllv.set( lf );
106f220fa62Smrg	    if( ll->param[0] > uarray.uarray[top.ustart-1] ) {
107f220fa62Smrg		bllv.set( ll );
108f220fa62Smrg		assert( ll->param[0] <= uarray.uarray[bot.ustart] );
109f220fa62Smrg	    } else {
110f220fa62Smrg		bllv.set( top.ustart-1, bot.vindex );
111f220fa62Smrg	    }
112f220fa62Smrg	    coveUpperLeftNoGrid( bl );
113f220fa62Smrg	} else {
114f220fa62Smrg	    tlv.param[0] = ll->param[0];
115f220fa62Smrg	    tlv.param[1] = lf->param[1];
116f220fa62Smrg	    tlv.nuid = 0; // XXX
117f220fa62Smrg	    assert( tlv.param[1] == top.vval );
118f220fa62Smrg	    tl = &tlv;
119f220fa62Smrg	    bl = ll;
120f220fa62Smrg	    bllv.set( ll );
121f220fa62Smrg	    if( lf->param[0] > uarray.uarray[bot.ustart-1] ) {
122f220fa62Smrg		assert( lf->param[0] <= uarray.uarray[bot.ustart] );
123f220fa62Smrg		tllv.set( lf );
124f220fa62Smrg	    } else {
125f220fa62Smrg		tllv.set( bot.ustart-1, top.vindex );
126f220fa62Smrg	    }
127f220fa62Smrg	    coveLowerLeftNoGrid( tl );
128f220fa62Smrg	}
129f220fa62Smrg
130f220fa62Smrg	TrimVertex brv, trv, *br, *tr;
131f220fa62Smrg	GridTrimVertex brrv, trrv;
132f220fa62Smrg	TrimVertex *rf = right.first();
133f220fa62Smrg	TrimVertex *rl = right.last();
134f220fa62Smrg
135f220fa62Smrg	if( rf->param[0] <= rl->param[0] ) {
136f220fa62Smrg	    brv.param[0] = rf->param[0];
137f220fa62Smrg	    brv.param[1] = rl->param[1];
138f220fa62Smrg	    brv.nuid = 0; // XXX
139f220fa62Smrg	    assert( brv.param[1] == bot.vval );
140f220fa62Smrg	    br = &brv;
141f220fa62Smrg	    tr = rf;
142f220fa62Smrg	    trrv.set( rf );
143f220fa62Smrg	    if( rl->param[0] < uarray.uarray[top.uend+1] ) {
144f220fa62Smrg		assert( rl->param[0] >= uarray.uarray[top.uend] );
145f220fa62Smrg		brrv.set( rl );
146f220fa62Smrg	    } else {
147f220fa62Smrg		brrv.set( top.uend+1, bot.vindex );
148f220fa62Smrg	    }
149f220fa62Smrg	    coveUpperRightNoGrid( br );
150f220fa62Smrg	} else {
151f220fa62Smrg	    trv.param[0] = rl->param[0];
152f220fa62Smrg	    trv.param[1] = rf->param[1];
153f220fa62Smrg	    trv.nuid = 0; // XXX
154f220fa62Smrg	    assert( trv.param[1] == top.vval );
155f220fa62Smrg	    tr = &trv;
156f220fa62Smrg	    br = rl;
157f220fa62Smrg	    brrv.set( rl );
158f220fa62Smrg	    if( rf->param[0] < uarray.uarray[bot.uend+1] ) {
159f220fa62Smrg		assert( rf->param[0] >= uarray.uarray[bot.uend] );
160f220fa62Smrg		trrv.set( rf );
161f220fa62Smrg	    } else {
162f220fa62Smrg		trrv.set( bot.uend+1, top.vindex );
163f220fa62Smrg	    }
164f220fa62Smrg	    coveLowerRightNoGrid( tr );
165f220fa62Smrg	}
166f220fa62Smrg
167f220fa62Smrg	backend.bgntmesh( "doit" );
168f220fa62Smrg	output(trrv);
169f220fa62Smrg	output(tllv);
170f220fa62Smrg	output( tr );
171f220fa62Smrg	output( tl );
172f220fa62Smrg	output( br );
173f220fa62Smrg	output( bl );
174f220fa62Smrg	output(brrv);
175f220fa62Smrg	output(bllv);
176f220fa62Smrg	backend.endtmesh();
177f220fa62Smrg    }
178f220fa62Smrg}
179f220fa62Smrg
180f220fa62Smrgvoid
181f220fa62SmrgCoveAndTiler::tile( long vindex, long ustart, long uend )
182f220fa62Smrg{
183f220fa62Smrg    long numsteps = uend - ustart;
184f220fa62Smrg
185f220fa62Smrg    if( numsteps == 0 ) return;
186f220fa62Smrg
187f220fa62Smrg    if( numsteps > MAXSTRIPSIZE ) {
188f220fa62Smrg	long umid = ustart + (uend - ustart) / 2;
189f220fa62Smrg	tile( vindex, ustart, umid );
190f220fa62Smrg	tile( vindex, umid, uend );
191f220fa62Smrg    } else {
192f220fa62Smrg	backend.surfmesh( ustart, vindex-1, numsteps, 1 );
193f220fa62Smrg    }
194f220fa62Smrg}
195f220fa62Smrg
196f220fa62Smrgvoid
197f220fa62SmrgCoveAndTiler::coveUpperRight( void )
198f220fa62Smrg{
199f220fa62Smrg    GridVertex tgv( top.uend, top.vindex );
200f220fa62Smrg    GridVertex gv( top.uend, bot.vindex );
201f220fa62Smrg
202f220fa62Smrg    right.first();
203f220fa62Smrg    backend.bgntmesh( "coveUpperRight" );
204f220fa62Smrg    output( right.next() );
205f220fa62Smrg    output( tgv );
206f220fa62Smrg    backend.swaptmesh();
207f220fa62Smrg    output( gv );
208f220fa62Smrg	coveUR();
209f220fa62Smrg    backend.endtmesh();
210f220fa62Smrg}
211f220fa62Smrg
212f220fa62Smrgvoid
213f220fa62SmrgCoveAndTiler::coveUpperRightNoGrid( TrimVertex* br )
214f220fa62Smrg{
215f220fa62Smrg    backend.bgntmesh( "coveUpperRight" );
216f220fa62Smrg    output( right.first() );
217f220fa62Smrg    output( right.next() );
218f220fa62Smrg    backend.swaptmesh();
219f220fa62Smrg    output( br );
220f220fa62Smrg	coveUR();
221f220fa62Smrg    backend.endtmesh();
222f220fa62Smrg}
223f220fa62Smrg
224f220fa62Smrgvoid
225f220fa62SmrgCoveAndTiler::coveUR( )
226f220fa62Smrg{
227f220fa62Smrg    GridVertex gv( top.uend, bot.vindex );
228f220fa62Smrg    TrimVertex *vert = right.next();
229f220fa62Smrg    if( vert == NULL ) return;
230f220fa62Smrg
231f220fa62Smrg    assert( vert->param[0] >= uarray.uarray[gv.gparam[0]]  );
232f220fa62Smrg
233f220fa62Smrg    if( gv.nextu() >= bot.uend ) {
234f220fa62Smrg	for( ; vert; vert = right.next() ) {
235f220fa62Smrg	    output( vert );
236f220fa62Smrg	    backend.swaptmesh();
237f220fa62Smrg	}
238f220fa62Smrg    } else while( 1 ) {
239f220fa62Smrg	if( vert->param[0] < uarray.uarray[gv.gparam[0]]  ) {
240f220fa62Smrg	    output( vert );
241f220fa62Smrg	    backend.swaptmesh();
242f220fa62Smrg	    vert = right.next();
243f220fa62Smrg	    if( vert == NULL ) break;
244f220fa62Smrg	} else {
245f220fa62Smrg	    backend.swaptmesh();
246f220fa62Smrg	    output( gv );
247f220fa62Smrg	    if( gv.nextu() == bot.uend ) {
248f220fa62Smrg		for( ; vert; vert = right.next() ) {
249f220fa62Smrg		    output( vert );
250f220fa62Smrg		    backend.swaptmesh();
251f220fa62Smrg		}
252f220fa62Smrg		break;
253f220fa62Smrg	    }
254f220fa62Smrg	}
255f220fa62Smrg    }
256f220fa62Smrg}
257f220fa62Smrg
258f220fa62Smrgvoid
259f220fa62SmrgCoveAndTiler::coveUpperLeft( void )
260f220fa62Smrg{
261f220fa62Smrg    GridVertex tgv( top.ustart, top.vindex );
262f220fa62Smrg    GridVertex gv( top.ustart, bot.vindex );
263f220fa62Smrg
264f220fa62Smrg    left.first();
265f220fa62Smrg    backend.bgntmesh( "coveUpperLeft" );
266f220fa62Smrg    output( tgv );
267f220fa62Smrg    output( left.next() );
268f220fa62Smrg    output( gv );
269f220fa62Smrg    backend.swaptmesh();
270f220fa62Smrg	coveUL();
271f220fa62Smrg    backend.endtmesh();
272f220fa62Smrg}
273f220fa62Smrg
274f220fa62Smrgvoid
275f220fa62SmrgCoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl )
276f220fa62Smrg{
277f220fa62Smrg    backend.bgntmesh( "coveUpperLeftNoGrid" );
278f220fa62Smrg    output( left.first() );
279f220fa62Smrg    output( left.next() );
280f220fa62Smrg    output( bl );
281f220fa62Smrg    backend.swaptmesh();
282f220fa62Smrg	coveUL();
283f220fa62Smrg    backend.endtmesh();
284f220fa62Smrg}
285f220fa62Smrg
286f220fa62Smrgvoid
287f220fa62SmrgCoveAndTiler::coveUL()
288f220fa62Smrg{
289f220fa62Smrg    GridVertex gv( top.ustart, bot.vindex );
290f220fa62Smrg    TrimVertex *vert = left.next();
291f220fa62Smrg    if( vert == NULL ) return;
292f220fa62Smrg    assert( vert->param[0] <= uarray.uarray[gv.gparam[0]]  );
293f220fa62Smrg
294f220fa62Smrg    if( gv.prevu() <= bot.ustart ) {
295f220fa62Smrg	for( ; vert; vert = left.next() ) {
296f220fa62Smrg	    backend.swaptmesh();
297f220fa62Smrg	    output( vert );
298f220fa62Smrg	}
299f220fa62Smrg    } else while( 1 ) {
300f220fa62Smrg	if( vert->param[0] > uarray.uarray[gv.gparam[0]]  ) {
301f220fa62Smrg	    backend.swaptmesh();
302f220fa62Smrg	    output( vert );
303f220fa62Smrg	    vert = left.next();
304f220fa62Smrg	    if( vert == NULL ) break;
305f220fa62Smrg	} else {
306f220fa62Smrg	    output( gv );
307f220fa62Smrg	    backend.swaptmesh();
308f220fa62Smrg	    if( gv.prevu() == bot.ustart ) {
309f220fa62Smrg		for( ; vert; vert = left.next() ) {
310f220fa62Smrg		    backend.swaptmesh();
311f220fa62Smrg		    output( vert );
312f220fa62Smrg		}
313f220fa62Smrg		break;
314f220fa62Smrg	    }
315f220fa62Smrg	}
316f220fa62Smrg    }
317f220fa62Smrg}
318f220fa62Smrg
319f220fa62Smrgvoid
320f220fa62SmrgCoveAndTiler::coveLowerLeft( void )
321f220fa62Smrg{
322f220fa62Smrg    GridVertex bgv( bot.ustart, bot.vindex );
323f220fa62Smrg    GridVertex gv( bot.ustart, top.vindex );
324f220fa62Smrg
325f220fa62Smrg    left.last();
326f220fa62Smrg    backend.bgntmesh( "coveLowerLeft" );
327f220fa62Smrg    output( left.prev() );
328f220fa62Smrg    output( bgv );
329f220fa62Smrg    backend.swaptmesh();
330f220fa62Smrg    output( gv );
331f220fa62Smrg	coveLL();
332f220fa62Smrg    backend.endtmesh();
333f220fa62Smrg}
334f220fa62Smrg
335f220fa62Smrgvoid
336f220fa62SmrgCoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl )
337f220fa62Smrg{
338f220fa62Smrg    backend.bgntmesh( "coveLowerLeft" );
339f220fa62Smrg    output( left.last() );
340f220fa62Smrg    output( left.prev() );
341f220fa62Smrg    backend.swaptmesh();
342f220fa62Smrg    output( tl );
343f220fa62Smrg	coveLL( );
344f220fa62Smrg    backend.endtmesh();
345f220fa62Smrg}
346f220fa62Smrg
347f220fa62Smrgvoid
348f220fa62SmrgCoveAndTiler::coveLL()
349f220fa62Smrg{
350f220fa62Smrg    GridVertex gv( bot.ustart, top.vindex );
351f220fa62Smrg    TrimVertex *vert = left.prev();
352f220fa62Smrg    if( vert == NULL ) return;
353f220fa62Smrg    assert( vert->param[0] <= uarray.uarray[gv.gparam[0]]  );
354f220fa62Smrg
355f220fa62Smrg    if( gv.prevu() <= top.ustart ) {
356f220fa62Smrg	for( ; vert; vert = left.prev() ) {
357f220fa62Smrg	    output( vert );
358f220fa62Smrg	    backend.swaptmesh();
359f220fa62Smrg	}
360f220fa62Smrg    } else while( 1 ) {
361f220fa62Smrg	if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){
362f220fa62Smrg	    output( vert );
363f220fa62Smrg	    backend.swaptmesh();
364f220fa62Smrg	    vert = left.prev();
365f220fa62Smrg	    if( vert == NULL ) break;
366f220fa62Smrg	} else {
367f220fa62Smrg	    backend.swaptmesh();
368f220fa62Smrg	    output( gv );
369f220fa62Smrg	    if( gv.prevu() == top.ustart ) {
370f220fa62Smrg		for( ; vert; vert = left.prev() ) {
371f220fa62Smrg		    output( vert );
372f220fa62Smrg		    backend.swaptmesh();
373f220fa62Smrg		}
374f220fa62Smrg		break;
375f220fa62Smrg	    }
376f220fa62Smrg	}
377f220fa62Smrg    }
378f220fa62Smrg}
379f220fa62Smrg
380f220fa62Smrgvoid
381f220fa62SmrgCoveAndTiler::coveLowerRight( void )
382f220fa62Smrg{
383f220fa62Smrg    GridVertex bgv( bot.uend, bot.vindex );
384f220fa62Smrg    GridVertex gv( bot.uend, top.vindex );
385f220fa62Smrg
386f220fa62Smrg    right.last();
387f220fa62Smrg    backend.bgntmesh( "coveLowerRight" );
388f220fa62Smrg    output( bgv );
389f220fa62Smrg    output( right.prev() );
390f220fa62Smrg    output( gv );
391f220fa62Smrg    backend.swaptmesh();
392f220fa62Smrg	coveLR();
393f220fa62Smrg    backend.endtmesh( );
394f220fa62Smrg}
395f220fa62Smrg
396f220fa62Smrgvoid
397f220fa62SmrgCoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr )
398f220fa62Smrg{
399f220fa62Smrg    backend.bgntmesh( "coveLowerRIght" );
400f220fa62Smrg    output( right.last() );
401f220fa62Smrg    output( right.prev() );
402f220fa62Smrg    output( tr );
403f220fa62Smrg    backend.swaptmesh();
404f220fa62Smrg	coveLR();
405f220fa62Smrg    backend.endtmesh();
406f220fa62Smrg}
407f220fa62Smrg
408f220fa62Smrgvoid
409f220fa62SmrgCoveAndTiler::coveLR( )
410f220fa62Smrg{
411f220fa62Smrg    GridVertex gv( bot.uend, top.vindex );
412f220fa62Smrg    TrimVertex *vert = right.prev();
413f220fa62Smrg    if( vert == NULL ) return;
414f220fa62Smrg    assert( vert->param[0] >= uarray.uarray[gv.gparam[0]]  );
415f220fa62Smrg
416f220fa62Smrg    if( gv.nextu() >= top.uend ) {
417f220fa62Smrg	for( ; vert; vert = right.prev() ) {
418f220fa62Smrg	    backend.swaptmesh();
419f220fa62Smrg	    output( vert );
420f220fa62Smrg	}
421f220fa62Smrg    } else while( 1 ) {
422f220fa62Smrg	if( vert->param[0] < uarray.uarray[gv.gparam[0]]  ) {
423f220fa62Smrg	    backend.swaptmesh();
424f220fa62Smrg	    output( vert );
425f220fa62Smrg	    vert = right.prev();
426f220fa62Smrg	    if( vert == NULL ) break;
427f220fa62Smrg	} else {
428f220fa62Smrg	    output( gv );
429f220fa62Smrg	    backend.swaptmesh();
430f220fa62Smrg	    if( gv.nextu() == top.uend ) {
431f220fa62Smrg		for( ; vert; vert = right.prev() ) {
432f220fa62Smrg		    backend.swaptmesh();
433f220fa62Smrg		    output( vert );
434f220fa62Smrg		}
435f220fa62Smrg		break;
436f220fa62Smrg	    }
437f220fa62Smrg	}
438f220fa62Smrg    }
439f220fa62Smrg}
440f220fa62Smrg
441