2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
38 * $Date: 2001/03/17 00:25:40 $ $Revision: 1.1 $
39 * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/interface/glsurfeval.cc,v 1.1 2001/03/17 00:25:40 brianp Exp $
42 /* Polynomial Evaluator Interface */
45 #include "glimports.h"
46 #include "glrenderer.h"
47 #include "glsurfeval.h"
48 #include "nurbsconsts.h"
49 #include "bezierPatchMesh.h"
52 //extern int surfcount;
55 /*#define USE_INTERNAL_EVAL*/ //use internal evaluator
57 /*whether do evaluation or not*/
58 /*#define NO_EVALUATION*/
60 //#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too
65 static int STAT_num_of_triangles
=0;
66 static int STAT_num_of_eval_vertices
=0;
67 static int STAT_num_of_quad_strips
=0;
70 /*for output triangles*/
71 /*#define OUTPUT_TRIANGLES*/
76 extern "C" { void evalUStripExt(int n_upper
, REAL v_upper
, REAL
* upper_val
,
77 int n_lower
, REAL v_lower
, REAL
* lower_val
);}
79 extern "C" { void evalVStripExt(int n_left
, REAL u_left
, REAL
* left_val
,
80 int n_right
, REAL u_right
, REAL
* right_val
);
85 /**************begin for LOD_eval_list***********/
86 void OpenGLSurfaceEvaluator::LOD_eval_list(int level
)
97 inBPMListEvalEM(global_bpm
);
101 OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
105 for (i
=0; i
<VERTEX_CACHE_SIZE
; i
++) {
106 vertexCache
[i
] = new StoredVertex
;
114 global_uprime
= -1.0;
115 global_vprime
= -1.0;
116 global_vprime_BV
= -1.0;
117 global_uprime_BU
= -1.0;
118 global_uorder_BU
= 0;
119 global_vorder_BU
= 0;
120 global_uorder_BV
= 0;
121 global_vorder_BV
= 0;
122 global_baseData
= NULL
;
125 output_triangles
= 0; //don't output triangles by default
127 //no default callback functions
128 beginCallBackN
= NULL
;
130 vertexCallBackN
= NULL
;
131 normalCallBackN
= NULL
;
132 colorCallBackN
= NULL
;
133 texcoordCallBackN
= NULL
;
134 beginCallBackData
= NULL
;
135 endCallBackData
= NULL
;
136 vertexCallBackData
= NULL
;
137 normalCallBackData
= NULL
;
138 colorCallBackData
= NULL
;
139 texcoordCallBackData
= NULL
;
143 auto_normal_flag
= 0;
144 callback_auto_normal
= 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0
150 em_vertex
.uprime
= -1.0;
151 em_vertex
.vprime
= -1.0;
152 em_normal
.uprime
= -1.0;
153 em_normal
.vprime
= -1.0;
154 em_color
.uprime
= -1.0;
155 em_color
.vprime
= -1.0;
156 em_texcoord
.uprime
= -1.0;
157 em_texcoord
.vprime
= -1.0;
164 OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
166 for (int ii
= 0; ii
< VERTEX_CACHE_SIZE
; ii
++) {
167 delete vertexCache
[ii
];
172 /*---------------------------------------------------------------------------
173 * disable - turn off a map
174 *---------------------------------------------------------------------------
177 OpenGLSurfaceEvaluator::disable(long type
)
179 glDisable((GLenum
) type
);
182 /*---------------------------------------------------------------------------
183 * enable - turn on a map
184 *---------------------------------------------------------------------------
187 OpenGLSurfaceEvaluator::enable(long type
)
189 glEnable((GLenum
) type
);
192 /*-------------------------------------------------------------------------
193 * mapgrid2f - define a lattice of points with origin and offset
194 *-------------------------------------------------------------------------
197 OpenGLSurfaceEvaluator::mapgrid2f(long nu
, REAL u0
, REAL u1
, long nv
, REAL v0
, REAL v1
)
199 #ifdef USE_INTERNAL_EVAL
200 inMapGrid2f((int) nu
, (REAL
) u0
, (REAL
) u1
, (int) nv
,
201 (REAL
) v0
, (REAL
) v1
);
214 glMapGrid2d((GLint
) nu
, (GLdouble
) u0
, (GLdouble
) u1
, (GLint
) nv
,
215 (GLdouble
) v0
, (GLdouble
) v1
);
221 OpenGLSurfaceEvaluator::polymode(long style
)
223 if(! output_triangles
)
229 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_FILL
);
232 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_LINE
);
235 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_POINT
);
242 OpenGLSurfaceEvaluator::bgnline(void)
245 bezierPatchMeshBeginStrip(global_bpm
, GL_LINE_STRIP
);
247 glBegin((GLenum
) GL_LINE_STRIP
);
251 OpenGLSurfaceEvaluator::endline(void)
254 bezierPatchMeshEndStrip(global_bpm
);
260 OpenGLSurfaceEvaluator::range2f(long type
, REAL
*from
, REAL
*to
)
265 OpenGLSurfaceEvaluator::domain2f(REAL ulo
, REAL uhi
, REAL vlo
, REAL vhi
)
270 OpenGLSurfaceEvaluator::bgnclosedline(void)
273 bezierPatchMeshBeginStrip(global_bpm
, GL_LINE_LOOP
);
275 glBegin((GLenum
) GL_LINE_LOOP
);
279 OpenGLSurfaceEvaluator::endclosedline(void)
282 bezierPatchMeshEndStrip(global_bpm
);
292 OpenGLSurfaceEvaluator::bgntmesh(void)
300 bezierPatchMeshBeginStrip(global_bpm
, GL_TRIANGLES
);
302 glBegin((GLenum
) GL_TRIANGLES
);
307 OpenGLSurfaceEvaluator::swaptmesh(void)
314 OpenGLSurfaceEvaluator::endtmesh(void)
320 bezierPatchMeshEndStrip(global_bpm
);
326 OpenGLSurfaceEvaluator::bgntfan(void)
330 bezierPatchMeshBeginStrip(global_bpm
, GL_TRIANGLE_FAN
);
332 glBegin((GLenum
) GL_TRIANGLE_FAN
);
336 OpenGLSurfaceEvaluator::endtfan(void)
339 bezierPatchMeshEndStrip(global_bpm
);
345 OpenGLSurfaceEvaluator::evalUStrip(int n_upper
, REAL v_upper
, REAL
* upper_val
, int n_lower
, REAL v_lower
, REAL
* lower_val
)
347 #ifdef USE_INTERNAL_EVAL
348 inEvalUStrip(n_upper
, v_upper
, upper_val
,
349 n_lower
, v_lower
, lower_val
);
353 evalUStripExt(n_upper
, v_upper
, upper_val
,
354 n_lower
, v_lower
, lower_val
);
362 *the algorithm works by scanning from left to right.
363 *leftMostV: the left most of the remaining verteces (on both upper and lower).
364 * it could an element of upperVerts or lowerVerts.
365 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
366 *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
369 /*initialize i,j,and leftMostV
371 if(upper_val
[0] <= lower_val
[0])
376 leftMostV
[0] = upper_val
[0];
377 leftMostV
[1] = v_upper
;
384 leftMostV
[0] = lower_val
[0];
385 leftMostV
[1] = v_lower
;
390 *the invariance is that:
391 *at the beginning of each loop, the meaning of i,j,and leftMostV are
396 if(i
>= n_upper
) /*case1: no more in upper*/
398 if(j
<n_lower
-1) /*at least two vertices in lower*/
401 coord2f(leftMostV
[0], leftMostV
[1]);
402 // glNormal3fv(leftMostNormal);
403 // glVertex3fv(leftMostXYZ);
406 coord2f(lower_val
[j
], v_lower
);
407 // glNormal3fv(lowerNormal[j]);
408 // glVertex3fv(lowerXYZ[j]);
414 break; /*exit the main loop*/
416 else if(j
>= n_lower
) /*case2: no more in lower*/
418 if(i
<n_upper
-1) /*at least two vertices in upper*/
421 coord2f(leftMostV
[0], leftMostV
[1]);
422 // glNormal3fv(leftMostNormal);
423 // glVertex3fv(leftMostXYZ);
425 for(k
=n_upper
-1; k
>=i
; k
--) /*reverse order for two-side lighting*/
427 coord2f(upper_val
[k
], v_upper
);
428 // glNormal3fv(upperNormal[k]);
429 // glVertex3fv(upperXYZ[k]);
434 break; /*exit the main loop*/
436 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
438 if(upper_val
[i
] <= lower_val
[j
])
441 coord2f(lower_val
[j
], v_lower
);
442 // glNormal3fv(lowerNormal[j]);
443 // glVertex3fv(lowerXYZ[j]);
445 /*find the last k>=i such that
446 *upperverts[k][0] <= lowerverts[j][0]
452 if(upper_val
[k
] > lower_val
[j
])
460 for(l
=k
; l
>=i
; l
--)/*the reverse is for two-side lighting*/
462 coord2f(upper_val
[l
], v_upper
);
463 // glNormal3fv(upperNormal[l]);
464 // glVertex3fv(upperXYZ[l]);
467 coord2f(leftMostV
[0], leftMostV
[1]);
468 // glNormal3fv(leftMostNormal);
469 // glVertex3fv(leftMostXYZ);
473 /*update i and leftMostV for next loop
477 leftMostV
[0] = upper_val
[k
];
478 leftMostV
[1] = v_upper
;
479 // leftMostNormal = upperNormal[k];
480 // leftMostXYZ = upperXYZ[k];
482 else /*upperVerts[i][0] > lowerVerts[j][0]*/
485 coord2f(upper_val
[i
], v_upper
);
486 // glNormal3fv(upperNormal[i]);
487 // glVertex3fv(upperXYZ[i]);
489 coord2f(leftMostV
[0], leftMostV
[1]);
490 // glNormal3fv(leftMostNormal);
491 // glVertex3fv(leftMostXYZ);
494 /*find the last k>=j such that
495 *lowerverts[k][0] < upperverts[i][0]
500 if(lower_val
[k
] >= upper_val
[i
])
502 coord2f(lower_val
[k
], v_lower
);
503 // glNormal3fv(lowerNormal[k]);
504 // glVertex3fv(lowerXYZ[k]);
510 /*update j and leftMostV for next loop
513 leftMostV
[0] = lower_val
[j
-1];
514 leftMostV
[1] = v_lower
;
516 // leftMostNormal = lowerNormal[j-1];
517 // leftMostXYZ = lowerXYZ[j-1];
524 // free(upperNormal);
525 // free(lowerNormal);
532 OpenGLSurfaceEvaluator::evalVStrip(int n_left
, REAL u_left
, REAL
* left_val
, int n_right
, REAL u_right
, REAL
* right_val
)
534 #ifdef USE_INTERNAL_EVAL
535 inEvalVStrip(n_left
, u_left
, left_val
,
536 n_right
, u_right
, right_val
);
540 evalVStripExt(n_left
, u_left
, left_val
,
541 n_right
, u_right
, right_val
);
549 *the algorithm works by scanning from bot to top.
550 *botMostV: the bot most of the remaining verteces (on both left and right).
551 * it could an element of leftVerts or rightVerts.
552 *i: leftVerts[i] is the first vertex to the top of botMostV on left line
553 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
556 /*initialize i,j,and botMostV
558 if(left_val
[0] <= right_val
[0])
563 botMostV
[0] = u_left
;
564 botMostV
[1] = left_val
[0];
571 botMostV
[0] = u_right
;
572 botMostV
[1] = right_val
[0];
576 *the invariance is that:
577 *at the beginning of each loop, the meaning of i,j,and botMostV are
582 if(i
>= n_left
) /*case1: no more in left*/
584 if(j
<n_right
-1) /*at least two vertices in right*/
587 coord2f(botMostV
[0], botMostV
[1]);
589 coord2f(u_right
, right_val
[j
]);
590 // glNormal3fv(rightNormal[j]);
591 // glVertex3fv(rightXYZ[j]);
597 break; /*exit the main loop*/
599 else if(j
>= n_right
) /*case2: no more in right*/
601 if(i
<n_left
-1) /*at least two vertices in left*/
604 coord2f(botMostV
[0], botMostV
[1]);
605 // glNormal3fv(botMostNormal);
606 // glVertex3fv(botMostXYZ);
608 for(k
=n_left
-1; k
>=i
; k
--) /*reverse order for two-side lighting*/
610 coord2f(u_left
, left_val
[k
]);
611 // glNormal3fv(leftNormal[k]);
612 // glVertex3fv(leftXYZ[k]);
617 break; /*exit the main loop*/
619 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
621 if(left_val
[i
] <= right_val
[j
])
624 coord2f(u_right
, right_val
[j
]);
625 // glNormal3fv(rightNormal[j]);
626 // glVertex3fv(rightXYZ[j]);
628 /*find the last k>=i such that
629 *leftverts[k][0] <= rightverts[j][0]
635 if(left_val
[k
] > right_val
[j
])
643 for(l
=k
; l
>=i
; l
--)/*the reverse is for two-side lighting*/
645 coord2f(u_left
, left_val
[l
]);
646 // glNormal3fv(leftNormal[l]);
647 // glVertex3fv(leftXYZ[l]);
650 coord2f(botMostV
[0], botMostV
[1]);
651 // glNormal3fv(botMostNormal);
652 // glVertex3fv(botMostXYZ);
656 /*update i and botMostV for next loop
660 botMostV
[0] = u_left
;
661 botMostV
[1] = left_val
[k
];
662 // botMostNormal = leftNormal[k];
663 // botMostXYZ = leftXYZ[k];
665 else /*left_val[i] > right_val[j])*/
668 coord2f(u_left
, left_val
[i
]);
669 // glNormal3fv(leftNormal[i]);
670 // glVertex3fv(leftXYZ[i]);
672 coord2f(botMostV
[0], botMostV
[1]);
673 // glNormal3fv(botMostNormal);
674 // glVertex3fv(botMostXYZ);
677 /*find the last k>=j such that
678 *rightverts[k][0] < leftverts[i][0]
683 if(right_val
[k
] >= left_val
[i
])
685 coord2f(u_right
, right_val
[k
]);
686 // glNormal3fv(rightNormal[k]);
687 // glVertex3fv(rightXYZ[k]);
693 /*update j and botMostV for next loop
696 botMostV
[0] = u_right
;
697 botMostV
[1] = right_val
[j
-1];
699 // botMostNormal = rightNormal[j-1];
700 // botMostXYZ = rightXYZ[j-1];
708 // free(rightNormal);
714 OpenGLSurfaceEvaluator::bgnqstrip(void)
717 bezierPatchMeshBeginStrip(global_bpm
, GL_QUAD_STRIP
);
719 glBegin((GLenum
) GL_QUAD_STRIP
);
722 STAT_num_of_quad_strips
++;
727 OpenGLSurfaceEvaluator::endqstrip(void)
730 bezierPatchMeshEndStrip(global_bpm
);
736 /*-------------------------------------------------------------------------
737 * bgnmap2f - preamble to surface definition and evaluations
738 *-------------------------------------------------------------------------
741 OpenGLSurfaceEvaluator::bgnmap2f(long)
745 /*deallocate the space which may has been
746 *allocated by global_bpm previously
748 if(global_bpm
!= NULL
) {
749 bezierPatchMeshListDelete(global_bpm
);
755 auto_normal_flag = 1; //always output normal in callback mode.
756 //we could have used the following code,
757 //but Inspector doesn't have gl context
758 //before it calls tessellator.
759 //this way is temporary.
762 //if one of the two normal callback functions are set,
764 if(normalCallBackN
!= NULL
||
765 normalCallBackData
!= NULL
)
766 auto_normal_flag
= 1;
768 auto_normal_flag
= 0;
770 //initialize so that no maps initially
777 if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE)
778 auto_normal_flag = 1;
779 else if (callback_auto_normal == 1)
780 auto_normal_flag = 1;
782 auto_normal_flag = 0;
785 //NEWCALLBACK: no need to worry about gl states when gling clalback
789 glPushAttrib((GLbitfield
) GL_EVAL_BIT
);
791 /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE
793 glGetIntegerv(GL_POLYGON_MODE
, gl_polygon_mode
);
798 /*-------------------------------------------------------------------------
799 * endmap2f - postamble to a map
800 *-------------------------------------------------------------------------
803 OpenGLSurfaceEvaluator::endmap2f(void)
808 //bezierPatchMeshListDelDeg(global_bpm);
810 // bezierPatchMeshListEval(global_bpm);
813 //printf("surfcount=%i\n", surfcount);
814 //if(surfcount == 8) exit(0);
816 inBPMListEvalEM(global_bpm
);
821 global_bpm = bezierPatchMeshListReverse(global_bpm);
828 bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips);
829 drawStrips(vertex_array, normal_array, length_array, type_array, num_strips);
837 //bezierPatchMeshListPrint(global_bpm);
838 //bezierPatchMeshListDraw(global_bpm);
840 // printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm));
844 bezierPatchMeshListDelete(global_bpm
);
856 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
);
859 /*to restore the gl_polygon_mode
862 glPolygonMode( GL_FRONT
, (GLenum
) gl_polygon_mode
[0]);
863 glPolygonMode( GL_BACK
, (GLenum
) gl_polygon_mode
[1]);
869 /*-------------------------------------------------------------------------
870 * map2f - pass a desription of a surface map
871 *-------------------------------------------------------------------------
874 OpenGLSurfaceEvaluator::map2f(
876 REAL _ulower
, /* u lower domain coord */
877 REAL _uupper
, /* u upper domain coord */
878 long _ustride
, /* interpoint distance */
879 long _uorder
, /* parametric order */
880 REAL _vlower
, /* v lower domain coord */
881 REAL _vupper
, /* v upper domain coord */
882 long _vstride
, /* interpoint distance */
883 long _vorder
, /* parametric order */
884 REAL
*pts
) /* control points */
886 #ifdef USE_INTERNAL_EVAL
887 inMap2f((int) _type
, (REAL
) _ulower
, (REAL
) _uupper
,
888 (int) _ustride
, (int) _uorder
, (REAL
) _vlower
,
889 (REAL
) _vupper
, (int) _vstride
, (int) _vorder
,
897 if(global_bpm
== NULL
)
898 global_bpm
= bezierPatchMeshMake2(10,10);
900 (global_bpm
->bpatch
== NULL
&&
901 (_type
== GL_MAP2_VERTEX_3
|| _type
== GL_MAP2_VERTEX_4
))
903 (global_bpm
->bpatch_normal
== NULL
&&
904 (_type
== GL_MAP2_NORMAL
))
906 (global_bpm
->bpatch_color
== NULL
&&
907 (_type
== GL_MAP2_INDEX
|| _type
== GL_MAP2_COLOR_4
))
909 (global_bpm
->bpatch_texcoord
== NULL
&&
910 (_type
== GL_MAP2_TEXTURE_COORD_1
||
911 _type
== GL_MAP2_TEXTURE_COORD_2
||
912 _type
== GL_MAP2_TEXTURE_COORD_3
||
913 _type
== GL_MAP2_TEXTURE_COORD_4
)
916 bezierPatchMeshPutPatch(global_bpm
, (int) _type
, _ulower
, _uupper
,(int) _ustride
,(int) _uorder
,_vlower
, _vupper
, (int) _vstride
, (int) _vorder
, pts
);
918 else /*new surface patch (with multiple maps) starts*/
920 bezierPatchMesh
*temp
= bezierPatchMeshMake2(10,10);
921 bezierPatchMeshPutPatch(temp
, (int) _type
, _ulower
, _uupper
,(int) _ustride
,(int) _uorder
,_vlower
, _vupper
, (int) _vstride
, (int) _vorder
, pts
);
922 global_bpm
= bezierPatchMeshListInsert(global_bpm
, temp
);
925 global_bpm = bezierPatchMeshListInsert(global_bpm,
927 (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10));
931 else /*not output triangles*/
933 glMap2f((GLenum
) _type
, (GLfloat
) _ulower
, (GLfloat
) _uupper
,
934 (GLint
) _ustride
, (GLint
) _uorder
, (GLfloat
) _vlower
,
935 (GLfloat
) _vupper
, (GLint
) _vstride
, (GLint
) _vorder
,
936 (const GLfloat
*) pts
);
943 /*-------------------------------------------------------------------------
944 * mapmesh2f - evaluate a mesh of points on lattice
945 *-------------------------------------------------------------------------
948 OpenGLSurfaceEvaluator::mapmesh2f(long style
, long umin
, long umax
, long vmin
, long vmax
)
954 #ifdef USE_INTERNAL_EVAL
955 inEvalMesh2((int)umin
, (int)vmin
, (int)umax
, (int)vmax
);
963 bezierPatchMeshBeginStrip(global_bpm
, GL_POLYGON
);
964 bezierPatchMeshInsertUV(global_bpm
, global_grid_u0
, global_grid_v0
);
965 bezierPatchMeshInsertUV(global_bpm
, global_grid_u1
, global_grid_v1
);
966 bezierPatchMeshInsertUV(global_bpm
, (REAL
)global_grid_nu
, (REAL
)global_grid_nv
);
967 bezierPatchMeshInsertUV(global_bpm
, (REAL
)umin
, (REAL
)vmin
);
968 bezierPatchMeshInsertUV(global_bpm
, (REAL
)umax
, (REAL
)vmax
);
969 bezierPatchMeshEndStrip(global_bpm
);
976 if(global_grid_nu
== 0 || global_grid_nv
== 0)
977 return; /*no points need to be output*/
978 du
= (global_grid_u1
- global_grid_u0
) / (REAL
)global_grid_nu
;
979 dv
= (global_grid_v1
- global_grid_v0
) / (REAL
)global_grid_nv
;
981 if(global_grid_nu
>= global_grid_nv
){
983 for(i
=umin
; i
<umax
; i
++){
984 REAL u1
= (i
==global_grid_nu
)? global_grid_u1
:(global_grid_u0
+ i
*du
);
985 REAL u2
= ((i
+1) == global_grid_nu
)? global_grid_u1
: (global_grid_u0
+(i
+1)*du
);
988 for(j
=vmax
; j
>=vmin
; j
--){
989 REAL v1
= (j
== global_grid_nv
)? global_grid_v1
: (global_grid_v0
+j
*dv
);
999 for(i
=vmin
; i
<vmax
; i
++){
1000 REAL v1
= (i
==global_grid_nv
)? global_grid_v1
:(global_grid_v0
+ i
*dv
);
1001 REAL v2
= ((i
+1) == global_grid_nv
)? global_grid_v1
: (global_grid_v0
+(i
+1)*dv
);
1004 for(j
=umax
; j
>=umin
; j
--){
1005 REAL u1
= (j
== global_grid_nu
)? global_grid_u1
: (global_grid_u0
+j
*du
);
1019 glEvalMesh2((GLenum
) GL_FILL
, (GLint
) umin
, (GLint
) umax
,
1020 (GLint
) vmin
, (GLint
) vmax
);
1023 glEvalMesh2((GLenum
) GL_LINE
, (GLint
) umin
, (GLint
) umax
,
1024 (GLint
) vmin
, (GLint
) vmax
);
1027 glEvalMesh2((GLenum
) GL_POINT
, (GLint
) umin
, (GLint
) umax
,
1028 (GLint
) vmin
, (GLint
) vmax
);
1036 STAT_num_of_quad_strips
+= (umax
-umin
)*(vmax
-vmin
);
1040 /*-------------------------------------------------------------------------
1041 * evalcoord2f - evaluate a point on a surface
1042 *-------------------------------------------------------------------------
1045 OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u
, REAL v
)
1049 #ifdef NO_EVALUATION
1057 /*-------------------------------------------------------------------------
1058 * evalpoint2i - evaluate a grid point
1059 *-------------------------------------------------------------------------
1062 OpenGLSurfaceEvaluator::evalpoint2i(long u
, long v
)
1064 #ifdef NO_EVALUATION
1072 OpenGLSurfaceEvaluator::point2i( long u
, long v
)
1074 #ifdef NO_EVALUATION
1078 #ifdef USE_INTERNAL_EVAL
1079 inEvalPoint2( (int)u
, (int)v
);
1083 if(output_triangles
)
1088 du
= (global_grid_u1
- global_grid_u0
) / (REAL
)global_grid_nu
;
1089 dv
= (global_grid_v1
- global_grid_v0
) / (REAL
)global_grid_nv
;
1090 fu
= (u
==global_grid_nu
)? global_grid_u1
:(global_grid_u0
+ u
*du
);
1091 fv
= (v
== global_grid_nv
)? global_grid_v1
: (global_grid_v0
+v
*dv
);
1095 glEvalPoint2((GLint
) u
, (GLint
) v
);
1101 STAT_num_of_eval_vertices
++;
1109 OpenGLSurfaceEvaluator::coord2f( REAL u
, REAL v
)
1111 #ifdef NO_EVALUATION
1115 #ifdef USE_INTERNAL_EVAL
1116 inEvalCoord2f( u
, v
);
1120 if(output_triangles
)
1121 bezierPatchMeshInsertUV(global_bpm
, u
,v
);
1123 glEvalCoord2f((GLfloat
) u
, (GLfloat
) v
);
1130 STAT_num_of_eval_vertices
++;
1137 OpenGLSurfaceEvaluator::newtmeshvert( long u
, long v
)
1139 #ifdef NO_EVALUATION
1146 vertexCache
[0]->invoke(this);
1147 vertexCache
[1]->invoke(this);
1154 vertexCache
[which
]->saveEvalPoint(u
, v
);
1163 OpenGLSurfaceEvaluator::newtmeshvert( REAL u
, REAL v
)
1165 #ifdef NO_EVALUATION
1172 vertexCache
[0]->invoke(this);
1173 vertexCache
[1]->invoke(this);
1180 vertexCache
[which
]->saveEvalCoord(u
, v
);
1191 OpenGLSurfaceEvaluator::putCallBack(GLenum which
, GLvoid (GLAPIENTRY
*fn
)(...))
1195 case GLU_NURBS_BEGIN
:
1196 beginCallBackN
= (void (GLAPIENTRY
*) (GLenum
)) fn
;
1199 endCallBackN
= (void (GLAPIENTRY
*) (void)) fn
;
1201 case GLU_NURBS_VERTEX
:
1202 vertexCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1204 case GLU_NURBS_NORMAL
:
1205 normalCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1207 case GLU_NURBS_COLOR
:
1208 colorCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1210 case GLU_NURBS_TEXTURE_COORD
:
1211 texcoordCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1213 case GLU_NURBS_BEGIN_DATA
:
1214 beginCallBackData
= (void (GLAPIENTRY
*) (GLenum
, void*)) fn
;
1216 case GLU_NURBS_END_DATA
:
1217 endCallBackData
= (void (GLAPIENTRY
*) (void*)) fn
;
1219 case GLU_NURBS_VERTEX_DATA
:
1220 vertexCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1222 case GLU_NURBS_NORMAL_DATA
:
1223 normalCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1225 case GLU_NURBS_COLOR_DATA
:
1226 colorCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1228 case GLU_NURBS_TEXTURE_COORD_DATA
:
1229 texcoordCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1237 OpenGLSurfaceEvaluator::beginCallBack(GLenum which
, void *data
)
1239 if(beginCallBackData
)
1240 beginCallBackData(which
, data
);
1241 else if(beginCallBackN
)
1242 beginCallBackN(which
);
1246 OpenGLSurfaceEvaluator::endCallBack(void *data
)
1249 endCallBackData(data
);
1250 else if(endCallBackN
)
1255 OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat
*vert
, void* data
)
1257 if(vertexCallBackData
)
1258 vertexCallBackData(vert
, data
);
1259 else if(vertexCallBackN
)
1260 vertexCallBackN(vert
);
1265 OpenGLSurfaceEvaluator::normalCallBack(const GLfloat
*normal
, void* data
)
1267 if(normalCallBackData
)
1268 normalCallBackData(normal
, data
);
1269 else if(normalCallBackN
)
1270 normalCallBackN(normal
);
1274 OpenGLSurfaceEvaluator::colorCallBack(const GLfloat
*color
, void* data
)
1276 if(colorCallBackData
)
1277 colorCallBackData(color
, data
);
1278 else if(colorCallBackN
)
1279 colorCallBackN(color
);
1283 OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat
*texcoord
, void* data
)
1285 if(texcoordCallBackData
)
1286 texcoordCallBackData(texcoord
, data
);
1287 else if(texcoordCallBackN
)
1288 texcoordCallBackN(texcoord
);