[WIN32SS/USER32]
[reactos.git] / dll / opengl / mesa / src / glu / sgi / libnurbs / internals / coveandtiler.cc
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 * coveandtiler.c++
37 *
38 */
39
40 #include "glimports.h"
41 #include "myassert.h"
42 #include "mystdio.h"
43 #include "coveandtiler.h"
44 #include "gridvertex.h"
45 #include "gridtrimvertex.h"
46 #include "uarray.h"
47 #include "backend.h"
48
49
50 const int CoveAndTiler::MAXSTRIPSIZE = 1000;
51
52 CoveAndTiler::CoveAndTiler( Backend& b )
53 : backend( b )
54 { }
55
56 CoveAndTiler::~CoveAndTiler( void )
57 { }
58
59 inline void
60 CoveAndTiler::output( GridVertex &gv )
61 {
62 backend.tmeshvert( &gv );
63 }
64
65 inline void
66 CoveAndTiler::output( TrimVertex *tv )
67 {
68 backend.tmeshvert( tv );
69 }
70
71 inline void
72 CoveAndTiler::output( GridTrimVertex& g )
73 {
74 backend.tmeshvert( &g );
75 }
76
77 void
78 CoveAndTiler::coveAndTile( void )
79 {
80 long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart;
81 long uend = (top.uend <= bot.uend) ? top.uend : bot.uend;
82 if( ustart <= uend ) {
83 tile( bot.vindex, ustart, uend );
84 if( top.ustart >= bot.ustart )
85 coveUpperLeft();
86 else
87 coveLowerLeft();
88
89 if( top.uend <= bot.uend )
90 coveUpperRight();
91 else
92 coveLowerRight();
93 } else {
94 TrimVertex blv, tlv, *bl, *tl;
95 GridTrimVertex bllv, tllv;
96 TrimVertex *lf = left.first();
97 TrimVertex *ll = left.last();
98 if( lf->param[0] >= ll->param[0] ) {
99 blv.param[0] = lf->param[0];
100 blv.param[1] = ll->param[1];
101 blv.nuid = 0; // XXX
102 assert( blv.param[1] == bot.vval );
103 bl = &blv;
104 tl = lf;
105 tllv.set( lf );
106 if( ll->param[0] > uarray.uarray[top.ustart-1] ) {
107 bllv.set( ll );
108 assert( ll->param[0] <= uarray.uarray[bot.ustart] );
109 } else {
110 bllv.set( top.ustart-1, bot.vindex );
111 }
112 coveUpperLeftNoGrid( bl );
113 } else {
114 tlv.param[0] = ll->param[0];
115 tlv.param[1] = lf->param[1];
116 tlv.nuid = 0; // XXX
117 assert( tlv.param[1] == top.vval );
118 tl = &tlv;
119 bl = ll;
120 bllv.set( ll );
121 if( lf->param[0] > uarray.uarray[bot.ustart-1] ) {
122 assert( lf->param[0] <= uarray.uarray[bot.ustart] );
123 tllv.set( lf );
124 } else {
125 tllv.set( bot.ustart-1, top.vindex );
126 }
127 coveLowerLeftNoGrid( tl );
128 }
129
130 TrimVertex brv, trv, *br, *tr;
131 GridTrimVertex brrv, trrv;
132 TrimVertex *rf = right.first();
133 TrimVertex *rl = right.last();
134
135 if( rf->param[0] <= rl->param[0] ) {
136 brv.param[0] = rf->param[0];
137 brv.param[1] = rl->param[1];
138 brv.nuid = 0; // XXX
139 assert( brv.param[1] == bot.vval );
140 br = &brv;
141 tr = rf;
142 trrv.set( rf );
143 if( rl->param[0] < uarray.uarray[top.uend+1] ) {
144 assert( rl->param[0] >= uarray.uarray[top.uend] );
145 brrv.set( rl );
146 } else {
147 brrv.set( top.uend+1, bot.vindex );
148 }
149 coveUpperRightNoGrid( br );
150 } else {
151 trv.param[0] = rl->param[0];
152 trv.param[1] = rf->param[1];
153 trv.nuid = 0; // XXX
154 assert( trv.param[1] == top.vval );
155 tr = &trv;
156 br = rl;
157 brrv.set( rl );
158 if( rf->param[0] < uarray.uarray[bot.uend+1] ) {
159 assert( rf->param[0] >= uarray.uarray[bot.uend] );
160 trrv.set( rf );
161 } else {
162 trrv.set( bot.uend+1, top.vindex );
163 }
164 coveLowerRightNoGrid( tr );
165 }
166
167 backend.bgntmesh( "doit" );
168 output(trrv);
169 output(tllv);
170 output( tr );
171 output( tl );
172 output( br );
173 output( bl );
174 output(brrv);
175 output(bllv);
176 backend.endtmesh();
177 }
178 }
179
180 void
181 CoveAndTiler::tile( long vindex, long ustart, long uend )
182 {
183 long numsteps = uend - ustart;
184
185 if( numsteps == 0 ) return;
186
187 if( numsteps > MAXSTRIPSIZE ) {
188 long umid = ustart + (uend - ustart) / 2;
189 tile( vindex, ustart, umid );
190 tile( vindex, umid, uend );
191 } else {
192 backend.surfmesh( ustart, vindex-1, numsteps, 1 );
193 }
194 }
195
196 void
197 CoveAndTiler::coveUpperRight( void )
198 {
199 GridVertex tgv( top.uend, top.vindex );
200 GridVertex gv( top.uend, bot.vindex );
201
202 right.first();
203 backend.bgntmesh( "coveUpperRight" );
204 output( right.next() );
205 output( tgv );
206 backend.swaptmesh();
207 output( gv );
208 coveUR();
209 backend.endtmesh();
210 }
211
212 void
213 CoveAndTiler::coveUpperRightNoGrid( TrimVertex* br )
214 {
215 backend.bgntmesh( "coveUpperRight" );
216 output( right.first() );
217 output( right.next() );
218 backend.swaptmesh();
219 output( br );
220 coveUR();
221 backend.endtmesh();
222 }
223
224 void
225 CoveAndTiler::coveUR( )
226 {
227 GridVertex gv( top.uend, bot.vindex );
228 TrimVertex *vert = right.next();
229 if( vert == NULL ) return;
230
231 assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] );
232
233 if( gv.nextu() >= bot.uend ) {
234 for( ; vert; vert = right.next() ) {
235 output( vert );
236 backend.swaptmesh();
237 }
238 } else while( 1 ) {
239 if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) {
240 output( vert );
241 backend.swaptmesh();
242 vert = right.next();
243 if( vert == NULL ) break;
244 } else {
245 backend.swaptmesh();
246 output( gv );
247 if( gv.nextu() == bot.uend ) {
248 for( ; vert; vert = right.next() ) {
249 output( vert );
250 backend.swaptmesh();
251 }
252 break;
253 }
254 }
255 }
256 }
257
258 void
259 CoveAndTiler::coveUpperLeft( void )
260 {
261 GridVertex tgv( top.ustart, top.vindex );
262 GridVertex gv( top.ustart, bot.vindex );
263
264 left.first();
265 backend.bgntmesh( "coveUpperLeft" );
266 output( tgv );
267 output( left.next() );
268 output( gv );
269 backend.swaptmesh();
270 coveUL();
271 backend.endtmesh();
272 }
273
274 void
275 CoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl )
276 {
277 backend.bgntmesh( "coveUpperLeftNoGrid" );
278 output( left.first() );
279 output( left.next() );
280 output( bl );
281 backend.swaptmesh();
282 coveUL();
283 backend.endtmesh();
284 }
285
286 void
287 CoveAndTiler::coveUL()
288 {
289 GridVertex gv( top.ustart, bot.vindex );
290 TrimVertex *vert = left.next();
291 if( vert == NULL ) return;
292 assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] );
293
294 if( gv.prevu() <= bot.ustart ) {
295 for( ; vert; vert = left.next() ) {
296 backend.swaptmesh();
297 output( vert );
298 }
299 } else while( 1 ) {
300 if( vert->param[0] > uarray.uarray[gv.gparam[0]] ) {
301 backend.swaptmesh();
302 output( vert );
303 vert = left.next();
304 if( vert == NULL ) break;
305 } else {
306 output( gv );
307 backend.swaptmesh();
308 if( gv.prevu() == bot.ustart ) {
309 for( ; vert; vert = left.next() ) {
310 backend.swaptmesh();
311 output( vert );
312 }
313 break;
314 }
315 }
316 }
317 }
318
319 void
320 CoveAndTiler::coveLowerLeft( void )
321 {
322 GridVertex bgv( bot.ustart, bot.vindex );
323 GridVertex gv( bot.ustart, top.vindex );
324
325 left.last();
326 backend.bgntmesh( "coveLowerLeft" );
327 output( left.prev() );
328 output( bgv );
329 backend.swaptmesh();
330 output( gv );
331 coveLL();
332 backend.endtmesh();
333 }
334
335 void
336 CoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl )
337 {
338 backend.bgntmesh( "coveLowerLeft" );
339 output( left.last() );
340 output( left.prev() );
341 backend.swaptmesh();
342 output( tl );
343 coveLL( );
344 backend.endtmesh();
345 }
346
347 void
348 CoveAndTiler::coveLL()
349 {
350 GridVertex gv( bot.ustart, top.vindex );
351 TrimVertex *vert = left.prev();
352 if( vert == NULL ) return;
353 assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] );
354
355 if( gv.prevu() <= top.ustart ) {
356 for( ; vert; vert = left.prev() ) {
357 output( vert );
358 backend.swaptmesh();
359 }
360 } else while( 1 ) {
361 if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){
362 output( vert );
363 backend.swaptmesh();
364 vert = left.prev();
365 if( vert == NULL ) break;
366 } else {
367 backend.swaptmesh();
368 output( gv );
369 if( gv.prevu() == top.ustart ) {
370 for( ; vert; vert = left.prev() ) {
371 output( vert );
372 backend.swaptmesh();
373 }
374 break;
375 }
376 }
377 }
378 }
379
380 void
381 CoveAndTiler::coveLowerRight( void )
382 {
383 GridVertex bgv( bot.uend, bot.vindex );
384 GridVertex gv( bot.uend, top.vindex );
385
386 right.last();
387 backend.bgntmesh( "coveLowerRight" );
388 output( bgv );
389 output( right.prev() );
390 output( gv );
391 backend.swaptmesh();
392 coveLR();
393 backend.endtmesh( );
394 }
395
396 void
397 CoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr )
398 {
399 backend.bgntmesh( "coveLowerRIght" );
400 output( right.last() );
401 output( right.prev() );
402 output( tr );
403 backend.swaptmesh();
404 coveLR();
405 backend.endtmesh();
406 }
407
408 void
409 CoveAndTiler::coveLR( )
410 {
411 GridVertex gv( bot.uend, top.vindex );
412 TrimVertex *vert = right.prev();
413 if( vert == NULL ) return;
414 assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] );
415
416 if( gv.nextu() >= top.uend ) {
417 for( ; vert; vert = right.prev() ) {
418 backend.swaptmesh();
419 output( vert );
420 }
421 } else while( 1 ) {
422 if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) {
423 backend.swaptmesh();
424 output( vert );
425 vert = right.prev();
426 if( vert == NULL ) break;
427 } else {
428 output( gv );
429 backend.swaptmesh();
430 if( gv.nextu() == top.uend ) {
431 for( ; vert; vert = right.prev() ) {
432 backend.swaptmesh();
433 output( vert );
434 }
435 break;
436 }
437 }
438 }
439 }
440