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.

766 lines
18 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1991, 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. * glsurfeval.c++ - surface evaluator
  14. *
  15. * $Revision: 1.5 $
  16. */
  17. /* Polynomial Evaluator Interface */
  18. #include <glos.h>
  19. #include <GL/gl.h>
  20. #include "glimport.h"
  21. #include "glrender.h"
  22. #include "glsurfev.h"
  23. #include "nurbscon.h"
  24. /*#define USE_INTERNAL_EVAL*/ //use internal evaluator
  25. /*whether do evaluation or not*/
  26. /*#define NO_EVALUATION*/
  27. /*for statistics*/
  28. /*#define STATISTICS*/
  29. #ifdef STATISTICS
  30. static int STAT_num_of_triangles=0;
  31. static int STAT_num_of_eval_vertices=0;
  32. static int STAT_num_of_quad_strips=0;
  33. #endif
  34. OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
  35. {
  36. int i;
  37. for (i=0; i<VERTEX_CACHE_SIZE; i++) {
  38. vertexCache[i] = new StoredVertex;
  39. }
  40. tmeshing = 0;
  41. which = 0;
  42. vcount = 0;
  43. }
  44. OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
  45. {
  46. for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) {
  47. delete vertexCache[ii];
  48. vertexCache[ii]= 0;
  49. }
  50. }
  51. /*---------------------------------------------------------------------------
  52. * disable - turn off a map
  53. *---------------------------------------------------------------------------
  54. */
  55. void
  56. OpenGLSurfaceEvaluator::disable(long type)
  57. {
  58. glDisable((GLenum) type);
  59. }
  60. /*---------------------------------------------------------------------------
  61. * enable - turn on a map
  62. *---------------------------------------------------------------------------
  63. */
  64. void
  65. OpenGLSurfaceEvaluator::enable(long type)
  66. {
  67. glEnable((GLenum) type);
  68. }
  69. /*-------------------------------------------------------------------------
  70. * mapgrid2f - define a lattice of points with origin and offset
  71. *-------------------------------------------------------------------------
  72. */
  73. void
  74. OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1)
  75. {
  76. #ifdef USE_INTERNAL_EVAL
  77. inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv,
  78. (REAL) v0, (REAL) v1);
  79. #else
  80. glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv,
  81. (GLdouble) v0, (GLdouble) v1);
  82. #endif
  83. }
  84. void
  85. OpenGLSurfaceEvaluator::polymode(long style)
  86. {
  87. switch(style) {
  88. default:
  89. case N_MESHFILL:
  90. glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL);
  91. break;
  92. case N_MESHLINE:
  93. glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE);
  94. break;
  95. case N_MESHPOINT:
  96. glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT);
  97. break;
  98. }
  99. }
  100. void
  101. OpenGLSurfaceEvaluator::bgnline(void)
  102. {
  103. glBegin((GLenum) GL_LINE_STRIP);
  104. }
  105. void
  106. OpenGLSurfaceEvaluator::endline(void)
  107. {
  108. glEnd();
  109. }
  110. void
  111. OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to)
  112. {
  113. }
  114. void
  115. OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi)
  116. {
  117. }
  118. void
  119. OpenGLSurfaceEvaluator::bgnclosedline(void)
  120. {
  121. glBegin((GLenum) GL_LINE_LOOP);
  122. }
  123. void
  124. OpenGLSurfaceEvaluator::endclosedline(void)
  125. {
  126. glEnd();
  127. }
  128. void
  129. OpenGLSurfaceEvaluator::bgntmesh(void)
  130. {
  131. tmeshing = 1;
  132. which = 0;
  133. vcount = 0;
  134. glBegin((GLenum) GL_TRIANGLES);
  135. }
  136. void
  137. OpenGLSurfaceEvaluator::swaptmesh(void)
  138. {
  139. which = 1 - which;
  140. }
  141. void
  142. OpenGLSurfaceEvaluator::endtmesh(void)
  143. {
  144. tmeshing = 0;
  145. glEnd();
  146. }
  147. void
  148. OpenGLSurfaceEvaluator::bgntfan(void)
  149. {
  150. glBegin((GLenum) GL_TRIANGLE_FAN);
  151. }
  152. void
  153. OpenGLSurfaceEvaluator::endtfan(void)
  154. {
  155. glEnd();
  156. }
  157. void
  158. OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
  159. {
  160. #ifdef USE_INTERNAL_EVAL
  161. inEvalUStrip(n_upper, v_upper, upper_val,
  162. n_lower, v_lower, lower_val);
  163. #else
  164. int i,j,k,l;
  165. REAL leftMostV[2];
  166. /*
  167. *the algorithm works by scanning from left to right.
  168. *leftMostV: the left most of the remaining verteces (on both upper and lower).
  169. * it could an element of upperVerts or lowerVerts.
  170. *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
  171. *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
  172. */
  173. /*initialize i,j,and leftMostV
  174. */
  175. if(upper_val[0] <= lower_val[0])
  176. {
  177. i=1;
  178. j=0;
  179. leftMostV[0] = upper_val[0];
  180. leftMostV[1] = v_upper;
  181. }
  182. else
  183. {
  184. i=0;
  185. j=1;
  186. leftMostV[0] = lower_val[0];
  187. leftMostV[1] = v_lower;
  188. }
  189. /*the main loop.
  190. *the invariance is that:
  191. *at the beginning of each loop, the meaning of i,j,and leftMostV are
  192. *maintained
  193. */
  194. while(1)
  195. {
  196. if(i >= n_upper) /*case1: no more in upper*/
  197. {
  198. if(j<n_lower-1) /*at least two vertices in lower*/
  199. {
  200. bgntfan();
  201. coord2f(leftMostV[0], leftMostV[1]);
  202. // glNormal3fv(leftMostNormal);
  203. // glVertex3fv(leftMostXYZ);
  204. while(j<n_lower){
  205. coord2f(lower_val[j], v_lower);
  206. // glNormal3fv(lowerNormal[j]);
  207. // glVertex3fv(lowerXYZ[j]);
  208. j++;
  209. }
  210. endtfan();
  211. }
  212. break; /*exit the main loop*/
  213. }
  214. else if(j>= n_lower) /*case2: no more in lower*/
  215. {
  216. if(i<n_upper-1) /*at least two vertices in upper*/
  217. {
  218. bgntfan();
  219. coord2f(leftMostV[0], leftMostV[1]);
  220. // glNormal3fv(leftMostNormal);
  221. // glVertex3fv(leftMostXYZ);
  222. for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
  223. {
  224. coord2f(upper_val[k], v_upper);
  225. // glNormal3fv(upperNormal[k]);
  226. // glVertex3fv(upperXYZ[k]);
  227. }
  228. endtfan();
  229. }
  230. break; /*exit the main loop*/
  231. }
  232. else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
  233. {
  234. if(upper_val[i] <= lower_val[j])
  235. {
  236. bgntfan();
  237. coord2f(lower_val[j], v_lower);
  238. // glNormal3fv(lowerNormal[j]);
  239. // glVertex3fv(lowerXYZ[j]);
  240. /*find the last k>=i such that
  241. *upperverts[k][0] <= lowerverts[j][0]
  242. */
  243. k=i;
  244. while(k<n_upper)
  245. {
  246. if(upper_val[k] > lower_val[j])
  247. break;
  248. k++;
  249. }
  250. k--;
  251. for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
  252. {
  253. coord2f(upper_val[l], v_upper);
  254. // glNormal3fv(upperNormal[l]);
  255. // glVertex3fv(upperXYZ[l]);
  256. }
  257. coord2f(leftMostV[0], leftMostV[1]);
  258. // glNormal3fv(leftMostNormal);
  259. // glVertex3fv(leftMostXYZ);
  260. endtfan();
  261. /*update i and leftMostV for next loop
  262. */
  263. i = k+1;
  264. leftMostV[0] = upper_val[k];
  265. leftMostV[1] = v_upper;
  266. // leftMostNormal = upperNormal[k];
  267. // leftMostXYZ = upperXYZ[k];
  268. }
  269. else /*upperVerts[i][0] > lowerVerts[j][0]*/
  270. {
  271. bgntfan();
  272. coord2f(upper_val[i], v_upper);
  273. // glNormal3fv(upperNormal[i]);
  274. // glVertex3fv(upperXYZ[i]);
  275. coord2f(leftMostV[0], leftMostV[1]);
  276. // glNormal3fv(leftMostNormal);
  277. // glVertex3fv(leftMostXYZ);
  278. /*find the last k>=j such that
  279. *lowerverts[k][0] < upperverts[i][0]
  280. */
  281. k=j;
  282. while(k< n_lower)
  283. {
  284. if(lower_val[k] >= upper_val[i])
  285. break;
  286. coord2f(lower_val[k], v_lower);
  287. // glNormal3fv(lowerNormal[k]);
  288. // glVertex3fv(lowerXYZ[k]);
  289. k++;
  290. }
  291. endtfan();
  292. /*update j and leftMostV for next loop
  293. */
  294. j=k;
  295. leftMostV[0] = lower_val[j-1];
  296. leftMostV[1] = v_lower;
  297. // leftMostNormal = lowerNormal[j-1];
  298. // leftMostXYZ = lowerXYZ[j-1];
  299. }
  300. }
  301. }
  302. //clean up
  303. // free(upperXYZ);
  304. // free(lowerXYZ);
  305. // free(upperNormal);
  306. // free(lowerNormal);
  307. #endif
  308. }
  309. void
  310. OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
  311. {
  312. #ifdef USE_INTERNAL_EVAL
  313. inEvalVStrip(n_left, u_left, left_val,
  314. n_right, u_right, right_val);
  315. #else
  316. int i,j,k,l;
  317. REAL botMostV[2];
  318. /*
  319. *the algorithm works by scanning from bot to top.
  320. *botMostV: the bot most of the remaining verteces (on both left and right).
  321. * it could an element of leftVerts or rightVerts.
  322. *i: leftVerts[i] is the first vertex to the top of botMostV on left line
  323. *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
  324. */
  325. /*initialize i,j,and botMostV
  326. */
  327. if(left_val[0] <= right_val[0])
  328. {
  329. i=1;
  330. j=0;
  331. botMostV[0] = u_left;
  332. botMostV[1] = left_val[0];
  333. }
  334. else
  335. {
  336. i=0;
  337. j=1;
  338. botMostV[0] = u_right;
  339. botMostV[1] = right_val[0];
  340. }
  341. /*the main loop.
  342. *the invariance is that:
  343. *at the beginning of each loop, the meaning of i,j,and botMostV are
  344. *maintained
  345. */
  346. while(1)
  347. {
  348. if(i >= n_left) /*case1: no more in left*/
  349. {
  350. if(j<n_right-1) /*at least two vertices in right*/
  351. {
  352. bgntfan();
  353. coord2f(botMostV[0], botMostV[1]);
  354. while(j<n_right){
  355. coord2f(u_right, right_val[j]);
  356. // glNormal3fv(rightNormal[j]);
  357. // glVertex3fv(rightXYZ[j]);
  358. j++;
  359. }
  360. endtfan();
  361. }
  362. break; /*exit the main loop*/
  363. }
  364. else if(j>= n_right) /*case2: no more in right*/
  365. {
  366. if(i<n_left-1) /*at least two vertices in left*/
  367. {
  368. bgntfan();
  369. coord2f(botMostV[0], botMostV[1]);
  370. // glNormal3fv(botMostNormal);
  371. // glVertex3fv(botMostXYZ);
  372. for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
  373. {
  374. coord2f(u_left, left_val[k]);
  375. // glNormal3fv(leftNormal[k]);
  376. // glVertex3fv(leftXYZ[k]);
  377. }
  378. endtfan();
  379. }
  380. break; /*exit the main loop*/
  381. }
  382. else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
  383. {
  384. if(left_val[i] <= right_val[j])
  385. {
  386. bgntfan();
  387. coord2f(u_right, right_val[j]);
  388. // glNormal3fv(rightNormal[j]);
  389. // glVertex3fv(rightXYZ[j]);
  390. /*find the last k>=i such that
  391. *leftverts[k][0] <= rightverts[j][0]
  392. */
  393. k=i;
  394. while(k<n_left)
  395. {
  396. if(left_val[k] > right_val[j])
  397. break;
  398. k++;
  399. }
  400. k--;
  401. for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
  402. {
  403. coord2f(u_left, left_val[l]);
  404. // glNormal3fv(leftNormal[l]);
  405. // glVertex3fv(leftXYZ[l]);
  406. }
  407. coord2f(botMostV[0], botMostV[1]);
  408. // glNormal3fv(botMostNormal);
  409. // glVertex3fv(botMostXYZ);
  410. endtfan();
  411. /*update i and botMostV for next loop
  412. */
  413. i = k+1;
  414. botMostV[0] = u_left;
  415. botMostV[1] = left_val[k];
  416. // botMostNormal = leftNormal[k];
  417. // botMostXYZ = leftXYZ[k];
  418. }
  419. else /*left_val[i] > right_val[j])*/
  420. {
  421. bgntfan();
  422. coord2f(u_left, left_val[i]);
  423. // glNormal3fv(leftNormal[i]);
  424. // glVertex3fv(leftXYZ[i]);
  425. coord2f(botMostV[0], botMostV[1]);
  426. // glNormal3fv(botMostNormal);
  427. // glVertex3fv(botMostXYZ);
  428. /*find the last k>=j such that
  429. *rightverts[k][0] < leftverts[i][0]
  430. */
  431. k=j;
  432. while(k< n_right)
  433. {
  434. if(right_val[k] >= left_val[i])
  435. break;
  436. coord2f(u_right, right_val[k]);
  437. // glNormal3fv(rightNormal[k]);
  438. // glVertex3fv(rightXYZ[k]);
  439. k++;
  440. }
  441. endtfan();
  442. /*update j and botMostV for next loop
  443. */
  444. j=k;
  445. botMostV[0] = u_right;
  446. botMostV[1] = right_val[j-1];
  447. // botMostNormal = rightNormal[j-1];
  448. // botMostXYZ = rightXYZ[j-1];
  449. }
  450. }
  451. }
  452. //clean up
  453. // free(leftXYZ);
  454. // free(leftNormal);
  455. // free(rightXYZ);
  456. // free(rightNormal);
  457. #endif
  458. }
  459. void
  460. OpenGLSurfaceEvaluator::bgnqstrip(void)
  461. {
  462. glBegin((GLenum) GL_QUAD_STRIP);
  463. #ifdef STATISTICS
  464. STAT_num_of_quad_strips++;
  465. #endif
  466. }
  467. void
  468. OpenGLSurfaceEvaluator::endqstrip(void)
  469. {
  470. glEnd();
  471. }
  472. /*-------------------------------------------------------------------------
  473. * bgnmap2f - preamble to surface definition and evaluations
  474. *-------------------------------------------------------------------------
  475. */
  476. void
  477. OpenGLSurfaceEvaluator::bgnmap2f(long)
  478. {
  479. glPushAttrib((GLbitfield) GL_EVAL_BIT);
  480. }
  481. /*-------------------------------------------------------------------------
  482. * endmap2f - postamble to a map
  483. *-------------------------------------------------------------------------
  484. */
  485. void
  486. OpenGLSurfaceEvaluator::endmap2f(void)
  487. {
  488. glPopAttrib();
  489. #ifdef STATISTICS
  490. fprintf(stderr, "num_vertices=%i,num_triangles=%i,num_quads_strips=%i\n", STAT_num_of_eval_vertices,STAT_num_of_triangles,STAT_num_of_quad_strips);
  491. #endif
  492. }
  493. /*-------------------------------------------------------------------------
  494. * map2f - pass a desription of a surface map
  495. *-------------------------------------------------------------------------
  496. */
  497. void
  498. OpenGLSurfaceEvaluator::map2f(
  499. long _type,
  500. REAL _ulower, /* u lower domain coord */
  501. REAL _uupper, /* u upper domain coord */
  502. long _ustride, /* interpoint distance */
  503. long _uorder, /* parametric order */
  504. REAL _vlower, /* v lower domain coord */
  505. REAL _vupper, /* v upper domain coord */
  506. long _vstride, /* interpoint distance */
  507. long _vorder, /* parametric order */
  508. REAL *pts) /* control points */
  509. {
  510. #ifdef USE_INTERNAL_EVAL
  511. inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper,
  512. (int) _ustride, (int) _uorder, (REAL) _vlower,
  513. (REAL) _vupper, (int) _vstride, (int) _vorder,
  514. (REAL *) pts);
  515. #else
  516. glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper,
  517. (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower,
  518. (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder,
  519. (const GLfloat *) pts);
  520. #endif
  521. }
  522. /*-------------------------------------------------------------------------
  523. * mapmesh2f - evaluate a mesh of points on lattice
  524. *-------------------------------------------------------------------------
  525. */
  526. void
  527. OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax)
  528. {
  529. #ifdef NO_EVALUATION
  530. return;
  531. #endif
  532. #ifdef USE_INTERNAL_EVAL
  533. inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax);
  534. #else
  535. switch(style) {
  536. default:
  537. case N_MESHFILL:
  538. glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax,
  539. (GLint) vmin, (GLint) vmax);
  540. break;
  541. case N_MESHLINE:
  542. glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax,
  543. (GLint) vmin, (GLint) vmax);
  544. break;
  545. case N_MESHPOINT:
  546. glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax,
  547. (GLint) vmin, (GLint) vmax);
  548. break;
  549. }
  550. #endif
  551. #ifdef STATISTICS
  552. STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin);
  553. #endif
  554. }
  555. /*-------------------------------------------------------------------------
  556. * evalcoord2f - evaluate a point on a surface
  557. *-------------------------------------------------------------------------
  558. */
  559. void
  560. OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v)
  561. {
  562. #ifdef NO_EVALUATION
  563. return;
  564. #endif
  565. newtmeshvert(u, v);
  566. }
  567. /*-------------------------------------------------------------------------
  568. * evalpoint2i - evaluate a grid point
  569. *-------------------------------------------------------------------------
  570. */
  571. void
  572. OpenGLSurfaceEvaluator::evalpoint2i(long u, long v)
  573. {
  574. #ifdef NO_EVALUATION
  575. return;
  576. #endif
  577. newtmeshvert(u, v);
  578. }
  579. void
  580. OpenGLSurfaceEvaluator::point2i( long u, long v )
  581. {
  582. #ifdef USE_INTERNAL_EVAL
  583. inEvalPoint2( (int)u, (int)v);
  584. #else
  585. glEvalPoint2((GLint) u, (GLint) v);
  586. #endif
  587. #ifdef STATISTICS
  588. STAT_num_of_eval_vertices++;
  589. #endif
  590. }
  591. void
  592. OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v )
  593. {
  594. #ifdef USE_INTERNAL_EVAL
  595. inEvalCoord2f( u, v);
  596. #else
  597. glEvalCoord2f((GLfloat) u, (GLfloat) v);
  598. #endif
  599. #ifdef STATISTICS
  600. STAT_num_of_eval_vertices++;
  601. #endif
  602. }
  603. void
  604. OpenGLSurfaceEvaluator::newtmeshvert( long u, long v )
  605. {
  606. if (tmeshing) {
  607. if (vcount == 2) {
  608. vertexCache[0]->invoke(this);
  609. vertexCache[1]->invoke(this);
  610. point2i( u, v);
  611. } else {
  612. vcount++;
  613. }
  614. vertexCache[which]->saveEvalPoint(u, v);
  615. which = 1 - which;
  616. } else {
  617. point2i( u, v);
  618. }
  619. }
  620. void
  621. OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v )
  622. {
  623. if (tmeshing) {
  624. if (vcount == 2) {
  625. vertexCache[0]->invoke(this);
  626. vertexCache[1]->invoke(this);
  627. coord2f(u,v);
  628. } else {
  629. vcount++;
  630. }
  631. vertexCache[which]->saveEvalCoord(u, v);
  632. which = 1 - which;
  633. } else {
  634. coord2f( u, v);
  635. }
  636. }