[GLU32]
[reactos.git] / reactos / dll / opengl / glu32 / src / libnurbs / internals / coveandtiler.cc
diff --git a/reactos/dll/opengl/glu32/src/libnurbs/internals/coveandtiler.cc b/reactos/dll/opengl/glu32/src/libnurbs/internals/coveandtiler.cc
new file mode 100644 (file)
index 0000000..ca5bf36
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+** 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.
+*/
+
+/*
+ * coveandtiler.c++
+ *
+ */
+
+#include "glimports.h"
+#include "myassert.h"
+#include "mystdio.h"
+#include "coveandtiler.h"
+#include "gridvertex.h"
+#include "gridtrimvertex.h"
+#include "uarray.h"
+#include "backend.h"
+
+
+const int CoveAndTiler::MAXSTRIPSIZE = 1000;
+
+CoveAndTiler::CoveAndTiler( Backend& b )
+           : backend( b )
+{ }
+
+CoveAndTiler::~CoveAndTiler( void )
+{ }
+
+inline void
+CoveAndTiler::output( GridVertex &gv )
+{
+    backend.tmeshvert( &gv );
+}
+
+inline void
+CoveAndTiler::output( TrimVertex *tv )
+{
+    backend.tmeshvert( tv );
+}
+
+inline void
+CoveAndTiler::output( GridTrimVertex& g )
+{
+    backend.tmeshvert( &g );
+}
+
+void
+CoveAndTiler::coveAndTile( void )
+{
+    long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart;
+    long uend  = (top.uend <= bot.uend)     ? top.uend   : bot.uend;
+    if( ustart <= uend ) {
+       tile( bot.vindex, ustart, uend );
+       if( top.ustart >= bot.ustart )
+           coveUpperLeft();
+       else
+           coveLowerLeft();
+
+       if( top.uend <= bot.uend )
+           coveUpperRight();
+       else
+           coveLowerRight();
+    } else {
+       TrimVertex blv, tlv, *bl, *tl;
+       GridTrimVertex bllv, tllv;
+       TrimVertex *lf = left.first();
+       TrimVertex *ll = left.last();
+       if( lf->param[0] >= ll->param[0] ) {
+           blv.param[0] = lf->param[0];
+           blv.param[1] = ll->param[1];
+           blv.nuid = 0; // XXX
+           assert( blv.param[1] == bot.vval );
+           bl = &blv;
+           tl = lf;
+           tllv.set( lf );
+           if( ll->param[0] > uarray.uarray[top.ustart-1] ) {
+               bllv.set( ll );
+               assert( ll->param[0] <= uarray.uarray[bot.ustart] );
+           } else {
+               bllv.set( top.ustart-1, bot.vindex );
+           }
+           coveUpperLeftNoGrid( bl );
+       } else {
+           tlv.param[0] = ll->param[0];
+           tlv.param[1] = lf->param[1];
+           tlv.nuid = 0; // XXX
+           assert( tlv.param[1] == top.vval );
+           tl = &tlv;
+           bl = ll;
+           bllv.set( ll );
+           if( lf->param[0] > uarray.uarray[bot.ustart-1] ) {
+               assert( lf->param[0] <= uarray.uarray[bot.ustart] );
+               tllv.set( lf );
+           } else {
+               tllv.set( bot.ustart-1, top.vindex );
+           }
+           coveLowerLeftNoGrid( tl );
+       }
+
+       TrimVertex brv, trv, *br, *tr;
+       GridTrimVertex brrv, trrv;
+       TrimVertex *rf = right.first();
+       TrimVertex *rl = right.last();
+
+       if( rf->param[0] <= rl->param[0] ) {
+           brv.param[0] = rf->param[0];
+           brv.param[1] = rl->param[1];
+           brv.nuid = 0; // XXX
+           assert( brv.param[1] == bot.vval );
+           br = &brv;
+           tr = rf;
+           trrv.set( rf );
+           if( rl->param[0] < uarray.uarray[top.uend+1] ) {
+               assert( rl->param[0] >= uarray.uarray[top.uend] );
+               brrv.set( rl );
+           } else {
+               brrv.set( top.uend+1, bot.vindex );
+           }
+           coveUpperRightNoGrid( br );
+       } else {
+           trv.param[0] = rl->param[0];
+           trv.param[1] = rf->param[1];
+           trv.nuid = 0; // XXX
+           assert( trv.param[1] == top.vval );
+           tr = &trv;
+           br = rl;
+           brrv.set( rl );
+           if( rf->param[0] < uarray.uarray[bot.uend+1] ) {
+               assert( rf->param[0] >= uarray.uarray[bot.uend] );
+               trrv.set( rf );
+           } else {
+               trrv.set( bot.uend+1, top.vindex );
+           }
+           coveLowerRightNoGrid( tr );
+       }
+
+       backend.bgntmesh( "doit" );
+       output(trrv);
+       output(tllv);
+       output( tr );
+       output( tl );
+       output( br );
+       output( bl );
+       output(brrv);
+       output(bllv);
+       backend.endtmesh();
+    }
+}
+
+void
+CoveAndTiler::tile( long vindex, long ustart, long uend )
+{
+    long numsteps = uend - ustart;
+
+    if( numsteps == 0 ) return;
+
+    if( numsteps > MAXSTRIPSIZE ) {
+       long umid = ustart + (uend - ustart) / 2;
+       tile( vindex, ustart, umid );
+       tile( vindex, umid, uend );
+    } else {
+       backend.surfmesh( ustart, vindex-1, numsteps, 1 );
+    }
+}
+
+void
+CoveAndTiler::coveUpperRight( void )
+{
+    GridVertex tgv( top.uend, top.vindex );
+    GridVertex gv( top.uend, bot.vindex );
+
+    right.first();
+    backend.bgntmesh( "coveUpperRight" );
+    output( right.next() );
+    output( tgv );
+    backend.swaptmesh();
+    output( gv );
+       coveUR();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveUpperRightNoGrid( TrimVertex* br )
+{
+    backend.bgntmesh( "coveUpperRight" );
+    output( right.first() );
+    output( right.next() );
+    backend.swaptmesh();
+    output( br );
+       coveUR();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveUR( )
+{
+    GridVertex gv( top.uend, bot.vindex );
+    TrimVertex *vert = right.next();
+    if( vert == NULL ) return;
+
+    assert( vert->param[0] >= uarray.uarray[gv.gparam[0]]  );
+
+    if( gv.nextu() >= bot.uend ) {
+       for( ; vert; vert = right.next() ) {
+           output( vert );
+           backend.swaptmesh();
+       }
+    } else while( 1 ) {
+       if( vert->param[0] < uarray.uarray[gv.gparam[0]]  ) {
+           output( vert );
+           backend.swaptmesh();
+           vert = right.next();
+           if( vert == NULL ) break;
+       } else {
+           backend.swaptmesh();
+           output( gv );
+           if( gv.nextu() == bot.uend ) {
+               for( ; vert; vert = right.next() ) {
+                   output( vert );
+                   backend.swaptmesh();
+               }
+               break;
+           }
+       }
+    }
+}
+
+void
+CoveAndTiler::coveUpperLeft( void )
+{
+    GridVertex tgv( top.ustart, top.vindex );
+    GridVertex gv( top.ustart, bot.vindex );
+
+    left.first();
+    backend.bgntmesh( "coveUpperLeft" );
+    output( tgv );
+    output( left.next() );
+    output( gv );
+    backend.swaptmesh();
+       coveUL();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl )
+{
+    backend.bgntmesh( "coveUpperLeftNoGrid" );
+    output( left.first() );
+    output( left.next() );
+    output( bl );
+    backend.swaptmesh();
+       coveUL();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveUL()
+{
+    GridVertex gv( top.ustart, bot.vindex );
+    TrimVertex *vert = left.next();
+    if( vert == NULL ) return;
+    assert( vert->param[0] <= uarray.uarray[gv.gparam[0]]  );
+
+    if( gv.prevu() <= bot.ustart ) {
+       for( ; vert; vert = left.next() ) {
+           backend.swaptmesh();
+           output( vert );
+       }
+    } else while( 1 ) {
+       if( vert->param[0] > uarray.uarray[gv.gparam[0]]  ) {
+           backend.swaptmesh();
+           output( vert );
+           vert = left.next();
+           if( vert == NULL ) break;
+       } else {
+           output( gv );
+           backend.swaptmesh();
+           if( gv.prevu() == bot.ustart ) {
+               for( ; vert; vert = left.next() ) {
+                   backend.swaptmesh();
+                   output( vert );
+               }
+               break;
+           }
+       }
+    }
+}
+
+void
+CoveAndTiler::coveLowerLeft( void )
+{
+    GridVertex bgv( bot.ustart, bot.vindex );
+    GridVertex gv( bot.ustart, top.vindex );
+
+    left.last();
+    backend.bgntmesh( "coveLowerLeft" );
+    output( left.prev() );
+    output( bgv );
+    backend.swaptmesh();
+    output( gv );
+       coveLL();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl )
+{
+    backend.bgntmesh( "coveLowerLeft" );
+    output( left.last() );
+    output( left.prev() );
+    backend.swaptmesh();
+    output( tl );
+       coveLL( );
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveLL()
+{
+    GridVertex gv( bot.ustart, top.vindex );
+    TrimVertex *vert = left.prev();
+    if( vert == NULL ) return;
+    assert( vert->param[0] <= uarray.uarray[gv.gparam[0]]  );
+
+    if( gv.prevu() <= top.ustart ) {
+       for( ; vert; vert = left.prev() ) {
+           output( vert );
+           backend.swaptmesh();
+       }
+    } else while( 1 ) {
+       if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){
+           output( vert );
+           backend.swaptmesh();
+           vert = left.prev();
+           if( vert == NULL ) break;
+       } else {
+           backend.swaptmesh();
+           output( gv );
+           if( gv.prevu() == top.ustart ) {
+               for( ; vert; vert = left.prev() ) {
+                   output( vert );
+                   backend.swaptmesh();
+               }
+               break;
+           }
+       }
+    }
+}
+
+void
+CoveAndTiler::coveLowerRight( void )
+{
+    GridVertex bgv( bot.uend, bot.vindex );
+    GridVertex gv( bot.uend, top.vindex );
+
+    right.last();
+    backend.bgntmesh( "coveLowerRight" );       
+    output( bgv );
+    output( right.prev() );
+    output( gv );
+    backend.swaptmesh();
+       coveLR();
+    backend.endtmesh( );
+}
+
+void
+CoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr )
+{
+    backend.bgntmesh( "coveLowerRIght" );
+    output( right.last() );
+    output( right.prev() );
+    output( tr );
+    backend.swaptmesh();
+       coveLR();
+    backend.endtmesh();
+}
+
+void
+CoveAndTiler::coveLR( )
+{
+    GridVertex gv( bot.uend, top.vindex );
+    TrimVertex *vert = right.prev();
+    if( vert == NULL ) return;
+    assert( vert->param[0] >= uarray.uarray[gv.gparam[0]]  );
+
+    if( gv.nextu() >= top.uend ) {
+       for( ; vert; vert = right.prev() ) {
+           backend.swaptmesh();
+           output( vert );
+       }
+    } else while( 1 ) {
+       if( vert->param[0] < uarray.uarray[gv.gparam[0]]  ) {
+           backend.swaptmesh();
+           output( vert );
+           vert = right.prev();
+           if( vert == NULL ) break;
+       } else {
+           output( gv );
+           backend.swaptmesh();
+           if( gv.nextu() == top.uend ) {
+               for( ; vert; vert = right.prev() ) {
+                   backend.swaptmesh();
+                   output( vert );
+               }
+               break;
+           }
+       }
+    }
+}
+