Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
14 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1992, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /*
  13. * nurbsinterfac.c++ - $Revision: 1.2 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "mystdio.h"
  18. #include "nurbscon.h"
  19. #include "nurbstes.h"
  20. #include "bufpool.h"
  21. #include "quilt.h"
  22. #include "displayl.h"
  23. #include "knotvect.h"
  24. #include "mapdesc.h"
  25. #define THREAD( work, arg, cleanup ) \
  26. if( dl ) {\
  27. arg->save = 1;\
  28. dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
  29. } else {\
  30. arg->save = 0;\
  31. work( arg );\
  32. }
  33. #define THREAD2( work ) \
  34. if( dl ) {\
  35. dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
  36. } else {\
  37. work( );\
  38. }
  39. NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e)
  40. : subdivider( renderhints, backend ),
  41. backend( c, e ),
  42. maplist( backend ),
  43. o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ),
  44. o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"),
  45. o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ),
  46. o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ),
  47. o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ),
  48. o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ),
  49. propertyPool( sizeof( Property ), 32, "propertyPool" ),
  50. quiltPool( sizeof( Quilt ), 32, "quiltPool" )
  51. {
  52. dl = 0;
  53. inSurface = 0;
  54. inCurve = 0;
  55. inTrim = 0;
  56. playBack = 0;
  57. jumpbuffer = newJumpbuffer();
  58. subdivider.setJumpbuffer( jumpbuffer );
  59. }
  60. NurbsTessellator::~NurbsTessellator( void )
  61. {
  62. if( inTrim ) {
  63. do_nurbserror( 12 );
  64. endtrim();
  65. }
  66. if( inSurface ) {
  67. *nextNurbssurface = 0;
  68. do_freeall();
  69. }
  70. if (jumpbuffer) {
  71. deleteJumpbuffer(jumpbuffer);
  72. jumpbuffer= 0;
  73. }
  74. }
  75. /*-----------------------------------------------------------------------------
  76. * bgnsurface - allocate and initialize an o_surface structure
  77. *
  78. * Client: GL user
  79. *-----------------------------------------------------------------------------
  80. */
  81. void
  82. NurbsTessellator::bgnsurface( long nuid )
  83. {
  84. O_surface *o_surface = new(o_surfacePool) O_surface;
  85. o_surface->nuid = nuid;
  86. THREAD( do_bgnsurface, o_surface, do_freebgnsurface );
  87. }
  88. /*-----------------------------------------------------------------------------
  89. * bgncurve - allocate an initialize an o_curve structure
  90. *
  91. * Client: GL user
  92. *-----------------------------------------------------------------------------
  93. */
  94. void
  95. NurbsTessellator::bgncurve( long nuid )
  96. {
  97. O_curve *o_curve = new(o_curvePool) O_curve;
  98. o_curve->nuid = nuid;
  99. THREAD( do_bgncurve, o_curve, do_freebgncurve );
  100. }
  101. /*-----------------------------------------------------------------------------
  102. * endcurve -
  103. *
  104. * Client:
  105. *-----------------------------------------------------------------------------
  106. */
  107. void
  108. NurbsTessellator::endcurve( void )
  109. {
  110. THREAD2( do_endcurve );
  111. }
  112. /*-----------------------------------------------------------------------------
  113. * endsurface - user level end of surface call
  114. *
  115. * Client: GL user
  116. *-----------------------------------------------------------------------------
  117. */
  118. void
  119. NurbsTessellator::endsurface( void )
  120. {
  121. THREAD2( do_endsurface );
  122. }
  123. /*-----------------------------------------------------------------------------
  124. * bgntrim - allocate and initialize a new trim loop structure (o_trim )
  125. *
  126. * Client: GL user
  127. *-----------------------------------------------------------------------------
  128. */
  129. void
  130. NurbsTessellator::bgntrim( void )
  131. {
  132. O_trim *o_trim = new(o_trimPool) O_trim;
  133. THREAD( do_bgntrim, o_trim, do_freebgntrim );
  134. }
  135. /*-----------------------------------------------------------------------------
  136. * endtrim -
  137. *
  138. * Client: GL user
  139. *-----------------------------------------------------------------------------
  140. */
  141. void
  142. NurbsTessellator::endtrim( void )
  143. {
  144. THREAD2( do_endtrim );
  145. }
  146. /*-----------------------------------------------------------------------------
  147. * pwlcurve -
  148. *
  149. * count - number of points on curve
  150. * array - array of points on curve
  151. * byte_stride - distance between points in bytes
  152. * type - valid data flag
  153. *
  154. * Client: Gl user
  155. *-----------------------------------------------------------------------------
  156. */
  157. void
  158. NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type )
  159. {
  160. Mapdesc *mapdesc = maplist.locate( type );
  161. if( mapdesc == 0 ) {
  162. do_nurbserror( 35 );
  163. isDataValid = 0;
  164. return;
  165. }
  166. if ( (type != N_P2D) && (type != N_P2DR) ) {
  167. do_nurbserror( 22 );
  168. isDataValid = 0;
  169. return;
  170. }
  171. if( count < 0 ) {
  172. do_nurbserror( 33 );
  173. isDataValid = 0;
  174. return;
  175. }
  176. if( byte_stride < 0 ) {
  177. do_nurbserror( 34 );
  178. isDataValid = 0;
  179. return;
  180. }
  181. #ifdef NOTDEF
  182. if( mapdesc->isRational() ) {
  183. INREAL *p = array;
  184. INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2];
  185. p = (INREAL *) (((char *) p) + byte_stride);
  186. for( long i = 1; i != count; i++ ) {
  187. if( p[0] == x && p[1] == y && p[2] == w ) break;
  188. x = p[0]; y = p[1]; w = p[2];
  189. p = (INREAL *) (((char *) p) + byte_stride);
  190. }
  191. if( i != count ) {
  192. do_nurbserror( 37 );
  193. dprintf( "point %d (%f,%f)\n", i, x, y );
  194. isDataValid = 0;
  195. return;
  196. }
  197. } else {
  198. INREAL *p = array;
  199. INREAL x = p[0]; INREAL y = p[1];
  200. p = (INREAL *) (((char *) p) + byte_stride);
  201. for( long i = 1; i != count; i++ ) {
  202. if( p[0] == x && p[1] == y ) break;
  203. x = p[0]; y = p[1];
  204. p = (INREAL *) (((char *) p) + byte_stride);
  205. }
  206. if( i != count ) {
  207. do_nurbserror( 37 );
  208. dprintf( "point %d (%f,%f)\n", i, x, y );
  209. isDataValid = 0;
  210. return;
  211. }
  212. }
  213. #endif
  214. O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) );
  215. THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve );
  216. }
  217. /*-----------------------------------------------------------------------------
  218. * nurbscurve -
  219. *
  220. * Client: GL user
  221. *-----------------------------------------------------------------------------
  222. */
  223. void
  224. NurbsTessellator::nurbscurve(
  225. long nknots, /* number of p knots */
  226. INREAL knot[], /* nondecreasing knot values in p */
  227. long byte_stride, /* distance in bytes between control points */
  228. INREAL ctlarray[], /* pointer to first control point */
  229. long order, /* order of spline */
  230. long type ) /* description of range space */
  231. {
  232. Mapdesc *mapdesc = maplist.locate( type );
  233. if( mapdesc == 0 ) {
  234. do_nurbserror( 35 );
  235. isDataValid = 0;
  236. return;
  237. }
  238. if( ctlarray == 0 ) {
  239. do_nurbserror( 36 );
  240. isDataValid = 0;
  241. return;
  242. }
  243. if( byte_stride < 0 ) {
  244. do_nurbserror( 34 );
  245. isDataValid = 0;
  246. return;
  247. }
  248. Knotvector knots;
  249. knots.init( nknots, byte_stride, order, knot );
  250. if( do_check_knots( &knots, "curve" ) ) return;
  251. O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type);
  252. o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc);
  253. o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() );
  254. THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve );
  255. }
  256. /*-----------------------------------------------------------------------------
  257. * nurbssurface -
  258. *
  259. * Client: User routine
  260. *-----------------------------------------------------------------------------
  261. */
  262. void
  263. NurbsTessellator::nurbssurface(
  264. long sknot_count, /* number of s knots */
  265. INREAL sknot[], /* nondecreasing knot values in s */
  266. long tknot_count, /* number of t knots */
  267. INREAL tknot[], /* nondecreasing knot values in t */
  268. long s_byte_stride, /* s step size in memory bytes */
  269. long t_byte_stride, /* t step size in memory bytes */
  270. INREAL ctlarray[], /* pointer to first control point */
  271. long sorder, /* order of the spline in s parameter */
  272. long torder, /* order of the spline in t parameter */
  273. long type) /* description of range space */
  274. {
  275. Mapdesc *mapdesc = maplist.locate( type );
  276. if( mapdesc == 0 ) {
  277. do_nurbserror( 35 );
  278. isDataValid = 0;
  279. return;
  280. }
  281. if( s_byte_stride < 0 ) {
  282. do_nurbserror( 34 );
  283. isDataValid = 0;
  284. return;
  285. }
  286. if( t_byte_stride < 0 ) {
  287. do_nurbserror( 34 );
  288. isDataValid = 0;
  289. return;
  290. }
  291. Knotvector sknotvector, tknotvector;
  292. sknotvector.init( sknot_count, s_byte_stride, sorder, sknot );
  293. if( do_check_knots( &sknotvector, "surface" ) ) return;
  294. tknotvector.init( tknot_count, t_byte_stride, torder, tknot );
  295. if( do_check_knots( &tknotvector, "surface" ) ) return;
  296. O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type);
  297. o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc);
  298. o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector,
  299. ctlarray, mapdesc->getNcoords() );
  300. THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface );
  301. }
  302. /*-----------------------------------------------------------------------------
  303. * setnurbsproperty -
  304. *
  305. *-----------------------------------------------------------------------------
  306. */
  307. void
  308. NurbsTessellator::setnurbsproperty( long tag, INREAL value )
  309. {
  310. if( ! renderhints.isProperty( tag ) ) {
  311. do_nurbserror( 26 );
  312. } else {
  313. Property *prop = new(propertyPool) Property( tag, value );
  314. THREAD( do_setnurbsproperty, prop, do_freenurbsproperty );
  315. }
  316. }
  317. /*-----------------------------------------------------------------------------
  318. * setnurbsproperty -
  319. *
  320. *-----------------------------------------------------------------------------
  321. */
  322. void
  323. NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value )
  324. {
  325. Mapdesc *mapdesc = maplist.locate( type );
  326. if( mapdesc == 0 ) {
  327. do_nurbserror( 35 );
  328. return;
  329. }
  330. if( ! mapdesc->isProperty( tag ) ) {
  331. do_nurbserror( 26 );
  332. return;
  333. }
  334. Property *prop = new(propertyPool) Property( type, tag, value );
  335. THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty );
  336. }
  337. /*-----------------------------------------------------------------------------
  338. * getnurbsproperty -
  339. *
  340. *-----------------------------------------------------------------------------
  341. */
  342. void
  343. NurbsTessellator::getnurbsproperty( long tag, INREAL *value )
  344. {
  345. if( renderhints.isProperty( tag ) ) {
  346. *value = renderhints.getProperty( tag );
  347. } else {
  348. do_nurbserror( 26 );
  349. }
  350. }
  351. /*-----------------------------------------------------------------------------
  352. * getnurbsproperty -
  353. *
  354. *-----------------------------------------------------------------------------
  355. */
  356. void
  357. NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value )
  358. {
  359. Mapdesc *mapdesc = maplist.locate( type );
  360. if( mapdesc == 0 )
  361. do_nurbserror( 35 );
  362. if( mapdesc->isProperty( tag ) ) {
  363. *value = mapdesc->getProperty( tag );
  364. } else {
  365. do_nurbserror( 26 );
  366. }
  367. }
  368. /*--------------------------------------------------------------------------
  369. * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
  370. *--------------------------------------------------------------------------
  371. */
  372. void
  373. NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat )
  374. {
  375. // XXX - cannot be put in display list
  376. Mapdesc *mapdesc = maplist.locate( type );
  377. if( mapdesc == 0 ) {
  378. do_nurbserror( 35 );
  379. isDataValid = 0;
  380. } else if( purpose == N_BBOXSIZE ) {
  381. mapdesc->setBboxsize( mat );
  382. } else {
  383. #ifndef NDEBUG
  384. dprintf( "ERRORRORRORR!!!\n");
  385. #endif
  386. }
  387. }
  388. /*--------------------------------------------------------------------------
  389. * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
  390. *--------------------------------------------------------------------------
  391. */
  392. void
  393. NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat,
  394. long rstride, long cstride )
  395. {
  396. // XXX - cannot be put in display list
  397. Mapdesc *mapdesc = maplist.locate( type );
  398. if( mapdesc == 0 ) {
  399. do_nurbserror( 35 );
  400. isDataValid = 0;
  401. } else if( purpose == N_CULLINGMATRIX ) {
  402. mapdesc->setCmat( mat, rstride, cstride );
  403. } else if( purpose == N_SAMPLINGMATRIX ) {
  404. mapdesc->setSmat( mat, rstride, cstride );
  405. } else if( purpose == N_BBOXMATRIX ) {
  406. mapdesc->setBmat( mat, rstride, cstride );
  407. } else {
  408. #ifndef NDEBUG
  409. dprintf( "ERRORRORRORR!!!\n");
  410. #endif
  411. }
  412. }
  413. void
  414. NurbsTessellator::redefineMaps( void )
  415. {
  416. maplist.initialize();
  417. }
  418. void
  419. NurbsTessellator::defineMap( long type, long rational, long ncoords )
  420. {
  421. maplist.define( type, (int) rational, (int) ncoords );
  422. }
  423. void
  424. NurbsTessellator::discardRecording( void *_dl )
  425. {
  426. delete (DisplayList *) _dl;
  427. }
  428. void *
  429. NurbsTessellator::beginRecording( void )
  430. {
  431. dl = new DisplayList( this );
  432. return (void *) dl;
  433. }
  434. void
  435. NurbsTessellator::endRecording( void )
  436. {
  437. dl->endList();
  438. dl = 0;
  439. }
  440. void
  441. NurbsTessellator::playRecording( void *_dl )
  442. {
  443. playBack = 1;
  444. bgnrender();
  445. ((DisplayList *)_dl)->play();
  446. endrender();
  447. playBack = 0;
  448. }