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