Source code of Windows XP (NT5)
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.

2134 lines
64 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: eval.c
  3. *
  4. * OpenGL Evaluator functions on the client side.
  5. *
  6. * Created:
  7. * Author:
  8. *
  9. * Copyright (c) 1993 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "glsbcltu.h"
  14. #include "glclt.h"
  15. #include "compsize.h"
  16. #include "glsize.h"
  17. #include "context.h"
  18. #include "global.h"
  19. #include "attrib.h"
  20. #include "imports.h"
  21. ////////////////////////////////////////////////////////////////////
  22. // Stuff needed for PA_EvalMesh2 ///////////////////////////////////
  23. ////////////////////////////////////////////////////////////////////
  24. #define MV_VERTEX3 0x0001
  25. #define MV_VERTEX4 0x0002
  26. #define MV_NORMAL 0x0004
  27. #define MV_COLOR 0x0008
  28. #define MV_INDEX 0x0010
  29. #define MV_TEXTURE1 0x0020
  30. #define MV_TEXTURE2 0x0040
  31. #define MV_TEXTURE3 0x0080
  32. #define MV_TEXTURE4 0x0100
  33. // Assumption: U is moving, left to right. V is moving top to bottom
  34. #define MV_TOP 0x0001
  35. #define MV_LEFT 0x0002
  36. typedef struct {
  37. __GLcoord vertex;
  38. __GLcoord normal;
  39. __GLcoord texture;
  40. __GLcolor color;
  41. } MESHVERTEX;
  42. #define MAX_MESH_VERTICES MAX_U_SIZE*MAX_V_SIZE
  43. #define MAX_U_SIZE 16
  44. #define MAX_V_SIZE 16
  45. GLubyte *dBufFill; //fill only
  46. GLuint totFillPts;
  47. GLubyte *dBufTopLeft; //for mv_left
  48. GLuint totTopLeftPts;
  49. GLubyte *dBufTopRight; //for non mv_left
  50. GLuint totTopRightPts;
  51. //////////////////////////////////////////////////////////////////////
  52. /// Function Prototypes //////////////////////////////////////////////
  53. //////////////////////////////////////////////////////////////////////
  54. void FASTCALL PADoEval1(__GLcontext *, __GLfloat);
  55. void FASTCALL PADoEval2(__GLcontext *, __GLfloat, __GLfloat);
  56. void FASTCALL PADoEval2VArray(__GLcontext *, __GLfloat, __GLfloat,
  57. MESHVERTEX *, GLuint *);
  58. static void PreEvaluate(GLint , __GLfloat , __GLfloat *);
  59. static void PreEvaluateWithDeriv(GLint, __GLfloat, __GLfloat *, __GLfloat *);
  60. void DoDomain2(__GLevaluatorMachine *, __GLfloat, __GLfloat,
  61. __GLevaluator2 *, __GLfloat *, __GLfloat *);
  62. void DoDomain2WithDerivs(__GLevaluatorMachine *, __GLfloat, __GLfloat,
  63. __GLevaluator2 *, __GLfloat *, __GLfloat *,
  64. __GLfloat *, __GLfloat *);
  65. int FASTCALL genMeshElts (GLenum, GLuint, GLint, GLint, GLubyte *);
  66. void FASTCALL PA_EvalMesh2Fast(__GLcontext *, GLint, GLint, GLint,
  67. GLint, GLint, GLenum, GLuint);
  68. void glcltColor4fv_Eval (__GLfloat *c4);
  69. void glcltIndexf_Eval (__GLfloat ci);
  70. void glcltNormal3fv_Eval(__GLfloat *n3);
  71. void glcltTexCoord1fv_Eval(__GLfloat *t1);
  72. void glcltTexCoord2fv_Eval(__GLfloat *t2);
  73. void glcltTexCoord3fv_Eval(__GLfloat *t3);
  74. void glcltTexCoord4fv_Eval(__GLfloat *t4);
  75. /************************************************************************/
  76. /********************** Client-side entry points ************************/
  77. /********************** for 1-D Evaluators ************************/
  78. /************************************************************************/
  79. void APIENTRY
  80. glcltEvalMesh1 ( IN GLenum mode, IN GLint u1, IN GLint u2 )
  81. {
  82. __GL_SETUP ();
  83. POLYARRAY *pa;
  84. GLenum primType;
  85. GLint i;
  86. WORD flags = (WORD) GET_EVALSTATE (gc);
  87. __GLfloat u;
  88. __GLfloat du;
  89. __GLevaluatorGrid *gu;
  90. // Not allowed in begin/end.
  91. pa = GLTEB_CLTPOLYARRAY();
  92. if (pa->flags & POLYARRAY_IN_BEGIN)
  93. {
  94. GLSETERROR(GL_INVALID_OPERATION);
  95. return;
  96. }
  97. switch(mode)
  98. {
  99. case GL_LINE:
  100. primType = GL_LINE_STRIP;
  101. break;
  102. case GL_POINT:
  103. primType = GL_POINTS;
  104. break;
  105. default:
  106. GLSETERROR(GL_INVALID_ENUM);
  107. return;
  108. }
  109. // if there are any pending API calls that affect the Evaluator state
  110. // then flush the message buffer
  111. if (flags & (__EVALS_AFFECTS_1D_EVAL|
  112. __EVALS_AFFECTS_ALL_EVAL))
  113. glsbAttention();
  114. gu = &gc->state.evaluator.u1;
  115. //du = (gu->finish - gu->start)/(__GLfloat)gu->n;
  116. du = gu->step;
  117. // Call Begin/End.
  118. glcltBegin(primType);
  119. for (i = u1; i <= u2; i++)
  120. {
  121. u = (i == gu->n) ? gu->finish : (gu->start + i * du);
  122. PADoEval1(gc, u);
  123. }
  124. glcltEnd();
  125. }
  126. void APIENTRY
  127. glcltEvalPoint1 ( IN GLint i )
  128. {
  129. __GL_SETUP ();
  130. POLYARRAY *pa;
  131. __GLfloat u;
  132. __GLfloat du;
  133. __GLevaluatorGrid *gu;
  134. // This call has no effect outside begin/end
  135. // (unless it is being compiled).
  136. pa = GLTEB_CLTPOLYARRAY();
  137. if (!(pa->flags & POLYARRAY_IN_BEGIN))
  138. {
  139. return;
  140. }
  141. gu = &gc->state.evaluator.u1;
  142. du = gu->step;
  143. //du = (gu->finish - gu->start)/(__GLfloat)gu->n;
  144. u = (i == gu->n) ? gu->finish : (gu->start + i * du);
  145. PADoEval1(gc, u);
  146. }
  147. void APIENTRY
  148. glcltEvalCoord1f ( IN GLfloat u )
  149. {
  150. __GL_SETUP ();
  151. POLYARRAY *pa;
  152. // This call has no effect outside begin/end
  153. // (unless it is being compiled).
  154. pa = GLTEB_CLTPOLYARRAY();
  155. // If not in Begin-End block, return without doing anything
  156. if (!(pa->flags & POLYARRAY_IN_BEGIN))
  157. {
  158. return;
  159. }
  160. PADoEval1(gc, u);
  161. }
  162. void APIENTRY
  163. glcltEvalCoord1d ( IN GLdouble u )
  164. {
  165. glcltEvalCoord1f((GLfloat) u);
  166. }
  167. void APIENTRY
  168. glcltEvalCoord1dv ( IN const GLdouble u[1] )
  169. {
  170. glcltEvalCoord1f((GLfloat) u[0]);
  171. }
  172. void APIENTRY
  173. glcltEvalCoord1fv ( IN const GLfloat u[1] )
  174. {
  175. glcltEvalCoord1f((GLfloat) u[0]);
  176. }
  177. void APIENTRY
  178. glcltMapGrid1d ( IN GLint un, IN GLdouble u1, IN GLdouble u2 )
  179. {
  180. glcltMapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
  181. }
  182. void APIENTRY
  183. glcltMapGrid1f ( IN GLint un, IN GLfloat u1, IN GLfloat u2 )
  184. {
  185. POLYARRAY *pa;
  186. __GL_SETUP ();
  187. WORD flags = (WORD) GET_EVALSTATE (gc);
  188. // Check if it is called inside a Begin-End block
  189. // If we are already in the begin/end bracket, return an error.
  190. pa = GLTEB_CLTPOLYARRAY();
  191. if (pa->flags & POLYARRAY_IN_BEGIN)
  192. {
  193. GLSETERROR(GL_INVALID_OPERATION);
  194. return;
  195. }
  196. // if there are any pending API calls that affect the Evaluator state
  197. // then flush the message buffer
  198. if (flags & (__EVALS_PUSH_EVAL_ATTRIB | __EVALS_POP_EVAL_ATTRIB))
  199. glsbAttention ();
  200. #ifdef NT
  201. if (un <= 0)
  202. {
  203. __glSetError(GL_INVALID_VALUE);
  204. return;
  205. }
  206. #endif
  207. gc->state.evaluator.u1.start = (__GLfloat)u1;
  208. gc->state.evaluator.u1.finish = (__GLfloat)u2;
  209. gc->state.evaluator.u1.n = un;
  210. gc->state.evaluator.u1.step = ((__GLfloat)u2 - (__GLfloat)u1)/(__GLfloat)un;
  211. }
  212. void APIENTRY
  213. glcltMap1d ( IN GLenum target, IN GLdouble u1, IN GLdouble u2, IN GLint stride, IN GLint order, IN const GLdouble points[] )
  214. {
  215. __GLevaluator1 *ev;
  216. __GLfloat *data;
  217. POLYARRAY *pa;
  218. __GL_SETUP ();
  219. // Check if it is called inside a Begin-End block
  220. // If we are already in the begin/end bracket, return an error.
  221. pa = GLTEB_CLTPOLYARRAY();
  222. if (pa->flags & POLYARRAY_IN_BEGIN)
  223. {
  224. GLSETERROR(GL_INVALID_OPERATION);
  225. return;
  226. }
  227. ev = __glSetUpMap1(gc, target, order, u1, u2);
  228. if (ev == 0) {
  229. return;
  230. }
  231. if (stride < ev->k) {
  232. __glSetError(GL_INVALID_VALUE);
  233. return;
  234. }
  235. data = gc->eval.eval1Data[__GL_EVAL1D_INDEX(target)];
  236. __glFillMap1d(ev->k, order, stride, points, data);
  237. }
  238. void APIENTRY
  239. glcltMap1f ( IN GLenum target, IN GLfloat u1, IN GLfloat u2, IN GLint stride, IN GLint order, IN const GLfloat points[] )
  240. {
  241. __GLevaluator1 *ev;
  242. __GLfloat *data;
  243. POLYARRAY *pa;
  244. __GL_SETUP ();
  245. // Check if it is called inside a Begin-End block
  246. // If we are already in the begin/end bracket, return an error.
  247. pa = GLTEB_CLTPOLYARRAY();
  248. if (pa->flags & POLYARRAY_IN_BEGIN)
  249. {
  250. GLSETERROR(GL_INVALID_OPERATION);
  251. return;
  252. }
  253. ev = __glSetUpMap1(gc, target, order, u1, u2);
  254. if (ev == 0) {
  255. return;
  256. }
  257. if (stride < ev->k) {
  258. __glSetError(GL_INVALID_VALUE);
  259. return;
  260. }
  261. data = gc->eval.eval1Data[__GL_EVAL1D_INDEX(target)];
  262. __glFillMap1f(ev->k, order, stride, points, data);
  263. }
  264. /************************************************************************/
  265. /********************** Client-side entry points ************************/
  266. /********************** for 2-D Evaluators ************************/
  267. /************************************************************************/
  268. void APIENTRY
  269. glcltEvalMesh2 ( IN GLenum mode, IN GLint u1, IN GLint u2, IN GLint v1, IN GLint v2 )
  270. {
  271. POLYARRAY *pa;
  272. GLint i, j, meshSize;
  273. __GL_SETUP();
  274. GLboolean done_v, done_u;
  275. GLint v_beg, v_end, u_beg, u_end, u_len;
  276. GLuint sides;
  277. WORD flags = (WORD) GET_EVALSTATE (gc);
  278. // Flush the command buffer before we start. We need to access the
  279. // latest evaluator states in this function.
  280. // if there are any pending API calls that affect the Evaluator state
  281. // then flush the message buffer
  282. if (flags & (__EVALS_AFFECTS_2D_EVAL|
  283. __EVALS_AFFECTS_ALL_EVAL))
  284. glsbAttention ();
  285. // Not allowed in begin/end.
  286. pa = gc->paTeb;
  287. if (pa->flags & POLYARRAY_IN_BEGIN)
  288. {
  289. GLSETERROR(GL_INVALID_OPERATION);
  290. return;
  291. }
  292. // If vertex map is not enabled, this is a noop.
  293. if (!(gc->state.enables.eval2 & (__GL_MAP2_VERTEX_4_ENABLE |
  294. __GL_MAP2_VERTEX_3_ENABLE)))
  295. return;
  296. // Make sure that the mesh is not empty.
  297. if (u1 > u2 || v1 > v2)
  298. return;
  299. if (mode == GL_FILL && dBufFill == NULL)
  300. {
  301. if (!(dBufFill = (GLubyte *) ALLOC (
  302. 4 * MAX_U_SIZE * MAX_V_SIZE * sizeof (GLubyte))))
  303. {
  304. GLSETERROR(GL_OUT_OF_MEMORY);
  305. return;
  306. }
  307. totFillPts = genMeshElts (GL_FILL, MV_TOP | MV_LEFT, MAX_U_SIZE,
  308. MAX_V_SIZE, dBufFill);
  309. }
  310. if (mode == GL_LINE && dBufTopLeft == NULL)
  311. {
  312. if (!(dBufTopLeft = (GLubyte *) ALLOC (
  313. 2 * 4 * MAX_U_SIZE * MAX_V_SIZE * sizeof (GLubyte))))
  314. {
  315. GLSETERROR(GL_OUT_OF_MEMORY);
  316. return;
  317. }
  318. dBufTopRight = &dBufTopLeft[4 * MAX_U_SIZE * MAX_V_SIZE];
  319. totTopLeftPts = genMeshElts (GL_LINE, MV_TOP | MV_LEFT, MAX_U_SIZE,
  320. MAX_V_SIZE, dBufTopLeft);
  321. totTopRightPts = genMeshElts (GL_LINE, MV_TOP, MAX_U_SIZE, MAX_V_SIZE,
  322. dBufTopRight);
  323. }
  324. switch(mode)
  325. {
  326. case GL_POINT:
  327. glcltBegin(GL_POINTS);
  328. for (i = v1; i <= v2; i++)
  329. for (j = u1; j <= u2; j++)
  330. glcltEvalPoint2(j, i);
  331. glcltEnd();
  332. break ;
  333. case GL_LINE:
  334. case GL_FILL: // the sides argument in the fastcall is ignored
  335. meshSize = (u2 - u1 + 1)*(v2 - v1 + 1);
  336. if (meshSize <= MAX_MESH_VERTICES)
  337. PA_EvalMesh2Fast(gc, u1, u2, v1, v2, meshSize, mode,
  338. (GLubyte) 15);
  339. else {
  340. u_beg = u1;
  341. u_end = u_beg + MAX_U_SIZE - 1;
  342. done_u = GL_FALSE;
  343. while (!done_u) { //Along U side
  344. if(u_end >= u2) {
  345. u_end = u2;
  346. done_u = GL_TRUE;
  347. }
  348. u_len = u_end - u_beg + 1;
  349. v_beg = v1;
  350. v_end = v_beg + MAX_V_SIZE - 1;
  351. done_v = GL_FALSE;
  352. while(!done_v) { //Along V side
  353. if(v_end >= v2) {
  354. v_end = v2;
  355. done_v = GL_TRUE;
  356. }
  357. meshSize = u_len*(v_end - v_beg + 1);
  358. sides = 0;
  359. if (u_beg == u1)
  360. sides |= MV_LEFT;
  361. if (v_beg == v1)
  362. sides |= MV_TOP;
  363. PA_EvalMesh2Fast(gc, u_beg, u_end,
  364. v_beg, v_end, meshSize, mode, sides);
  365. v_beg = v_end;
  366. v_end = v_beg+MAX_V_SIZE-1;
  367. }
  368. u_beg = u_end;
  369. u_end = u_beg + MAX_U_SIZE - 1;
  370. }
  371. }
  372. break ;
  373. default:
  374. GLSETERROR(GL_INVALID_ENUM);
  375. return;
  376. }
  377. }
  378. void APIENTRY
  379. glcltEvalCoord2f ( IN GLfloat u, IN GLfloat v )
  380. {
  381. __GL_SETUP ();
  382. POLYARRAY *pa;
  383. // This call has no effect outside begin/end
  384. // (unless it is being compiled).
  385. pa = GLTEB_CLTPOLYARRAY();
  386. if (!(pa->flags & POLYARRAY_IN_BEGIN))
  387. {
  388. return;
  389. }
  390. PADoEval2(gc, u, v);
  391. }
  392. void APIENTRY
  393. glcltEvalCoord2d ( IN GLdouble u, IN GLdouble v )
  394. {
  395. glcltEvalCoord2f((GLfloat) u, (GLfloat) v);
  396. }
  397. void APIENTRY
  398. glcltEvalCoord2dv ( IN const GLdouble u[2] )
  399. {
  400. glcltEvalCoord2f((GLfloat) u[0], (GLfloat) u[1]);
  401. }
  402. void APIENTRY
  403. glcltEvalCoord2fv ( IN const GLfloat u[2] )
  404. {
  405. glcltEvalCoord2f((GLfloat) u[0], (GLfloat) u[1]);
  406. }
  407. void APIENTRY
  408. glcltEvalPoint2 ( IN GLint i, IN GLint j )
  409. {
  410. __GL_SETUP ();
  411. POLYARRAY *pa;
  412. __GLfloat u, v;
  413. __GLfloat du, dv;
  414. __GLevaluatorGrid *gu;
  415. __GLevaluatorGrid *gv;
  416. // This call has no effect outside begin/end
  417. // (unless it is being compiled).
  418. pa = GLTEB_CLTPOLYARRAY();
  419. if (!(pa->flags & POLYARRAY_IN_BEGIN))
  420. {
  421. return;
  422. }
  423. gu = &gc->state.evaluator.u2;
  424. gv = &gc->state.evaluator.v2;
  425. du = gu->step;
  426. dv = gv->step;
  427. //du = (gu->finish - gu->start)/(__GLfloat)gu->n;
  428. //dv = (gv->finish - gv->start)/(__GLfloat)gv->n;
  429. u = (i == gu->n) ? gu->finish : (gu->start + i * du);
  430. v = (j == gv->n) ? gv->finish : (gv->start + j * dv);
  431. PADoEval2 (gc, u, v);
  432. }
  433. void APIENTRY
  434. glcltMapGrid2d ( IN GLint un, IN GLdouble u1, IN GLdouble u2, IN GLint vn, IN GLdouble v1, IN GLdouble v2 )
  435. {
  436. glcltMapGrid2f(un, (GLfloat) u1, (GLfloat) u2, vn, (GLfloat) v1, (GLfloat) v2);
  437. }
  438. void APIENTRY
  439. glcltMapGrid2f ( IN GLint un, IN GLfloat u1, IN GLfloat u2, IN GLint vn, IN GLfloat v1, IN GLfloat v2 )
  440. {
  441. POLYARRAY *pa;
  442. __GL_SETUP ();
  443. WORD flags = (WORD) GET_EVALSTATE (gc);
  444. // Check if it is called inside a Begin-End block
  445. // If we are already in the begin/end bracket, return an error.
  446. pa = GLTEB_CLTPOLYARRAY();
  447. if (pa->flags & POLYARRAY_IN_BEGIN)
  448. {
  449. GLSETERROR(GL_INVALID_OPERATION);
  450. return;
  451. }
  452. // if there are any pending API calls that affect the Evaluator state
  453. // then flush the message buffer
  454. if (flags & (__EVALS_PUSH_EVAL_ATTRIB|
  455. __EVALS_POP_EVAL_ATTRIB))
  456. glsbAttention ();
  457. #ifdef NT
  458. if (un <= 0 || vn <= 0)
  459. {
  460. __glSetError(GL_INVALID_VALUE);
  461. return;
  462. }
  463. #endif
  464. gc->state.evaluator.u2.start = (__GLfloat)u1;
  465. gc->state.evaluator.u2.finish = (__GLfloat)u2;
  466. gc->state.evaluator.u2.n = un;
  467. gc->state.evaluator.u2.step = ((__GLfloat)u2 - (__GLfloat)u1)/(__GLfloat)un;
  468. gc->state.evaluator.v2.start = (__GLfloat)v1;
  469. gc->state.evaluator.v2.finish = (__GLfloat)v2;
  470. gc->state.evaluator.v2.n = vn;
  471. gc->state.evaluator.v2.step = ((__GLfloat)v2 - (__GLfloat)v1)/(__GLfloat)vn;
  472. }
  473. void APIENTRY
  474. glcltMap2d ( IN GLenum target, IN GLdouble u1, IN GLdouble u2, IN GLint ustride, IN GLint uorder, IN GLdouble v1, IN GLdouble v2, IN GLint vstride, IN GLint vorder, IN const GLdouble points[] )
  475. {
  476. __GLevaluator2 *ev;
  477. __GLfloat *data;
  478. POLYARRAY *pa;
  479. __GL_SETUP ();
  480. // Check if it is called inside a Begin-End block
  481. // If we are already in the begin/end bracket, return an error.
  482. pa = GLTEB_CLTPOLYARRAY();
  483. if (pa->flags & POLYARRAY_IN_BEGIN)
  484. {
  485. GLSETERROR(GL_INVALID_OPERATION);
  486. return;
  487. }
  488. ev = __glSetUpMap2(gc, target, uorder, vorder, u1, u2, v1, v2);
  489. if (ev == 0) {
  490. return;
  491. }
  492. if (ustride < ev->k) {
  493. __glSetError(GL_INVALID_VALUE);
  494. return;
  495. }
  496. if (vstride < ev->k) {
  497. __glSetError(GL_INVALID_VALUE);
  498. return;
  499. }
  500. data = gc->eval.eval2Data[__GL_EVAL2D_INDEX(target)];
  501. __glFillMap2d(ev->k, uorder, vorder, ustride, vstride,
  502. points, data);
  503. }
  504. void APIENTRY
  505. glcltMap2f ( IN GLenum target, IN GLfloat u1, IN GLfloat u2, IN GLint ustride, IN GLint uorder, IN GLfloat v1, IN GLfloat v2, IN GLint vstride, IN GLint vorder, IN const GLfloat points[] )
  506. {
  507. __GLevaluator2 *ev;
  508. __GLfloat *data;
  509. POLYARRAY *pa;
  510. __GL_SETUP ();
  511. // Check if it is called inside a Begin-End block
  512. // If we are already in the begin/end bracket, return an error.
  513. pa = GLTEB_CLTPOLYARRAY();
  514. if (pa->flags & POLYARRAY_IN_BEGIN)
  515. {
  516. GLSETERROR(GL_INVALID_OPERATION);
  517. return;
  518. }
  519. ev = __glSetUpMap2(gc, target, uorder, vorder, u1, u2, v1, v2);
  520. if (ev == 0) {
  521. return;
  522. }
  523. if (ustride < ev->k) {
  524. __glSetError(GL_INVALID_VALUE);
  525. return;
  526. }
  527. if (vstride < ev->k) {
  528. __glSetError(GL_INVALID_VALUE);
  529. return;
  530. }
  531. data = gc->eval.eval2Data[__GL_EVAL2D_INDEX(target)];
  532. __glFillMap2f(ev->k, uorder, vorder, ustride, vstride,
  533. points, data);
  534. }
  535. /************************************************************************/
  536. /********************** Evaluator helper functions **********************/
  537. /********************** taken from so_eval.c **********************/
  538. /************************************************************************/
  539. GLint FASTCALL __glEvalComputeK(GLenum target)
  540. {
  541. switch(target) {
  542. case GL_MAP1_VERTEX_4:
  543. case GL_MAP1_COLOR_4:
  544. case GL_MAP1_TEXTURE_COORD_4:
  545. case GL_MAP2_VERTEX_4:
  546. case GL_MAP2_COLOR_4:
  547. case GL_MAP2_TEXTURE_COORD_4:
  548. return 4;
  549. case GL_MAP1_VERTEX_3:
  550. case GL_MAP1_TEXTURE_COORD_3:
  551. case GL_MAP1_NORMAL:
  552. case GL_MAP2_VERTEX_3:
  553. case GL_MAP2_TEXTURE_COORD_3:
  554. case GL_MAP2_NORMAL:
  555. return 3;
  556. case GL_MAP1_TEXTURE_COORD_2:
  557. case GL_MAP2_TEXTURE_COORD_2:
  558. return 2;
  559. case GL_MAP1_TEXTURE_COORD_1:
  560. case GL_MAP2_TEXTURE_COORD_1:
  561. case GL_MAP1_INDEX:
  562. case GL_MAP2_INDEX:
  563. return 1;
  564. default:
  565. return -1;
  566. }
  567. }
  568. void ComputeNormal2(__GLcontext *gc, __GLfloat *n, __GLfloat *pu,
  569. __GLfloat *pv)
  570. {
  571. n[0] = pu[1]*pv[2] - pu[2]*pv[1];
  572. n[1] = pu[2]*pv[0] - pu[0]*pv[2];
  573. n[2] = pu[0]*pv[1] - pu[1]*pv[0];
  574. #ifdef NT
  575. // Only need to normalize auto normals if normalization is not enabled!
  576. if (!(gc->state.enables.general & __GL_NORMALIZE_ENABLE))
  577. #endif
  578. __glNormalize(n, n);
  579. }
  580. void ComputeFirstPartials(__GLfloat *p, __GLfloat *pu, __GLfloat *pv)
  581. {
  582. pu[0] = pu[0]*p[3] - pu[3]*p[0];
  583. pu[1] = pu[1]*p[3] - pu[3]*p[1];
  584. pu[2] = pu[2]*p[3] - pu[3]*p[2];
  585. pv[0] = pv[0]*p[3] - pv[3]*p[0];
  586. pv[1] = pv[1]*p[3] - pv[3]*p[1];
  587. pv[2] = pv[2]*p[3] - pv[3]*p[2];
  588. }
  589. /*
  590. ** define a one dimensional map
  591. */
  592. __GLevaluator1 *__glSetUpMap1(__GLcontext *gc, GLenum type,
  593. GLint order, __GLfloat u1, __GLfloat u2)
  594. {
  595. __GLevaluator1 *ev;
  596. __GLfloat **evData;
  597. __GLfloat *pevData;
  598. switch (type)
  599. {
  600. case GL_MAP1_COLOR_4:
  601. case GL_MAP1_INDEX:
  602. case GL_MAP1_NORMAL:
  603. case GL_MAP1_TEXTURE_COORD_1:
  604. case GL_MAP1_TEXTURE_COORD_2:
  605. case GL_MAP1_TEXTURE_COORD_3:
  606. case GL_MAP1_TEXTURE_COORD_4:
  607. case GL_MAP1_VERTEX_3:
  608. case GL_MAP1_VERTEX_4:
  609. ev = &gc->eval.eval1[__GL_EVAL1D_INDEX(type)];
  610. evData = &gc->eval.eval1Data[__GL_EVAL1D_INDEX(type)];
  611. break;
  612. default:
  613. __glSetError(GL_INVALID_ENUM);
  614. return 0;
  615. }
  616. if (u1 == u2 || order < 1 || order > gc->constants.maxEvalOrder)
  617. {
  618. __glSetError(GL_INVALID_VALUE);
  619. return 0;
  620. }
  621. pevData = (__GLfloat *)
  622. GCREALLOC(gc, *evData,
  623. (__glMap1_size(ev->k, order) * sizeof(__GLfloat)));
  624. if (!pevData)
  625. {
  626. __glSetError(GL_OUT_OF_MEMORY);
  627. return 0;
  628. }
  629. *evData = pevData;
  630. ev->order = order;
  631. ev->u1 = u1;
  632. ev->u2 = u2;
  633. return ev;
  634. }
  635. /*
  636. ** define a two dimensional map
  637. */
  638. __GLevaluator2 *__glSetUpMap2(__GLcontext *gc, GLenum type,
  639. GLint majorOrder, GLint minorOrder,
  640. __GLfloat u1, __GLfloat u2,
  641. __GLfloat v1, __GLfloat v2)
  642. {
  643. __GLevaluator2 *ev;
  644. __GLfloat **evData;
  645. __GLfloat *pevData;
  646. switch (type) {
  647. case GL_MAP2_COLOR_4:
  648. case GL_MAP2_INDEX:
  649. case GL_MAP2_NORMAL:
  650. case GL_MAP2_TEXTURE_COORD_1:
  651. case GL_MAP2_TEXTURE_COORD_2:
  652. case GL_MAP2_TEXTURE_COORD_3:
  653. case GL_MAP2_TEXTURE_COORD_4:
  654. case GL_MAP2_VERTEX_3:
  655. case GL_MAP2_VERTEX_4:
  656. ev = &gc->eval.eval2[__GL_EVAL2D_INDEX(type)];
  657. evData = &gc->eval.eval2Data[__GL_EVAL2D_INDEX(type)];
  658. break;
  659. default:
  660. __glSetError(GL_INVALID_ENUM);
  661. return 0;
  662. }
  663. if (minorOrder < 1 || minorOrder > gc->constants.maxEvalOrder ||
  664. majorOrder < 1 || majorOrder > gc->constants.maxEvalOrder ||
  665. u1 == u2 || v1 == v2)
  666. {
  667. __glSetError(GL_INVALID_VALUE);
  668. return 0;
  669. }
  670. pevData = (__GLfloat *)
  671. GCREALLOC(gc, *evData,
  672. (__glMap2_size(ev->k, majorOrder, minorOrder)
  673. * sizeof(__GLfloat)));
  674. if (!pevData)
  675. {
  676. __glSetError(GL_OUT_OF_MEMORY);
  677. return 0;
  678. }
  679. *evData = pevData;
  680. ev->majorOrder = majorOrder;
  681. ev->minorOrder = minorOrder;
  682. ev->u1 = u1;
  683. ev->u2 = u2;
  684. ev->v1 = v1;
  685. ev->v2 = v2;
  686. return ev;
  687. }
  688. /*
  689. ** Fill our data from user data
  690. */
  691. void APIPRIVATE __glFillMap1f(GLint k, GLint order, GLint stride,
  692. const GLfloat *points, __GLfloat *data)
  693. {
  694. int i,j;
  695. #ifndef __GL_DOUBLE
  696. /* Optimization always hit during display list execution */
  697. if (k == stride)
  698. {
  699. __GL_MEMCOPY(data, points,
  700. __glMap1_size(k, order) * sizeof(__GLfloat));
  701. return;
  702. }
  703. #endif
  704. for (i=0; i<order; i++)
  705. {
  706. for (j=0; j<k; j++)
  707. {
  708. data[j] = points[j];
  709. }
  710. points += stride;
  711. data += k;
  712. }
  713. }
  714. void APIPRIVATE __glFillMap1d(GLint k, GLint order, GLint stride,
  715. const GLdouble *points, __GLfloat *data)
  716. {
  717. int i,j;
  718. for (i=0; i<order; i++)
  719. {
  720. for (j=0; j<k; j++)
  721. {
  722. data[j] = points[j];
  723. }
  724. points += stride;
  725. data += k;
  726. }
  727. }
  728. void APIPRIVATE __glFillMap2f(GLint k, GLint majorOrder, GLint minorOrder,
  729. GLint majorStride, GLint minorStride,
  730. const GLfloat *points, __GLfloat *data)
  731. {
  732. int i,j,x;
  733. #ifndef __GL_DOUBLE
  734. /* Optimization always hit during display list execution */
  735. if (k == minorStride && majorStride == k * minorOrder)
  736. {
  737. __GL_MEMCOPY(data, points,
  738. __glMap2_size(k, majorOrder, minorOrder) * sizeof(__GLfloat));
  739. return;
  740. }
  741. #endif
  742. for (i=0; i<majorOrder; i++)
  743. {
  744. for (j=0; j<minorOrder; j++)
  745. {
  746. for (x=0; x<k; x++)
  747. {
  748. data[x] = points[x];
  749. }
  750. points += minorStride;
  751. data += k;
  752. }
  753. points += majorStride - minorStride * minorOrder;
  754. }
  755. }
  756. void APIPRIVATE __glFillMap2d(GLint k, GLint majorOrder, GLint minorOrder,
  757. GLint majorStride, GLint minorStride,
  758. const GLdouble *points, __GLfloat *data)
  759. {
  760. int i,j,x;
  761. for (i=0; i<majorOrder; i++)
  762. {
  763. for (j=0; j<minorOrder; j++)
  764. {
  765. for (x=0; x<k; x++)
  766. {
  767. data[x] = points[x];
  768. }
  769. points += minorStride;
  770. data += k;
  771. }
  772. points += majorStride - minorStride * minorOrder;
  773. }
  774. }
  775. #define TYPE_COEFF_AND_DERIV 1
  776. #define TYPE_COEFF 2
  777. void DoDomain1(__GLevaluatorMachine *em, __GLfloat u, __GLevaluator1 *e,
  778. __GLfloat *v, __GLfloat *baseData)
  779. {
  780. GLint j, row;
  781. __GLfloat uprime;
  782. __GLfloat *data;
  783. GLint k;
  784. #ifdef NT
  785. ASSERTOPENGL(e->u2 != e->u1, "Assert in DoDomain1 failed\n");
  786. // assert(e->u2 != e->u1);
  787. #else
  788. if(e->u2 == e->u1)
  789. return;
  790. #endif
  791. uprime = (u - e->u1) / (e->u2 - e->u1);
  792. /* Use already cached values if possible */
  793. if (em->uvalue != uprime || em->uorder != e->order)
  794. {
  795. /* Compute coefficients for values */
  796. PreEvaluate(e->order, uprime, em->ucoeff);
  797. em->utype = TYPE_COEFF;
  798. em->uorder = e->order;
  799. em->uvalue = uprime;
  800. }
  801. k=e->k;
  802. for (j = 0; j < k; j++)
  803. {
  804. data=baseData+j;
  805. v[j] = 0;
  806. for (row = 0; row < e->order; row++)
  807. {
  808. v[j] += em->ucoeff[row] * (*data);
  809. data += k;
  810. }
  811. }
  812. }
  813. // Helper Macro used in PADoEval1 and PADoEval2
  814. #ifdef __NO_OPTIMIZE_FOR_DLIST
  815. #define PropagateToNextPolyData (eval, pa) \
  816. { \
  817. if ((gc)->eval.accFlags & EVAL_COLOR_VALID) \
  818. { \
  819. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_COLOR; \
  820. if ((gc)->modes.colorIndexMode) \
  821. glcltIndexf_InCI((gc)->eval.color.r); \
  822. else \
  823. glcltColor4f_InRGBA ((gc)->eval.color.r, \
  824. (gc)->eval.color.g, \
  825. (gc)->eval.color.b, \
  826. (gc)->eval.color.a); \
  827. } \
  828. \
  829. if ((gc)->eval.accFlags & EVAL_NORMAL_VALID) \
  830. { \
  831. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_NORMAL; \
  832. glcltNormal3f ((gc)->eval.normal.x, \
  833. (gc)->eval.normal.y, \
  834. (gc)->eval.normal.z); \
  835. } \
  836. \
  837. if ((gc)->eval.accFlags & EVAL_TEXTURE_VALID) \
  838. { \
  839. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_TEXCOORD; \
  840. if (__GL_FLOAT_COMPARE_PONE((gc)->eval.texture.w, !=)) \
  841. glcltTexCoord4f ((gc)->eval.texture.x, \
  842. (gc)->eval.texture.y, \
  843. (gc)->eval.texture.z, \
  844. (gc)->eval.texture.w); \
  845. else if (__GL_FLOAT_NEZ((gc)->eval.texture.z)) \
  846. glcltTexCoord3f ((gc)->eval.texture.x, \
  847. (gc)->eval.texture.y, \
  848. (gc)->eval.texture.z); \
  849. else if (__GL_FLOAT_NEZ((gc)->eval.texture.y)) \
  850. glcltTexCoord2f ((gc)->eval.texture.x, \
  851. (gc)->eval.texture.y); \
  852. else \
  853. glcltTexCoord1f ((gc)->eval.texture.x); \
  854. } \
  855. }
  856. #else
  857. #define PropagateToNextPolyData(eval,pa) \
  858. \
  859. if ((gc)->eval.accFlags & EVAL_COLOR_VALID) \
  860. { \
  861. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_COLOR; \
  862. if ((gc)->modes.colorIndexMode) \
  863. glcltIndexf_InCI((gc)->eval.color.r); \
  864. else \
  865. glcltColor4f_InRGBA ((gc)->eval.color.r, \
  866. (gc)->eval.color.g, \
  867. (gc)->eval.color.b, \
  868. (gc)->eval.color.a); \
  869. } \
  870. \
  871. if ((gc)->eval.accFlags & EVAL_NORMAL_VALID) \
  872. { \
  873. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_NORMAL; \
  874. glcltNormal3f ((gc)->eval.normal.x, \
  875. (gc)->eval.normal.y, \
  876. (gc)->eval.normal.z); \
  877. } \
  878. \
  879. if ((gc)->eval.accFlags & EVAL_TEXTURE_VALID) \
  880. { \
  881. (pa)->pdNextVertex->flags &= ~POLYDATA_EVAL_TEXCOORD; \
  882. glcltTexCoord4f ((gc)->eval.texture.x, \
  883. (gc)->eval.texture.y, \
  884. (gc)->eval.texture.z, \
  885. (gc)->eval.texture.w); \
  886. }
  887. #endif
  888. //////////////////////////////////////////////////////
  889. // Assuming that the latest State is available here //
  890. //////////////////////////////////////////////////////
  891. void FASTCALL PADoEval1(__GLcontext *gc, __GLfloat u)
  892. {
  893. __GLevaluator1 *eval;
  894. __GLfloat **evalData;
  895. __GLevaluatorMachine em;
  896. __GLfloat v4[4];
  897. __GLfloat n3[3];
  898. __GLfloat t4[4];
  899. __GLfloat c4[4];
  900. __GLfloat ci;
  901. POLYARRAY *pa;
  902. pa = gc->paTeb;
  903. eval = gc->eval.eval1;
  904. evalData = gc->eval.eval1Data;
  905. em = gc->eval;
  906. // Initialize the flag
  907. gc->eval.accFlags = 0;
  908. // Evaluated color, index, normal and texture coords are ignored
  909. // in selection
  910. if ((gc->renderMode != GL_SELECT) &&
  911. (gc->state.enables.eval1 & (__GL_MAP1_VERTEX_4_ENABLE |
  912. __GL_MAP1_VERTEX_3_ENABLE ))
  913. )
  914. {
  915. if (gc->modes.colorIndexMode)
  916. {
  917. if (!(gc->state.enables.general & __GL_LIGHTING_ENABLE))
  918. {
  919. if (gc->state.enables.eval1 & __GL_MAP1_INDEX_ENABLE)
  920. {
  921. DoDomain1(&em, u, &eval[__GL_I], &ci, evalData[__GL_I]);
  922. glcltIndexf_Eval(ci);
  923. }
  924. }
  925. }
  926. else
  927. {
  928. if (gc->state.enables.eval1 & __GL_MAP1_COLOR_4_ENABLE)
  929. {
  930. // NOTE: In OpenGL 1.0, color material does not apply to
  931. // evaluated colors.
  932. // In OpenGL 1.1, this behavior was changed.
  933. // This (1.1) code assumes that ColorMaterial applies to
  934. // evaluated colors to simplify the graphics pipeline.
  935. // Otherwise, the evaluated colors have no effect when
  936. // lighting is enabled.
  937. DoDomain1(&em, u, &eval[__GL_C4], c4, evalData[__GL_C4]);
  938. // If some color is set in the current polydata, then
  939. // Save it in a temporary buffer and call glcltColor later
  940. // Also make sure that the current-color pointer is updated
  941. // appropriately
  942. glcltColor4fv_Eval(c4);
  943. }
  944. if (gc->state.enables.eval1 & __GL_MAP1_TEXTURE_COORD_4_ENABLE)
  945. {
  946. DoDomain1(&em, u, &eval[__GL_T4], t4, evalData[__GL_T4]);
  947. glcltTexCoord4fv_Eval(t4);
  948. }
  949. else if (gc->state.enables.eval1 &
  950. __GL_MAP1_TEXTURE_COORD_3_ENABLE)
  951. {
  952. DoDomain1(&em, u, &eval[__GL_T3], t4, evalData[__GL_T3]);
  953. glcltTexCoord3fv_Eval(t4);
  954. }
  955. else if (gc->state.enables.eval1 &
  956. __GL_MAP1_TEXTURE_COORD_2_ENABLE)
  957. {
  958. DoDomain1(&em, u, &eval[__GL_T2], t4, evalData[__GL_T2]);
  959. glcltTexCoord2fv_Eval(t4);
  960. }
  961. else if (gc->state.enables.eval1 &
  962. __GL_MAP1_TEXTURE_COORD_1_ENABLE)
  963. {
  964. DoDomain1(&em, u, &eval[__GL_T1], t4, evalData[__GL_T1]);
  965. glcltTexCoord1fv_Eval(t4);
  966. }
  967. }
  968. if (gc->state.enables.eval1 & __GL_MAP1_NORMAL_ENABLE)
  969. {
  970. DoDomain1(&em, u, &eval[__GL_N3], n3, evalData[__GL_N3]);
  971. glcltNormal3fv_Eval(n3);
  972. }
  973. }
  974. /* Vertex */
  975. if (gc->state.enables.eval1 & __GL_MAP1_VERTEX_4_ENABLE)
  976. {
  977. DoDomain1(&em, u, &eval[__GL_V4], v4, evalData[__GL_V4]);
  978. glcltVertex4fv (v4);
  979. }
  980. else if (gc->state.enables.eval1 & __GL_MAP1_VERTEX_3_ENABLE)
  981. {
  982. DoDomain1(&em, u, &eval[__GL_V3], v4, evalData[__GL_V3]);
  983. glcltVertex3fv (v4);
  984. }
  985. // If there are any prior glcltColor, glcltIndex, glcltTexCoord
  986. // or glcltNormal calls. The values are saved in gc->eval. Use
  987. // these and propagate them, to the next PolyData
  988. PropagateToNextPolyData (eval, pa);
  989. }
  990. // Compute the color, texture, normal, vertex based upon u and v.
  991. //
  992. // NOTE: This function is called by the client side EvalMesh2 functions.
  993. // If you modify it, make sure that you modify the callers too!
  994. //////////////////////////////////////////////////////
  995. // Assuming that the latest State is available here //
  996. //////////////////////////////////////////////////////
  997. void FASTCALL PADoEval2(__GLcontext *gc, __GLfloat u, __GLfloat v)
  998. {
  999. __GLevaluator2 *eval = gc->eval.eval2;
  1000. __GLfloat **evalData = gc->eval.eval2Data;
  1001. __GLevaluatorMachine em = gc->eval;
  1002. __GLfloat v4[4];
  1003. __GLfloat n3[3];
  1004. __GLfloat t4[4];
  1005. __GLfloat c4[4];
  1006. __GLfloat ci;
  1007. POLYARRAY *pa;
  1008. pa = gc->paTeb;
  1009. // Mark this PolyArray to indicate that it has a Evaluator vertex
  1010. // pa->flags |= POLYARRAY_EVALCOORD;
  1011. // Evaluated colors, normals and texture coords are ignored in selection.
  1012. if (gc->renderMode == GL_SELECT)
  1013. {
  1014. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1015. {
  1016. DoDomain2(&em, u, v, &eval[__GL_V4], v4, evalData[__GL_V4]);
  1017. glcltVertex4fv (v4);
  1018. }
  1019. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1020. {
  1021. DoDomain2(&em, u, v, &eval[__GL_V3], v4, evalData[__GL_V3]);
  1022. glcltVertex3fv (v4);
  1023. }
  1024. return;
  1025. }
  1026. if (gc->state.enables.eval2 & (__GL_MAP2_VERTEX_3_ENABLE |
  1027. __GL_MAP2_VERTEX_4_ENABLE))
  1028. {
  1029. if (gc->modes.colorIndexMode)
  1030. {
  1031. if (!(gc->state.enables.general & __GL_LIGHTING_ENABLE))
  1032. {
  1033. if (gc->state.enables.eval2 & __GL_MAP2_INDEX_ENABLE)
  1034. {
  1035. DoDomain2(&em, u, v, &eval[__GL_I], &ci, evalData[__GL_I]);
  1036. glcltIndexf_Eval(ci);
  1037. }
  1038. }
  1039. }
  1040. else
  1041. {
  1042. if (gc->state.enables.eval2 & __GL_MAP2_COLOR_4_ENABLE)
  1043. {
  1044. DoDomain2(&em, u, v, &eval[__GL_C4], c4, evalData[__GL_C4]);
  1045. glcltColor4fv_Eval(c4);
  1046. }
  1047. if (gc->state.enables.eval2 & __GL_MAP2_TEXTURE_COORD_4_ENABLE)
  1048. {
  1049. DoDomain2(&em, u, v, &eval[__GL_T4], t4, evalData[__GL_T4]);
  1050. glcltTexCoord4fv_Eval(t4);
  1051. }
  1052. else if (gc->state.enables.eval2 &
  1053. __GL_MAP2_TEXTURE_COORD_3_ENABLE)
  1054. {
  1055. DoDomain2(&em, u, v, &eval[__GL_T3], t4, evalData[__GL_T3]);
  1056. glcltTexCoord3fv_Eval(t4);
  1057. }
  1058. else if (gc->state.enables.eval2 &
  1059. __GL_MAP2_TEXTURE_COORD_2_ENABLE)
  1060. {
  1061. DoDomain2(&em, u, v, &eval[__GL_T2], t4, evalData[__GL_T2]);
  1062. glcltTexCoord2fv_Eval(t4);
  1063. }
  1064. else if (gc->state.enables.eval2 &
  1065. __GL_MAP2_TEXTURE_COORD_1_ENABLE)
  1066. {
  1067. DoDomain2(&em, u, v, &eval[__GL_T1], t4, evalData[__GL_T1]);
  1068. glcltTexCoord1fv_Eval(t4);
  1069. }
  1070. }
  1071. if (gc->state.enables.general & __GL_AUTO_NORMAL_ENABLE)
  1072. {
  1073. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1074. {
  1075. __GLfloat du[4];
  1076. __GLfloat dv[4];
  1077. DoDomain2WithDerivs(&em, u, v, &eval[__GL_V4], v4, du, dv,
  1078. evalData[__GL_V4]);
  1079. ComputeFirstPartials(v4, du, dv);
  1080. ComputeNormal2(gc, n3, du, dv);
  1081. glcltNormal3fv_Eval(n3);
  1082. glcltVertex4fv(v4);
  1083. }
  1084. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1085. {
  1086. __GLfloat du[3];
  1087. __GLfloat dv[3];
  1088. DoDomain2WithDerivs(&em, u, v, &eval[__GL_V3], v4, du, dv,
  1089. evalData[__GL_V3]);
  1090. ComputeNormal2(gc, n3, du, dv);
  1091. glcltNormal3fv_Eval(n3);
  1092. glcltVertex3fv(v4);
  1093. }
  1094. }
  1095. else
  1096. {
  1097. if (gc->state.enables.eval2 & __GL_MAP2_NORMAL_ENABLE)
  1098. {
  1099. DoDomain2(&em, u, v, &eval[__GL_N3], n3, evalData[__GL_N3]);
  1100. glcltNormal3fv_Eval(n3);
  1101. }
  1102. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1103. {
  1104. DoDomain2(&em, u, v, &eval[__GL_V4], v4, evalData[__GL_V4]);
  1105. glcltVertex4fv(v4);
  1106. }
  1107. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1108. {
  1109. DoDomain2(&em, u, v, &eval[__GL_V3], v4, evalData[__GL_V3]);
  1110. glcltVertex3fv(v4);
  1111. }
  1112. }
  1113. }
  1114. // If there are any prior glcltColor, glcltIndex, glcltTexCoord
  1115. // or glcltNormal calls. The values are saved in gc->eval. Use
  1116. // these and propagate them, to the next PolyData
  1117. PropagateToNextPolyData (eval, pa);
  1118. }
  1119. #define COPYMESHVERTEX(m,v) \
  1120. { \
  1121. (m)->vertex.x = (v)[0]; \
  1122. (m)->vertex.y = (v)[1]; \
  1123. (m)->vertex.z = (v)[2]; \
  1124. (m)->vertex.w = (v)[3]; \
  1125. }
  1126. #define COPYMESHNORMAL(m,n) \
  1127. { \
  1128. (m)->normal.x = (n)[0]; \
  1129. (m)->normal.y = (n)[1]; \
  1130. (m)->normal.z = (n)[2]; \
  1131. }
  1132. #define COPYMESHCOLOR(m,c) \
  1133. { \
  1134. (m)->color.r = (c)[0]; \
  1135. (m)->color.g = (c)[1]; \
  1136. (m)->color.b = (c)[2]; \
  1137. (m)->color.a = (c)[3]; \
  1138. }
  1139. #define COPYMESHTEXTURE(m,t) \
  1140. { \
  1141. (m)->texture.x = (t)[0]; \
  1142. (m)->texture.y = (t)[1]; \
  1143. (m)->texture.z = (t)[2]; \
  1144. (m)->texture.w = (t)[3]; \
  1145. }
  1146. //////////////////////////////////////////////////////
  1147. // Assuming that the latest State is available here //
  1148. //////////////////////////////////////////////////////
  1149. void FASTCALL PADoEval2VArray(__GLcontext *gc, __GLfloat u, __GLfloat v,
  1150. MESHVERTEX *mv, GLuint *flags)
  1151. {
  1152. __GLevaluator2 *eval = gc->eval.eval2;
  1153. __GLfloat **evalData = gc->eval.eval2Data;
  1154. __GLevaluatorMachine em = gc->eval;
  1155. __GLfloat v4[4];
  1156. __GLfloat n3[3];
  1157. __GLfloat t4[4];
  1158. __GLfloat c4[4];
  1159. __GLfloat ci;
  1160. // Evaluated colors, normals and texture coords are ignored in selection.
  1161. if (gc->renderMode == GL_SELECT)
  1162. {
  1163. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1164. {
  1165. DoDomain2(&em, u, v, &eval[__GL_V4], v4, evalData[__GL_V4]);
  1166. *flags = *flags | MV_VERTEX4;
  1167. }
  1168. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1169. {
  1170. DoDomain2(&em, u, v, &eval[__GL_V3], v4, evalData[__GL_V3]);
  1171. *flags = *flags | MV_VERTEX3;
  1172. }
  1173. COPYMESHVERTEX (mv, v4);
  1174. return;
  1175. }
  1176. if (gc->state.enables.general & __GL_AUTO_NORMAL_ENABLE)
  1177. {
  1178. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1179. {
  1180. __GLfloat du[4];
  1181. __GLfloat dv[4];
  1182. DoDomain2WithDerivs(&em, u, v, &eval[__GL_V4], v4, du, dv,
  1183. evalData[__GL_V4]);
  1184. ComputeFirstPartials(v4, du, dv);
  1185. ComputeNormal2(gc, n3, du, dv);
  1186. *flags = *flags | MV_VERTEX4 | MV_NORMAL;
  1187. }
  1188. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1189. {
  1190. __GLfloat du[3];
  1191. __GLfloat dv[3];
  1192. DoDomain2WithDerivs(&em, u, v, &eval[__GL_V3], v4, du, dv,
  1193. evalData[__GL_V3]);
  1194. ComputeNormal2(gc, n3, du, dv);
  1195. *flags = *flags | MV_VERTEX3 | MV_NORMAL;
  1196. }
  1197. COPYMESHNORMAL (mv, n3);
  1198. COPYMESHVERTEX (mv, v4);
  1199. }
  1200. else
  1201. {
  1202. if (gc->state.enables.eval2 & __GL_MAP2_NORMAL_ENABLE)
  1203. {
  1204. DoDomain2(&em, u, v, &eval[__GL_N3], n3, evalData[__GL_N3]);
  1205. COPYMESHNORMAL (mv, n3);
  1206. *flags = *flags | MV_NORMAL;
  1207. }
  1208. if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_4_ENABLE)
  1209. {
  1210. DoDomain2(&em, u, v, &eval[__GL_V4], v4, evalData[__GL_V4]);
  1211. COPYMESHVERTEX (mv, v4);
  1212. *flags = *flags | MV_VERTEX4;
  1213. }
  1214. else if (gc->state.enables.eval2 & __GL_MAP2_VERTEX_3_ENABLE)
  1215. {
  1216. DoDomain2(&em, u, v, &eval[__GL_V3], v4, evalData[__GL_V3]);
  1217. COPYMESHVERTEX (mv, v4);
  1218. *flags = *flags | MV_VERTEX3;
  1219. }
  1220. }
  1221. if (gc->modes.colorIndexMode)
  1222. {
  1223. if (!(gc->state.enables.general & __GL_LIGHTING_ENABLE))
  1224. {
  1225. if (gc->state.enables.eval2 & __GL_MAP2_INDEX_ENABLE)
  1226. {
  1227. DoDomain2(&em, u, v, &eval[__GL_I], &(mv->color.r),
  1228. evalData[__GL_I]);
  1229. *flags = *flags | MV_INDEX;
  1230. }
  1231. }
  1232. }
  1233. else
  1234. {
  1235. if (gc->state.enables.eval2 & __GL_MAP2_COLOR_4_ENABLE)
  1236. {
  1237. DoDomain2(&em, u, v, &eval[__GL_C4], c4, evalData[__GL_C4]);
  1238. COPYMESHCOLOR (mv, c4);
  1239. *flags = *flags | MV_COLOR;
  1240. }
  1241. if (gc->state.enables.eval2 & __GL_MAP2_TEXTURE_COORD_4_ENABLE)
  1242. {
  1243. DoDomain2(&em, u, v, &eval[__GL_T4], t4, evalData[__GL_T4]);
  1244. COPYMESHTEXTURE (mv, t4);
  1245. *flags = *flags | MV_TEXTURE4;
  1246. }
  1247. else if (gc->state.enables.eval2 & __GL_MAP2_TEXTURE_COORD_3_ENABLE)
  1248. {
  1249. DoDomain2(&em, u, v, &eval[__GL_T3], t4, evalData[__GL_T3]);
  1250. COPYMESHTEXTURE (mv, t4);
  1251. *flags = *flags | MV_TEXTURE3;
  1252. }
  1253. else if (gc->state.enables.eval2 & __GL_MAP2_TEXTURE_COORD_2_ENABLE)
  1254. {
  1255. DoDomain2(&em, u, v, &eval[__GL_T2], t4, evalData[__GL_T2]);
  1256. COPYMESHTEXTURE (mv, t4);
  1257. *flags = *flags | MV_TEXTURE2;
  1258. }
  1259. else if (gc->state.enables.eval2 & __GL_MAP2_TEXTURE_COORD_1_ENABLE)
  1260. {
  1261. DoDomain2(&em, u, v, &eval[__GL_T1], t4, evalData[__GL_T1]);
  1262. COPYMESHTEXTURE (mv, t4);
  1263. *flags = *flags | MV_TEXTURE1;
  1264. }
  1265. }
  1266. }
  1267. /*
  1268. ** Optimization to precompute coefficients for polynomial evaluation.
  1269. */
  1270. static void PreEvaluate(GLint order, __GLfloat vprime, __GLfloat *coeff)
  1271. {
  1272. GLint i, j;
  1273. __GLfloat oldval, temp;
  1274. __GLfloat oneMinusvprime;
  1275. /*
  1276. ** Minor optimization
  1277. ** Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
  1278. ** their i==1 loop values to avoid the initialization and the i==1 loop.
  1279. */
  1280. if (order == 1)
  1281. {
  1282. coeff[0] = ((__GLfloat) 1.0);
  1283. return;
  1284. }
  1285. oneMinusvprime = 1-vprime;
  1286. coeff[0] = oneMinusvprime;
  1287. coeff[1] = vprime;
  1288. if (order == 2) return;
  1289. for (i = 2; i < order; i++)
  1290. {
  1291. oldval = coeff[0] * vprime;
  1292. coeff[0] = oneMinusvprime * coeff[0];
  1293. for (j = 1; j < i; j++)
  1294. {
  1295. temp = oldval;
  1296. oldval = coeff[j] * vprime;
  1297. coeff[j] = temp + oneMinusvprime * coeff[j];
  1298. }
  1299. coeff[j] = oldval;
  1300. }
  1301. }
  1302. /*
  1303. ** Optimization to precompute coefficients for polynomial evaluation.
  1304. */
  1305. static void PreEvaluateWithDeriv(GLint order, __GLfloat vprime,
  1306. __GLfloat *coeff, __GLfloat *coeffDeriv)
  1307. {
  1308. GLint i, j;
  1309. __GLfloat oldval, temp;
  1310. __GLfloat oneMinusvprime;
  1311. oneMinusvprime = 1-vprime;
  1312. /*
  1313. ** Minor optimization
  1314. ** Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
  1315. ** their i==1 loop values to avoid the initialization and the i==1 loop.
  1316. */
  1317. if (order == 1)
  1318. {
  1319. coeff[0] = ((__GLfloat) 1.0);
  1320. coeffDeriv[0] = __glZero;
  1321. return;
  1322. }
  1323. else if (order == 2)
  1324. {
  1325. coeffDeriv[0] = __glMinusOne;
  1326. coeffDeriv[1] = ((__GLfloat) 1.0);
  1327. coeff[0] = oneMinusvprime;
  1328. coeff[1] = vprime;
  1329. return;
  1330. }
  1331. coeff[0] = oneMinusvprime;
  1332. coeff[1] = vprime;
  1333. for (i = 2; i < order - 1; i++)
  1334. {
  1335. oldval = coeff[0] * vprime;
  1336. coeff[0] = oneMinusvprime * coeff[0];
  1337. for (j = 1; j < i; j++)
  1338. {
  1339. temp = oldval;
  1340. oldval = coeff[j] * vprime;
  1341. coeff[j] = temp + oneMinusvprime * coeff[j];
  1342. }
  1343. coeff[j] = oldval;
  1344. }
  1345. coeffDeriv[0] = -coeff[0];
  1346. /*
  1347. ** Minor optimization:
  1348. ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always
  1349. ** executed at least once, so this is more efficient.
  1350. */
  1351. j=1;
  1352. do
  1353. {
  1354. coeffDeriv[j] = coeff[j-1] - coeff[j];
  1355. j++;
  1356. } while (j < order - 1);
  1357. coeffDeriv[j] = coeff[j-1];
  1358. oldval = coeff[0] * vprime;
  1359. coeff[0] = oneMinusvprime * coeff[0];
  1360. for (j = 1; j < i; j++)
  1361. {
  1362. temp = oldval;
  1363. oldval = coeff[j] * vprime;
  1364. coeff[j] = temp + oneMinusvprime * coeff[j];
  1365. }
  1366. coeff[j] = oldval;
  1367. }
  1368. void DoDomain2(__GLevaluatorMachine *em, __GLfloat u, __GLfloat v,
  1369. __GLevaluator2 *e, __GLfloat *r, __GLfloat *baseData)
  1370. {
  1371. GLint j, row, col;
  1372. __GLfloat uprime;
  1373. __GLfloat vprime;
  1374. __GLfloat p;
  1375. __GLfloat *data;
  1376. GLint k;
  1377. #ifdef NT
  1378. ASSERTOPENGL((e->u2 != e->u1) && (e->v2 != e->v1), "In DoDomain2\n");
  1379. // assert((e->u2 != e->u1) && (e->v2 != e->v1));
  1380. #else
  1381. if((e->u2 == e->u1) || (e->v2 == e->v1))
  1382. return;
  1383. #endif
  1384. uprime = (u - e->u1) / (e->u2 - e->u1);
  1385. vprime = (v - e->v1) / (e->v2 - e->v1);
  1386. /* Compute coefficients for values */
  1387. /* Use already cached values if possible */
  1388. if (em->uvalue != uprime || em->uorder != e->majorOrder)
  1389. {
  1390. PreEvaluate(e->majorOrder, uprime, em->ucoeff);
  1391. em->utype = TYPE_COEFF;
  1392. em->uorder = e->majorOrder;
  1393. em->uvalue = uprime;
  1394. }
  1395. if (em->vvalue != vprime || em->vorder != e->minorOrder)
  1396. {
  1397. PreEvaluate(e->minorOrder, vprime, em->vcoeff);
  1398. em->vtype = TYPE_COEFF;
  1399. em->vorder = e->minorOrder;
  1400. em->vvalue = vprime;
  1401. }
  1402. k=e->k;
  1403. for (j = 0; j < k; j++)
  1404. {
  1405. data=baseData+j;
  1406. r[j] = 0;
  1407. for (row = 0; row < e->majorOrder; row++)
  1408. {
  1409. /*
  1410. ** Minor optimization.
  1411. ** The col == 0 part of the loop is extracted so we don't
  1412. ** have to initialize p to 0.
  1413. */
  1414. p=em->vcoeff[0] * (*data);
  1415. data += k;
  1416. for (col = 1; col < e->minorOrder; col++)
  1417. {
  1418. p += em->vcoeff[col] * (*data);
  1419. data += k;
  1420. }
  1421. r[j] += em->ucoeff[row] * p;
  1422. }
  1423. }
  1424. }
  1425. void DoDomain2WithDerivs(__GLevaluatorMachine *em, __GLfloat u,
  1426. __GLfloat v, __GLevaluator2 *e, __GLfloat *r,
  1427. __GLfloat *du, __GLfloat *dv, __GLfloat *baseData)
  1428. {
  1429. GLint j, row, col;
  1430. __GLfloat uprime;
  1431. __GLfloat vprime;
  1432. __GLfloat p;
  1433. __GLfloat pdv;
  1434. __GLfloat n[3];
  1435. __GLfloat *data;
  1436. GLint k;
  1437. #ifdef NT
  1438. ASSERTOPENGL((e->u2 != e->u1) && (e->v2 != e->v1),
  1439. "In Dodomain2WithDerivs\n");
  1440. // assert((e->u2 != e->u1) && (e->v2 != e->v1));
  1441. #else
  1442. if((e->u2 == e->u1) || (e->v2 == e->v1))
  1443. return;
  1444. #endif
  1445. uprime = (u - e->u1) / (e->u2 - e->u1);
  1446. vprime = (v - e->v1) / (e->v2 - e->v1);
  1447. /* Compute coefficients for values and derivs */
  1448. /* Use already cached values if possible */
  1449. if (em->uvalue != uprime || em->utype != TYPE_COEFF_AND_DERIV ||
  1450. em->uorder != e->majorOrder)
  1451. {
  1452. PreEvaluateWithDeriv(e->majorOrder, uprime, em->ucoeff,
  1453. em->ucoeffDeriv);
  1454. em->utype = TYPE_COEFF_AND_DERIV;
  1455. em->uorder = e->majorOrder;
  1456. em->uvalue = uprime;
  1457. }
  1458. if (em->vvalue != vprime || em->vtype != TYPE_COEFF_AND_DERIV ||
  1459. em->vorder != e->minorOrder)
  1460. {
  1461. PreEvaluateWithDeriv(e->minorOrder, vprime, em->vcoeff,
  1462. em->vcoeffDeriv);
  1463. em->vtype = TYPE_COEFF_AND_DERIV;
  1464. em->vorder = e->minorOrder;
  1465. em->vvalue = vprime;
  1466. }
  1467. k=e->k;
  1468. for (j = 0; j < k; j++)
  1469. {
  1470. data=baseData+j;
  1471. r[j] = du[j] = dv[j] = __glZero;
  1472. for (row = 0; row < e->majorOrder; row++)
  1473. {
  1474. /*
  1475. ** Minor optimization.
  1476. ** The col == 0 part of the loop is extracted so we don't
  1477. ** have to initialize p and pdv to 0.
  1478. */
  1479. p = em->vcoeff[0] * (*data);
  1480. pdv = em->vcoeffDeriv[0] * (*data);
  1481. data += k;
  1482. for (col = 1; col < e->minorOrder; col++)
  1483. {
  1484. /* Incrementally build up p, pdv value */
  1485. p += em->vcoeff[col] * (*data);
  1486. pdv += em->vcoeffDeriv[col] * (*data);
  1487. data += k;
  1488. }
  1489. /* Use p, pdv value to incrementally add up r, du, dv */
  1490. r[j] += em->ucoeff[row] * p;
  1491. du[j] += em->ucoeffDeriv[row] * p;
  1492. dv[j] += em->ucoeff[row] * pdv;
  1493. }
  1494. }
  1495. }
  1496. int FASTCALL genMeshElts (GLenum mode, GLuint sides, GLint nu, GLint nv,
  1497. GLubyte *buff)
  1498. {
  1499. GLint start;
  1500. GLint i, j, k;
  1501. // Compute the DrawElements Indices
  1502. switch(mode) {
  1503. case GL_LINE :
  1504. // Draw lines along U direction
  1505. start = 1;
  1506. k = 0;
  1507. if (sides & MV_TOP)
  1508. start = 0 ;
  1509. for (i=start; i<nv; i++)
  1510. for(j=0; j<nu-1; j++) {
  1511. buff[k++] = i*nu+j;
  1512. buff[k++] = i*nu+j+1;
  1513. }
  1514. // Draw lines along V direction
  1515. start = 1 ;
  1516. if (sides & MV_LEFT)
  1517. start = 0;
  1518. for (i=start; i<nu; i++)
  1519. for (j=0; j<nv-1; j++) {
  1520. buff[k++] = j*nu+i;
  1521. buff[k++] = (j+1)*nu+i;
  1522. }
  1523. break ;
  1524. case GL_FILL :
  1525. for (i=0, k=0; i<nv-1; i++)
  1526. for (j=0; j<nu-1; j++) {
  1527. buff[k++] = i*nu+j;
  1528. buff[k++] = (i+1)*nu+j;
  1529. buff[k++] = (i+1)*nu+j+1;
  1530. buff[k++] = i*nu+j+1;
  1531. }
  1532. break ;
  1533. }
  1534. return k; //the total number of points
  1535. }
  1536. void FASTCALL PA_EvalMesh2Fast(__GLcontext *gc, GLint u1, GLint u2, GLint v1,
  1537. GLint v2, GLint meshSize, GLenum mode,
  1538. GLuint sides)
  1539. {
  1540. GLint i, j, k, nu, nv;
  1541. __GLcolor currentColor;
  1542. __GLcoord currentNormal, currentTexture;
  1543. GLboolean currentEdgeFlag;
  1544. MESHVERTEX *mv, mvBuf[MAX_U_SIZE*MAX_V_SIZE];
  1545. GLuint mflags = 0;
  1546. GLuint stride;
  1547. GLubyte *disBuf;
  1548. __GLvertexArray currentVertexInfo;
  1549. GLuint texSize = 0, start, totalPts;
  1550. GLubyte dBufSmall[4*MAX_U_SIZE*MAX_V_SIZE]; //small
  1551. __GLfloat u, v;
  1552. __GLfloat du, dv;
  1553. __GLevaluatorGrid *gu;
  1554. __GLevaluatorGrid *gv;
  1555. // Now build the mesh vertex array [0..u2-u1, 0..v2-v1]
  1556. gu = &gc->state.evaluator.u2;
  1557. gv = &gc->state.evaluator.v2;
  1558. du = gu->step;
  1559. dv = gv->step;
  1560. //du = (gu->finish - gu->start)/(__GLfloat)gu->n;
  1561. //dv = (gv->finish - gv->start)/(__GLfloat)gv->n;
  1562. mv = &mvBuf[0];
  1563. nu = u2 - u1 + 1;
  1564. nv = v2 - v1 + 1;
  1565. for (i = v1; i < nv+v1; i++) //along V
  1566. {
  1567. for (j = u1; j < nu+u1; j++) //along U
  1568. {
  1569. u = (j == gu->n) ? gu->finish : (gu->start + j * du);
  1570. v = (i == gv->n) ? gv->finish : (gv->start + i * dv);
  1571. PADoEval2VArray(gc, u, v, mv, &mflags);
  1572. mv++;
  1573. }
  1574. }
  1575. if ((nv != MAX_V_SIZE) || (nu != MAX_U_SIZE)) {
  1576. disBuf = dBufSmall;
  1577. totalPts = genMeshElts (mode, sides, nu, nv, disBuf);
  1578. } else {
  1579. if (mode == GL_FILL) {
  1580. disBuf = dBufFill;
  1581. totalPts = totFillPts;
  1582. } else
  1583. switch (sides) {
  1584. case (MV_TOP | MV_LEFT):
  1585. disBuf = dBufTopLeft;
  1586. totalPts = totTopLeftPts;
  1587. break;
  1588. case (MV_TOP):
  1589. disBuf = dBufTopRight;
  1590. totalPts = totTopRightPts;
  1591. break;
  1592. case (MV_LEFT):
  1593. disBuf = &dBufTopLeft [(MAX_U_SIZE - 1) * 2];
  1594. totalPts = totTopLeftPts - (MAX_U_SIZE - 1) * 2;
  1595. break;
  1596. default : //NONE
  1597. disBuf = &dBufTopRight [(MAX_V_SIZE - 1) * 2];
  1598. totalPts = totTopRightPts - (MAX_V_SIZE - 1) * 2;
  1599. break;
  1600. }
  1601. }
  1602. if (mflags & MV_TEXTURE4)
  1603. texSize = 4;
  1604. else if (mflags & MV_TEXTURE3)
  1605. texSize = 3;
  1606. else if (mflags & MV_TEXTURE2)
  1607. texSize = 2;
  1608. else if (mflags & MV_TEXTURE1)
  1609. texSize = 1;
  1610. // Save current values.
  1611. if (mflags & MV_NORMAL)
  1612. currentNormal = gc->state.current.normal;
  1613. if (mflags & MV_INDEX)
  1614. currentColor.r = gc->state.current.userColorIndex;
  1615. else if (mflags & MV_COLOR)
  1616. currentColor = gc->state.current.userColor;
  1617. if (texSize)
  1618. currentTexture = gc->state.current.texture;
  1619. // Always force edge flag on in GL_FILL mode. The spec uses QUAD_STRIP
  1620. // which implies that edge flag is on for the evaluated mesh.
  1621. currentEdgeFlag = gc->state.current.edgeTag;
  1622. gc->state.current.edgeTag = GL_TRUE;
  1623. currentVertexInfo = gc->vertexArray;
  1624. //Enable the appropriate arrays
  1625. // Disable the arrays followed by enabling each individual array.
  1626. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  1627. gc->vertexArray.mask &= ~(VAMASK_VERTEX_ENABLE_MASK |
  1628. VAMASK_NORMAL_ENABLE_MASK |
  1629. VAMASK_COLOR_ENABLE_MASK |
  1630. VAMASK_INDEX_ENABLE_MASK |
  1631. VAMASK_TEXCOORD_ENABLE_MASK |
  1632. VAMASK_EDGEFLAG_ENABLE_MASK);
  1633. stride = sizeof(MESHVERTEX);
  1634. if (mflags & MV_NORMAL)
  1635. {
  1636. gc->vertexArray.mask |= VAMASK_NORMAL_ENABLE_MASK;
  1637. glcltNormalPointer(GL_FLOAT, stride, &(mvBuf[0].normal.x));
  1638. }
  1639. if (mflags & MV_INDEX) {
  1640. gc->vertexArray.mask |= VAMASK_INDEX_ENABLE_MASK;
  1641. glcltIndexPointer(GL_FLOAT, stride, &(mvBuf[0].color.r));
  1642. } else if (mflags & MV_COLOR) {
  1643. gc->vertexArray.mask |= VAMASK_COLOR_ENABLE_MASK;
  1644. glcltColorPointer(3, GL_FLOAT, stride, &(mvBuf[0].color.r));
  1645. }
  1646. if (texSize)
  1647. {
  1648. glcltTexCoordPointer(texSize, GL_FLOAT, stride,
  1649. &(mvBuf[0].texture.x));
  1650. gc->vertexArray.mask |= VAMASK_TEXCOORD_ENABLE_MASK;
  1651. }
  1652. if (mflags & MV_VERTEX3)
  1653. glcltVertexPointer(3, GL_FLOAT, stride, &(mvBuf[0].vertex.x));
  1654. else
  1655. glcltVertexPointer(4, GL_FLOAT, stride, &(mvBuf[0].vertex.x));
  1656. gc->vertexArray.mask |= VAMASK_VERTEX_ENABLE_MASK;
  1657. if (mode == GL_FILL)
  1658. glcltDrawElements(GL_QUADS, totalPts, GL_UNSIGNED_BYTE, disBuf);
  1659. else
  1660. glcltDrawElements(GL_LINES, totalPts, GL_UNSIGNED_BYTE, disBuf);
  1661. // Execute the command now.
  1662. // Otherwise, the current states will be messed up.
  1663. glsbAttention();
  1664. // Restore current values.
  1665. if (mflags & MV_NORMAL)
  1666. gc->state.current.normal = currentNormal;
  1667. if (mflags & MV_INDEX)
  1668. gc->state.current.userColorIndex = currentColor.r;
  1669. else if (mflags & MV_COLOR)
  1670. gc->state.current.userColor = currentColor;
  1671. if (texSize)
  1672. gc->state.current.texture = currentTexture;
  1673. gc->state.current.edgeTag = currentEdgeFlag;
  1674. gc->vertexArray = currentVertexInfo ;
  1675. }
  1676. void glcltColor4fv_Eval (__GLfloat *c4)
  1677. {
  1678. __GL_SETUP ();
  1679. POLYARRAY *pa;
  1680. POLYDATA *pd;
  1681. // POLYDATA *pdNext;
  1682. pa = gc->paTeb;
  1683. pd = pa->pdNextVertex;
  1684. // We are in RGBA mode.
  1685. ASSERTOPENGL (!gc->modes.colorIndexMode, "We should be in RGBA mode\n");
  1686. // Do not update the CurColor pointer
  1687. // If the color has already been set by a previous glcltColor call,
  1688. // simply, push this color to the next POLYDATA.
  1689. // This is a COLOR and not an INDEX.
  1690. if ((pd->flags & POLYDATA_COLOR_VALID) &&
  1691. !(pd->flags & POLYDATA_EVAL_COLOR))
  1692. {
  1693. gc->eval.color.r = pd->colors[0].r;
  1694. gc->eval.color.g = pd->colors[0].g;
  1695. gc->eval.color.b = pd->colors[0].b;
  1696. gc->eval.color.a = pd->colors[0].a;
  1697. gc->eval.accFlags |= EVAL_COLOR_VALID;
  1698. }
  1699. __GL_SCALE_AND_CHECK_CLAMP_RGBA(pd->colors[0].r,
  1700. pd->colors[0].g,
  1701. pd->colors[0].b,
  1702. pd->colors[0].a,
  1703. gc, pa->flags,
  1704. c4[0], c4[1], c4[2], c4[3]);
  1705. pd->flags |= (POLYDATA_COLOR_VALID | POLYDATA_DLIST_COLOR_4 |
  1706. POLYDATA_EVAL_COLOR) ;
  1707. pa->pdLastEvalColor = pd;
  1708. }
  1709. void glcltIndexf_Eval (__GLfloat ci)
  1710. {
  1711. __GL_SETUP ();
  1712. POLYARRAY *pa;
  1713. POLYDATA *pd;
  1714. pa = gc->paTeb;
  1715. pd = pa->pdNextVertex;
  1716. // We are in CI mode.
  1717. ASSERTOPENGL (gc->modes.colorIndexMode, "We should be in CI mode\n");
  1718. // Do not update the CurColor pointer
  1719. // If the index has already been set by a previous glcltIndex call,
  1720. // simply, push this color to the next POLYDATA.
  1721. // This is an INDEX and not a COLOR.
  1722. if ((pd->flags & POLYDATA_COLOR_VALID) &&
  1723. !(pd->flags & POLYDATA_EVAL_COLOR))
  1724. {
  1725. gc->eval.color.r = pd->colors[0].r;
  1726. gc->eval.accFlags |= EVAL_COLOR_VALID;
  1727. }
  1728. __GL_CHECK_CLAMP_CI(pd->colors[0].r, gc, pa->flags, ci);
  1729. pd->flags |= (POLYDATA_COLOR_VALID | POLYDATA_EVAL_COLOR) ;
  1730. pa->pdLastEvalColor = pd;
  1731. }
  1732. void glcltTexCoord1fv_Eval (__GLfloat *t1)
  1733. {
  1734. __GL_SETUP ();
  1735. POLYARRAY *pa;
  1736. POLYDATA *pd;
  1737. pa = GLTEB_CLTPOLYARRAY();
  1738. pa->flags |= POLYARRAY_TEXTURE1;
  1739. pd = pa->pdNextVertex;
  1740. // Do not update the CurTexture pointer
  1741. if (pd->flags & POLYDATA_TEXTURE_VALID)
  1742. {
  1743. ASSERTOPENGL (!(pd->flags & POLYDATA_EVAL_TEXCOORD),
  1744. "This cannot have been generated by an evaluator\n");
  1745. gc->eval.texture.x = pd->texture.x;
  1746. gc->eval.texture.y = pd->texture.y;
  1747. gc->eval.texture.z = pd->texture.z;
  1748. gc->eval.texture.w = pd->texture.w;
  1749. gc->eval.accFlags |= EVAL_TEXTURE_VALID;
  1750. }
  1751. pd->texture.x = t1[0];
  1752. pd->texture.y = __glZero;
  1753. pd->texture.z = __glZero;
  1754. pd->texture.w = __glOne;
  1755. pd->flags |= (POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE1 |
  1756. POLYDATA_EVAL_TEXCOORD);
  1757. pa->pdLastEvalTexture = pd;
  1758. }
  1759. void glcltTexCoord2fv_Eval (__GLfloat *t2)
  1760. {
  1761. __GL_SETUP ();
  1762. POLYARRAY *pa;
  1763. POLYDATA *pd;
  1764. pa = GLTEB_CLTPOLYARRAY();
  1765. pa->flags |= POLYARRAY_TEXTURE2;
  1766. pd = pa->pdNextVertex;
  1767. // Do not update the CurTexture pointer
  1768. if (pd->flags & POLYDATA_TEXTURE_VALID)
  1769. {
  1770. ASSERTOPENGL (!(pd->flags & POLYDATA_EVAL_TEXCOORD),
  1771. "This cannot have been generated by an evaluator\n");
  1772. gc->eval.texture.x = pd->texture.x;
  1773. gc->eval.texture.y = pd->texture.y;
  1774. gc->eval.texture.z = pd->texture.z;
  1775. gc->eval.texture.w = pd->texture.w;
  1776. gc->eval.accFlags |= EVAL_TEXTURE_VALID;
  1777. }
  1778. pd->texture.x = t2[0];
  1779. pd->texture.y = t2[1];
  1780. pd->texture.z = __glZero;
  1781. pd->texture.w = __glOne;
  1782. pd->flags |= (POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE2 |
  1783. POLYDATA_EVAL_TEXCOORD);
  1784. pa->pdLastEvalTexture = pd;
  1785. }
  1786. void glcltTexCoord3fv_Eval (__GLfloat *t3)
  1787. {
  1788. __GL_SETUP ();
  1789. POLYARRAY *pa;
  1790. POLYDATA *pd;
  1791. pa = GLTEB_CLTPOLYARRAY();
  1792. pa->flags |= POLYARRAY_TEXTURE3;
  1793. pd = pa->pdNextVertex;
  1794. if (pd->flags & POLYDATA_TEXTURE_VALID)
  1795. {
  1796. ASSERTOPENGL (!(pd->flags & POLYDATA_EVAL_TEXCOORD),
  1797. "This cannot have been generated by an evaluator\n");
  1798. gc->eval.texture.x = pd->texture.x;
  1799. gc->eval.texture.y = pd->texture.y;
  1800. gc->eval.texture.z = pd->texture.z;
  1801. gc->eval.texture.w = pd->texture.w;
  1802. gc->eval.accFlags |= EVAL_TEXTURE_VALID;
  1803. }
  1804. pd->texture.x = t3[0];
  1805. pd->texture.y = t3[1];
  1806. pd->texture.z = t3[2];
  1807. pd->texture.w = __glOne;
  1808. pd->flags |= (POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE3 |
  1809. POLYDATA_EVAL_TEXCOORD) ;
  1810. pa->pdLastEvalTexture = pd;
  1811. }
  1812. // Do not update the CurTexture pointer
  1813. void glcltTexCoord4fv_Eval (__GLfloat *t4)
  1814. {
  1815. __GL_SETUP ();
  1816. POLYARRAY *pa;
  1817. POLYDATA *pd;
  1818. pa = GLTEB_CLTPOLYARRAY();
  1819. pa->flags |= POLYARRAY_TEXTURE4;
  1820. pd = pa->pdNextVertex;
  1821. if (pd->flags & POLYDATA_TEXTURE_VALID)
  1822. {
  1823. ASSERTOPENGL (!(pd->flags & POLYDATA_EVAL_TEXCOORD),
  1824. "This cannot have been generated by an evaluator\n");
  1825. gc->eval.texture.x = pd->texture.x;
  1826. gc->eval.texture.y = pd->texture.y;
  1827. gc->eval.texture.z = pd->texture.z;
  1828. gc->eval.texture.w = pd->texture.w;
  1829. gc->eval.accFlags |= EVAL_TEXTURE_VALID;
  1830. }
  1831. pd->texture.x = t4[0];
  1832. pd->texture.y = t4[1];
  1833. pd->texture.z = t4[2];
  1834. pd->texture.w = t4[4];
  1835. pd->flags |= (POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE4 |
  1836. POLYDATA_EVAL_TEXCOORD);
  1837. pa->pdLastEvalTexture = pd;
  1838. }
  1839. // We do not update the CurNormal pointer here
  1840. void glcltNormal3fv_Eval (__GLfloat *n3)
  1841. {
  1842. __GL_SETUP ();
  1843. POLYARRAY *pa;
  1844. POLYDATA *pd;
  1845. pa = GLTEB_CLTPOLYARRAY();
  1846. pd = pa->pdNextVertex;
  1847. // If the existing normal is not from an evaluator, store it
  1848. // so that it can be set later.
  1849. if (pd->flags & POLYDATA_NORMAL_VALID)
  1850. {
  1851. ASSERTOPENGL (!(pd->flags & POLYDATA_EVAL_NORMAL),
  1852. "This cannot have been generated by an evaluator\n");
  1853. gc->eval.normal.x = pd->normal.x;
  1854. gc->eval.normal.y = pd->normal.y;
  1855. gc->eval.normal.z = pd->normal.z;
  1856. gc->eval.accFlags |= EVAL_NORMAL_VALID;
  1857. }
  1858. pd->normal.x = n3[0];
  1859. pd->normal.y = n3[1];
  1860. pd->normal.z = n3[2];
  1861. pd->flags |= (POLYDATA_NORMAL_VALID | POLYDATA_EVAL_NORMAL);
  1862. pa->pdLastEvalNormal = pd;
  1863. }