mirror of
https://github.com/reactos/reactos.git
synced 2024-11-04 13:52:30 +00:00
4019caae75
svn path=/branches/shell32_new-bringup/; revision=51893
537 lines
14 KiB
C++
537 lines
14 KiB
C++
/*
|
|
** 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.
|
|
*/
|
|
|
|
/*
|
|
* nurbsinterfac.c++
|
|
*
|
|
*/
|
|
|
|
#include "glimports.h"
|
|
#include "mystdio.h"
|
|
#include "nurbsconsts.h"
|
|
#include "nurbstess.h"
|
|
#include "bufpool.h"
|
|
#include "quilt.h"
|
|
#include "displaylist.h"
|
|
#include "knotvector.h"
|
|
#include "mapdesc.h"
|
|
|
|
#define THREAD( work, arg, cleanup ) \
|
|
if( dl ) {\
|
|
arg->save = 1;\
|
|
dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
|
|
} else {\
|
|
arg->save = 0;\
|
|
work( arg );\
|
|
}
|
|
|
|
#define THREAD2( work ) \
|
|
if( dl ) {\
|
|
dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
|
|
} else {\
|
|
work( );\
|
|
}
|
|
|
|
NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e)
|
|
: maplist( backend ),
|
|
backend( c, e ),
|
|
subdivider( renderhints, backend ),
|
|
o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ),
|
|
o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"),
|
|
o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ),
|
|
o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ),
|
|
o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ),
|
|
o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ),
|
|
propertyPool( sizeof( Property ), 32, "propertyPool" ),
|
|
quiltPool( sizeof( Quilt ), 32, "quiltPool" )
|
|
{
|
|
dl = 0;
|
|
inSurface = 0;
|
|
inCurve = 0;
|
|
inTrim = 0;
|
|
playBack = 0;
|
|
jumpbuffer = newJumpbuffer();
|
|
subdivider.setJumpbuffer( jumpbuffer );
|
|
}
|
|
|
|
NurbsTessellator::~NurbsTessellator( void )
|
|
{
|
|
if( inTrim ) {
|
|
do_nurbserror( 12 );
|
|
endtrim();
|
|
}
|
|
|
|
if( inSurface ) {
|
|
*nextNurbssurface = 0;
|
|
do_freeall();
|
|
}
|
|
|
|
if (jumpbuffer) {
|
|
deleteJumpbuffer(jumpbuffer);
|
|
jumpbuffer= 0;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* bgnsurface - allocate and initialize an o_surface structure
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::bgnsurface( long nuid )
|
|
{
|
|
O_surface *o_surface = new(o_surfacePool) O_surface;
|
|
o_surface->nuid = nuid;
|
|
THREAD( do_bgnsurface, o_surface, do_freebgnsurface );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* bgncurve - allocate an initialize an o_curve structure
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::bgncurve( long nuid )
|
|
{
|
|
O_curve *o_curve = new(o_curvePool) O_curve;
|
|
o_curve->nuid = nuid;
|
|
THREAD( do_bgncurve, o_curve, do_freebgncurve );
|
|
}
|
|
/*-----------------------------------------------------------------------------
|
|
* endcurve -
|
|
*
|
|
* Client:
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
NurbsTessellator::endcurve( void )
|
|
{
|
|
THREAD2( do_endcurve );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* endsurface - user level end of surface call
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::endsurface( void )
|
|
{
|
|
THREAD2( do_endsurface );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* bgntrim - allocate and initialize a new trim loop structure (o_trim )
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::bgntrim( void )
|
|
{
|
|
O_trim *o_trim = new(o_trimPool) O_trim;
|
|
THREAD( do_bgntrim, o_trim, do_freebgntrim );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* endtrim -
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::endtrim( void )
|
|
{
|
|
THREAD2( do_endtrim );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* pwlcurve -
|
|
*
|
|
* count - number of points on curve
|
|
* array - array of points on curve
|
|
* byte_stride - distance between points in bytes
|
|
* type - valid data flag
|
|
*
|
|
* Client: Gl user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type )
|
|
{
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
if ( (type != N_P2D) && (type != N_P2DR) ) {
|
|
do_nurbserror( 22 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
if( count < 0 ) {
|
|
do_nurbserror( 33 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
if( byte_stride < 0 ) {
|
|
do_nurbserror( 34 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
#ifdef NOTDEF
|
|
if( mapdesc->isRational() ) {
|
|
INREAL *p = array;
|
|
INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2];
|
|
p = (INREAL *) (((char *) p) + byte_stride);
|
|
for( long i = 1; i != count; i++ ) {
|
|
if( p[0] == x && p[1] == y && p[2] == w ) break;
|
|
x = p[0]; y = p[1]; w = p[2];
|
|
p = (INREAL *) (((char *) p) + byte_stride);
|
|
}
|
|
if( i != count ) {
|
|
do_nurbserror( 37 );
|
|
dprintf( "point %d (%f,%f)\n", i, x, y );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
} else {
|
|
INREAL *p = array;
|
|
INREAL x = p[0]; INREAL y = p[1];
|
|
p = (INREAL *) (((char *) p) + byte_stride);
|
|
for( long i = 1; i != count; i++ ) {
|
|
if( p[0] == x && p[1] == y ) break;
|
|
x = p[0]; y = p[1];
|
|
p = (INREAL *) (((char *) p) + byte_stride);
|
|
}
|
|
if( i != count ) {
|
|
do_nurbserror( 37 );
|
|
dprintf( "point %d (%f,%f)\n", i, x, y );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) );
|
|
THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* nurbscurve -
|
|
*
|
|
* Client: GL user
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::nurbscurve(
|
|
long nknots, /* number of p knots */
|
|
INREAL knot[], /* nondecreasing knot values in p */
|
|
long byte_stride, /* distance in bytes between control points */
|
|
INREAL ctlarray[], /* pointer to first control point */
|
|
long order, /* order of spline */
|
|
long type ) /* description of range space */
|
|
{
|
|
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
if( ctlarray == 0 ) {
|
|
do_nurbserror( 36 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
if( byte_stride < 0 ) {
|
|
do_nurbserror( 34 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
Knotvector knots;
|
|
|
|
knots.init( nknots, byte_stride, order, knot );
|
|
if( do_check_knots( &knots, "curve" ) ) return;
|
|
|
|
O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type);
|
|
o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc);
|
|
o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() );
|
|
|
|
THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* nurbssurface -
|
|
*
|
|
* Client: User routine
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::nurbssurface(
|
|
long sknot_count, /* number of s knots */
|
|
INREAL sknot[], /* nondecreasing knot values in s */
|
|
long tknot_count, /* number of t knots */
|
|
INREAL tknot[], /* nondecreasing knot values in t */
|
|
long s_byte_stride, /* s step size in memory bytes */
|
|
long t_byte_stride, /* t step size in memory bytes */
|
|
INREAL ctlarray[], /* pointer to first control point */
|
|
long sorder, /* order of the spline in s parameter */
|
|
long torder, /* order of the spline in t parameter */
|
|
long type) /* description of range space */
|
|
{
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
if( s_byte_stride < 0 ) {
|
|
do_nurbserror( 34 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
if( t_byte_stride < 0 ) {
|
|
do_nurbserror( 34 );
|
|
isDataValid = 0;
|
|
return;
|
|
}
|
|
|
|
Knotvector sknotvector, tknotvector;
|
|
|
|
sknotvector.init( sknot_count, s_byte_stride, sorder, sknot );
|
|
if( do_check_knots( &sknotvector, "surface" ) ) return;
|
|
|
|
tknotvector.init( tknot_count, t_byte_stride, torder, tknot );
|
|
if( do_check_knots( &tknotvector, "surface" ) ) return;
|
|
|
|
O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type);
|
|
o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc);
|
|
|
|
o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector,
|
|
ctlarray, mapdesc->getNcoords() );
|
|
THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* setnurbsproperty -
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::setnurbsproperty( long tag, INREAL value )
|
|
{
|
|
if( ! renderhints.isProperty( tag ) ) {
|
|
do_nurbserror( 26 );
|
|
} else {
|
|
Property *prop = new(propertyPool) Property( tag, value );
|
|
THREAD( do_setnurbsproperty, prop, do_freenurbsproperty );
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* setnurbsproperty -
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value )
|
|
{
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
return;
|
|
}
|
|
|
|
if( ! mapdesc->isProperty( tag ) ) {
|
|
do_nurbserror( 26 );
|
|
return;
|
|
}
|
|
|
|
Property *prop = new(propertyPool) Property( type, tag, value );
|
|
THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty );
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* getnurbsproperty -
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
NurbsTessellator::getnurbsproperty( long tag, INREAL *value )
|
|
{
|
|
if( renderhints.isProperty( tag ) ) {
|
|
*value = renderhints.getProperty( tag );
|
|
} else {
|
|
do_nurbserror( 26 );
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* getnurbsproperty -
|
|
*
|
|
*-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value )
|
|
{
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 )
|
|
do_nurbserror( 35 );
|
|
|
|
if( mapdesc->isProperty( tag ) ) {
|
|
*value = mapdesc->getProperty( tag );
|
|
} else {
|
|
do_nurbserror( 26 );
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* setnurbsproperty - accept a user supplied matrix as culling or sampling mat
|
|
*--------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat )
|
|
{
|
|
// XXX - cannot be put in display list
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
isDataValid = 0;
|
|
} else if( purpose == N_BBOXSIZE ) {
|
|
mapdesc->setBboxsize( mat );
|
|
} else {
|
|
#ifndef NDEBUG
|
|
dprintf( "ERRORRORRORR!!!\n");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* setnurbsproperty - accept a user supplied matrix as culling or sampling mat
|
|
*--------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat,
|
|
long rstride, long cstride )
|
|
{
|
|
// XXX - cannot be put in display list
|
|
Mapdesc *mapdesc = maplist.locate( type );
|
|
|
|
if( mapdesc == 0 ) {
|
|
do_nurbserror( 35 );
|
|
isDataValid = 0;
|
|
} else if( purpose == N_CULLINGMATRIX ) {
|
|
mapdesc->setCmat( mat, rstride, cstride );
|
|
} else if( purpose == N_SAMPLINGMATRIX ) {
|
|
mapdesc->setSmat( mat, rstride, cstride );
|
|
} else if( purpose == N_BBOXMATRIX ) {
|
|
mapdesc->setBmat( mat, rstride, cstride );
|
|
} else {
|
|
#ifndef NDEBUG
|
|
dprintf( "ERRORRORRORR!!!\n");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void
|
|
NurbsTessellator::redefineMaps( void )
|
|
{
|
|
maplist.initialize();
|
|
}
|
|
|
|
void
|
|
NurbsTessellator::defineMap( long type, long rational, long ncoords )
|
|
{
|
|
maplist.define( type, (int) rational, (int) ncoords );
|
|
}
|
|
|
|
void
|
|
NurbsTessellator::discardRecording( void *_dl )
|
|
{
|
|
delete (DisplayList *) _dl;
|
|
}
|
|
|
|
void *
|
|
NurbsTessellator::beginRecording( void )
|
|
{
|
|
dl = new DisplayList( this );
|
|
return (void *) dl;
|
|
}
|
|
|
|
void
|
|
NurbsTessellator::endRecording( void )
|
|
{
|
|
dl->endList();
|
|
dl = 0;
|
|
}
|
|
|
|
void
|
|
NurbsTessellator::playRecording( void *_dl )
|
|
{
|
|
playBack = 1;
|
|
bgnrender();
|
|
((DisplayList *)_dl)->play();
|
|
endrender();
|
|
playBack = 0;
|
|
}
|
|
|