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.
40 /* Polynomial Evaluator Interface */
43 #include "glimports.h"
44 #include "glrenderer.h"
45 #include "glsurfeval.h"
46 #include "nurbsconsts.h"
47 #include "bezierPatchMesh.h"
50 //extern int surfcount;
53 /*#define USE_INTERNAL_EVAL*/ //use internal evaluator
55 /*whether do evaluation or not*/
56 /*#define NO_EVALUATION*/
58 //#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too
63 static int STAT_num_of_triangles
=0;
64 static int STAT_num_of_eval_vertices
=0;
65 static int STAT_num_of_quad_strips
=0;
68 /*for output triangles*/
69 /*#define OUTPUT_TRIANGLES*/
74 extern "C" { void evalUStripExt(int n_upper
, REAL v_upper
, REAL
* upper_val
,
75 int n_lower
, REAL v_lower
, REAL
* lower_val
);}
77 extern "C" { void evalVStripExt(int n_left
, REAL u_left
, REAL
* left_val
,
78 int n_right
, REAL u_right
, REAL
* right_val
);
83 /**************begin for LOD_eval_list***********/
84 void OpenGLSurfaceEvaluator::LOD_eval_list(int level
)
95 inBPMListEvalEM(global_bpm
);
99 OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
103 for (i
=0; i
<VERTEX_CACHE_SIZE
; i
++) {
104 vertexCache
[i
] = new StoredVertex
;
112 global_uprime
= -1.0;
113 global_vprime
= -1.0;
114 global_vprime_BV
= -1.0;
115 global_uprime_BU
= -1.0;
116 global_uorder_BU
= 0;
117 global_vorder_BU
= 0;
118 global_uorder_BV
= 0;
119 global_vorder_BV
= 0;
120 global_baseData
= NULL
;
123 output_triangles
= 0; //don't output triangles by default
125 //no default callback functions
126 beginCallBackN
= NULL
;
128 vertexCallBackN
= NULL
;
129 normalCallBackN
= NULL
;
130 colorCallBackN
= NULL
;
131 texcoordCallBackN
= NULL
;
132 beginCallBackData
= NULL
;
133 endCallBackData
= NULL
;
134 vertexCallBackData
= NULL
;
135 normalCallBackData
= NULL
;
136 colorCallBackData
= NULL
;
137 texcoordCallBackData
= NULL
;
141 auto_normal_flag
= 0;
142 callback_auto_normal
= 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0
148 em_vertex
.uprime
= -1.0;
149 em_vertex
.vprime
= -1.0;
150 em_normal
.uprime
= -1.0;
151 em_normal
.vprime
= -1.0;
152 em_color
.uprime
= -1.0;
153 em_color
.vprime
= -1.0;
154 em_texcoord
.uprime
= -1.0;
155 em_texcoord
.vprime
= -1.0;
162 OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
164 for (int ii
= 0; ii
< VERTEX_CACHE_SIZE
; ii
++) {
165 delete vertexCache
[ii
];
170 /*---------------------------------------------------------------------------
171 * disable - turn off a map
172 *---------------------------------------------------------------------------
175 OpenGLSurfaceEvaluator::disable(long type
)
177 glDisable((GLenum
) type
);
180 /*---------------------------------------------------------------------------
181 * enable - turn on a map
182 *---------------------------------------------------------------------------
185 OpenGLSurfaceEvaluator::enable(long type
)
187 glEnable((GLenum
) type
);
190 /*-------------------------------------------------------------------------
191 * mapgrid2f - define a lattice of points with origin and offset
192 *-------------------------------------------------------------------------
195 OpenGLSurfaceEvaluator::mapgrid2f(long nu
, REAL u0
, REAL u1
, long nv
, REAL v0
, REAL v1
)
197 #ifdef USE_INTERNAL_EVAL
198 inMapGrid2f((int) nu
, (REAL
) u0
, (REAL
) u1
, (int) nv
,
199 (REAL
) v0
, (REAL
) v1
);
212 glMapGrid2d((GLint
) nu
, (GLdouble
) u0
, (GLdouble
) u1
, (GLint
) nv
,
213 (GLdouble
) v0
, (GLdouble
) v1
);
219 OpenGLSurfaceEvaluator::polymode(long style
)
221 if(! output_triangles
)
227 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_FILL
);
230 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_LINE
);
233 glPolygonMode((GLenum
) GL_FRONT_AND_BACK
, (GLenum
) GL_POINT
);
240 OpenGLSurfaceEvaluator::bgnline(void)
243 bezierPatchMeshBeginStrip(global_bpm
, GL_LINE_STRIP
);
245 glBegin((GLenum
) GL_LINE_STRIP
);
249 OpenGLSurfaceEvaluator::endline(void)
252 bezierPatchMeshEndStrip(global_bpm
);
258 OpenGLSurfaceEvaluator::range2f(long type
, REAL
*from
, REAL
*to
)
263 OpenGLSurfaceEvaluator::domain2f(REAL ulo
, REAL uhi
, REAL vlo
, REAL vhi
)
268 OpenGLSurfaceEvaluator::bgnclosedline(void)
271 bezierPatchMeshBeginStrip(global_bpm
, GL_LINE_LOOP
);
273 glBegin((GLenum
) GL_LINE_LOOP
);
277 OpenGLSurfaceEvaluator::endclosedline(void)
280 bezierPatchMeshEndStrip(global_bpm
);
290 OpenGLSurfaceEvaluator::bgntmesh(void)
298 bezierPatchMeshBeginStrip(global_bpm
, GL_TRIANGLES
);
300 glBegin((GLenum
) GL_TRIANGLES
);
305 OpenGLSurfaceEvaluator::swaptmesh(void)
312 OpenGLSurfaceEvaluator::endtmesh(void)
318 bezierPatchMeshEndStrip(global_bpm
);
324 OpenGLSurfaceEvaluator::bgntfan(void)
328 bezierPatchMeshBeginStrip(global_bpm
, GL_TRIANGLE_FAN
);
330 glBegin((GLenum
) GL_TRIANGLE_FAN
);
334 OpenGLSurfaceEvaluator::endtfan(void)
337 bezierPatchMeshEndStrip(global_bpm
);
343 OpenGLSurfaceEvaluator::evalUStrip(int n_upper
, REAL v_upper
, REAL
* upper_val
, int n_lower
, REAL v_lower
, REAL
* lower_val
)
345 #ifdef USE_INTERNAL_EVAL
346 inEvalUStrip(n_upper
, v_upper
, upper_val
,
347 n_lower
, v_lower
, lower_val
);
351 evalUStripExt(n_upper
, v_upper
, upper_val
,
352 n_lower
, v_lower
, lower_val
);
360 *the algorithm works by scanning from left to right.
361 *leftMostV: the left most of the remaining verteces (on both upper and lower).
362 * it could an element of upperVerts or lowerVerts.
363 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
364 *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
367 /*initialize i,j,and leftMostV
369 if(upper_val
[0] <= lower_val
[0])
374 leftMostV
[0] = upper_val
[0];
375 leftMostV
[1] = v_upper
;
382 leftMostV
[0] = lower_val
[0];
383 leftMostV
[1] = v_lower
;
388 *the invariance is that:
389 *at the beginning of each loop, the meaning of i,j,and leftMostV are
394 if(i
>= n_upper
) /*case1: no more in upper*/
396 if(j
<n_lower
-1) /*at least two vertices in lower*/
399 coord2f(leftMostV
[0], leftMostV
[1]);
400 // glNormal3fv(leftMostNormal);
401 // glVertex3fv(leftMostXYZ);
404 coord2f(lower_val
[j
], v_lower
);
405 // glNormal3fv(lowerNormal[j]);
406 // glVertex3fv(lowerXYZ[j]);
412 break; /*exit the main loop*/
414 else if(j
>= n_lower
) /*case2: no more in lower*/
416 if(i
<n_upper
-1) /*at least two vertices in upper*/
419 coord2f(leftMostV
[0], leftMostV
[1]);
420 // glNormal3fv(leftMostNormal);
421 // glVertex3fv(leftMostXYZ);
423 for(k
=n_upper
-1; k
>=i
; k
--) /*reverse order for two-side lighting*/
425 coord2f(upper_val
[k
], v_upper
);
426 // glNormal3fv(upperNormal[k]);
427 // glVertex3fv(upperXYZ[k]);
432 break; /*exit the main loop*/
434 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
436 if(upper_val
[i
] <= lower_val
[j
])
439 coord2f(lower_val
[j
], v_lower
);
440 // glNormal3fv(lowerNormal[j]);
441 // glVertex3fv(lowerXYZ[j]);
443 /*find the last k>=i such that
444 *upperverts[k][0] <= lowerverts[j][0]
450 if(upper_val
[k
] > lower_val
[j
])
458 for(l
=k
; l
>=i
; l
--)/*the reverse is for two-side lighting*/
460 coord2f(upper_val
[l
], v_upper
);
461 // glNormal3fv(upperNormal[l]);
462 // glVertex3fv(upperXYZ[l]);
465 coord2f(leftMostV
[0], leftMostV
[1]);
466 // glNormal3fv(leftMostNormal);
467 // glVertex3fv(leftMostXYZ);
471 /*update i and leftMostV for next loop
475 leftMostV
[0] = upper_val
[k
];
476 leftMostV
[1] = v_upper
;
477 // leftMostNormal = upperNormal[k];
478 // leftMostXYZ = upperXYZ[k];
480 else /*upperVerts[i][0] > lowerVerts[j][0]*/
483 coord2f(upper_val
[i
], v_upper
);
484 // glNormal3fv(upperNormal[i]);
485 // glVertex3fv(upperXYZ[i]);
487 coord2f(leftMostV
[0], leftMostV
[1]);
488 // glNormal3fv(leftMostNormal);
489 // glVertex3fv(leftMostXYZ);
492 /*find the last k>=j such that
493 *lowerverts[k][0] < upperverts[i][0]
498 if(lower_val
[k
] >= upper_val
[i
])
500 coord2f(lower_val
[k
], v_lower
);
501 // glNormal3fv(lowerNormal[k]);
502 // glVertex3fv(lowerXYZ[k]);
508 /*update j and leftMostV for next loop
511 leftMostV
[0] = lower_val
[j
-1];
512 leftMostV
[1] = v_lower
;
514 // leftMostNormal = lowerNormal[j-1];
515 // leftMostXYZ = lowerXYZ[j-1];
522 // free(upperNormal);
523 // free(lowerNormal);
530 OpenGLSurfaceEvaluator::evalVStrip(int n_left
, REAL u_left
, REAL
* left_val
, int n_right
, REAL u_right
, REAL
* right_val
)
532 #ifdef USE_INTERNAL_EVAL
533 inEvalVStrip(n_left
, u_left
, left_val
,
534 n_right
, u_right
, right_val
);
538 evalVStripExt(n_left
, u_left
, left_val
,
539 n_right
, u_right
, right_val
);
547 *the algorithm works by scanning from bot to top.
548 *botMostV: the bot most of the remaining verteces (on both left and right).
549 * it could an element of leftVerts or rightVerts.
550 *i: leftVerts[i] is the first vertex to the top of botMostV on left line
551 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
554 /*initialize i,j,and botMostV
556 if(left_val
[0] <= right_val
[0])
561 botMostV
[0] = u_left
;
562 botMostV
[1] = left_val
[0];
569 botMostV
[0] = u_right
;
570 botMostV
[1] = right_val
[0];
574 *the invariance is that:
575 *at the beginning of each loop, the meaning of i,j,and botMostV are
580 if(i
>= n_left
) /*case1: no more in left*/
582 if(j
<n_right
-1) /*at least two vertices in right*/
585 coord2f(botMostV
[0], botMostV
[1]);
587 coord2f(u_right
, right_val
[j
]);
588 // glNormal3fv(rightNormal[j]);
589 // glVertex3fv(rightXYZ[j]);
595 break; /*exit the main loop*/
597 else if(j
>= n_right
) /*case2: no more in right*/
599 if(i
<n_left
-1) /*at least two vertices in left*/
602 coord2f(botMostV
[0], botMostV
[1]);
603 // glNormal3fv(botMostNormal);
604 // glVertex3fv(botMostXYZ);
606 for(k
=n_left
-1; k
>=i
; k
--) /*reverse order for two-side lighting*/
608 coord2f(u_left
, left_val
[k
]);
609 // glNormal3fv(leftNormal[k]);
610 // glVertex3fv(leftXYZ[k]);
615 break; /*exit the main loop*/
617 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
619 if(left_val
[i
] <= right_val
[j
])
622 coord2f(u_right
, right_val
[j
]);
623 // glNormal3fv(rightNormal[j]);
624 // glVertex3fv(rightXYZ[j]);
626 /*find the last k>=i such that
627 *leftverts[k][0] <= rightverts[j][0]
633 if(left_val
[k
] > right_val
[j
])
641 for(l
=k
; l
>=i
; l
--)/*the reverse is for two-side lighting*/
643 coord2f(u_left
, left_val
[l
]);
644 // glNormal3fv(leftNormal[l]);
645 // glVertex3fv(leftXYZ[l]);
648 coord2f(botMostV
[0], botMostV
[1]);
649 // glNormal3fv(botMostNormal);
650 // glVertex3fv(botMostXYZ);
654 /*update i and botMostV for next loop
658 botMostV
[0] = u_left
;
659 botMostV
[1] = left_val
[k
];
660 // botMostNormal = leftNormal[k];
661 // botMostXYZ = leftXYZ[k];
663 else /*left_val[i] > right_val[j])*/
666 coord2f(u_left
, left_val
[i
]);
667 // glNormal3fv(leftNormal[i]);
668 // glVertex3fv(leftXYZ[i]);
670 coord2f(botMostV
[0], botMostV
[1]);
671 // glNormal3fv(botMostNormal);
672 // glVertex3fv(botMostXYZ);
675 /*find the last k>=j such that
676 *rightverts[k][0] < leftverts[i][0]
681 if(right_val
[k
] >= left_val
[i
])
683 coord2f(u_right
, right_val
[k
]);
684 // glNormal3fv(rightNormal[k]);
685 // glVertex3fv(rightXYZ[k]);
691 /*update j and botMostV for next loop
694 botMostV
[0] = u_right
;
695 botMostV
[1] = right_val
[j
-1];
697 // botMostNormal = rightNormal[j-1];
698 // botMostXYZ = rightXYZ[j-1];
706 // free(rightNormal);
712 OpenGLSurfaceEvaluator::bgnqstrip(void)
715 bezierPatchMeshBeginStrip(global_bpm
, GL_QUAD_STRIP
);
717 glBegin((GLenum
) GL_QUAD_STRIP
);
720 STAT_num_of_quad_strips
++;
725 OpenGLSurfaceEvaluator::endqstrip(void)
728 bezierPatchMeshEndStrip(global_bpm
);
734 /*-------------------------------------------------------------------------
735 * bgnmap2f - preamble to surface definition and evaluations
736 *-------------------------------------------------------------------------
739 OpenGLSurfaceEvaluator::bgnmap2f(long)
743 /*deallocate the space which may has been
744 *allocated by global_bpm previously
746 if(global_bpm
!= NULL
) {
747 bezierPatchMeshListDelete(global_bpm
);
753 auto_normal_flag = 1; //always output normal in callback mode.
754 //we could have used the following code,
755 //but Inspector doesn't have gl context
756 //before it calls tessellator.
757 //this way is temporary.
760 //if one of the two normal callback functions are set,
762 if(normalCallBackN
!= NULL
||
763 normalCallBackData
!= NULL
)
764 auto_normal_flag
= 1;
766 auto_normal_flag
= 0;
768 //initialize so that no maps initially
775 if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE)
776 auto_normal_flag = 1;
777 else if (callback_auto_normal == 1)
778 auto_normal_flag = 1;
780 auto_normal_flag = 0;
783 //NEWCALLBACK: no need to worry about gl states when gling clalback
787 glPushAttrib((GLbitfield
) GL_EVAL_BIT
);
789 /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE
791 glGetIntegerv(GL_POLYGON_MODE
, gl_polygon_mode
);
796 /*-------------------------------------------------------------------------
797 * endmap2f - postamble to a map
798 *-------------------------------------------------------------------------
801 OpenGLSurfaceEvaluator::endmap2f(void)
806 //bezierPatchMeshListDelDeg(global_bpm);
808 // bezierPatchMeshListEval(global_bpm);
811 //printf("surfcount=%i\n", surfcount);
812 //if(surfcount == 8) exit(0);
814 inBPMListEvalEM(global_bpm
);
819 global_bpm = bezierPatchMeshListReverse(global_bpm);
826 bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips);
827 drawStrips(vertex_array, normal_array, length_array, type_array, num_strips);
835 //bezierPatchMeshListPrint(global_bpm);
836 //bezierPatchMeshListDraw(global_bpm);
838 // printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm));
842 bezierPatchMeshListDelete(global_bpm
);
854 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
);
857 /*to restore the gl_polygon_mode
860 glPolygonMode( GL_FRONT
, (GLenum
) gl_polygon_mode
[0]);
861 glPolygonMode( GL_BACK
, (GLenum
) gl_polygon_mode
[1]);
867 /*-------------------------------------------------------------------------
868 * map2f - pass a desription of a surface map
869 *-------------------------------------------------------------------------
872 OpenGLSurfaceEvaluator::map2f(
874 REAL _ulower
, /* u lower domain coord */
875 REAL _uupper
, /* u upper domain coord */
876 long _ustride
, /* interpoint distance */
877 long _uorder
, /* parametric order */
878 REAL _vlower
, /* v lower domain coord */
879 REAL _vupper
, /* v upper domain coord */
880 long _vstride
, /* interpoint distance */
881 long _vorder
, /* parametric order */
882 REAL
*pts
) /* control points */
884 #ifdef USE_INTERNAL_EVAL
885 inMap2f((int) _type
, (REAL
) _ulower
, (REAL
) _uupper
,
886 (int) _ustride
, (int) _uorder
, (REAL
) _vlower
,
887 (REAL
) _vupper
, (int) _vstride
, (int) _vorder
,
895 if(global_bpm
== NULL
)
896 global_bpm
= bezierPatchMeshMake2(10,10);
898 (global_bpm
->bpatch
== NULL
&&
899 (_type
== GL_MAP2_VERTEX_3
|| _type
== GL_MAP2_VERTEX_4
))
901 (global_bpm
->bpatch_normal
== NULL
&&
902 (_type
== GL_MAP2_NORMAL
))
904 (global_bpm
->bpatch_color
== NULL
&&
905 (_type
== GL_MAP2_INDEX
|| _type
== GL_MAP2_COLOR_4
))
907 (global_bpm
->bpatch_texcoord
== NULL
&&
908 (_type
== GL_MAP2_TEXTURE_COORD_1
||
909 _type
== GL_MAP2_TEXTURE_COORD_2
||
910 _type
== GL_MAP2_TEXTURE_COORD_3
||
911 _type
== GL_MAP2_TEXTURE_COORD_4
)
914 bezierPatchMeshPutPatch(global_bpm
, (int) _type
, _ulower
, _uupper
,(int) _ustride
,(int) _uorder
,_vlower
, _vupper
, (int) _vstride
, (int) _vorder
, pts
);
916 else /*new surface patch (with multiple maps) starts*/
918 bezierPatchMesh
*temp
= bezierPatchMeshMake2(10,10);
919 bezierPatchMeshPutPatch(temp
, (int) _type
, _ulower
, _uupper
,(int) _ustride
,(int) _uorder
,_vlower
, _vupper
, (int) _vstride
, (int) _vorder
, pts
);
920 global_bpm
= bezierPatchMeshListInsert(global_bpm
, temp
);
923 global_bpm = bezierPatchMeshListInsert(global_bpm,
925 (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10));
929 else /*not output triangles*/
931 glMap2f((GLenum
) _type
, (GLfloat
) _ulower
, (GLfloat
) _uupper
,
932 (GLint
) _ustride
, (GLint
) _uorder
, (GLfloat
) _vlower
,
933 (GLfloat
) _vupper
, (GLint
) _vstride
, (GLint
) _vorder
,
934 (const GLfloat
*) pts
);
941 /*-------------------------------------------------------------------------
942 * mapmesh2f - evaluate a mesh of points on lattice
943 *-------------------------------------------------------------------------
946 OpenGLSurfaceEvaluator::mapmesh2f(long style
, long umin
, long umax
, long vmin
, long vmax
)
952 #ifdef USE_INTERNAL_EVAL
953 inEvalMesh2((int)umin
, (int)vmin
, (int)umax
, (int)vmax
);
961 bezierPatchMeshBeginStrip(global_bpm
, GL_POLYGON
);
962 bezierPatchMeshInsertUV(global_bpm
, global_grid_u0
, global_grid_v0
);
963 bezierPatchMeshInsertUV(global_bpm
, global_grid_u1
, global_grid_v1
);
964 bezierPatchMeshInsertUV(global_bpm
, (REAL
)global_grid_nu
, (REAL
)global_grid_nv
);
965 bezierPatchMeshInsertUV(global_bpm
, (REAL
)umin
, (REAL
)vmin
);
966 bezierPatchMeshInsertUV(global_bpm
, (REAL
)umax
, (REAL
)vmax
);
967 bezierPatchMeshEndStrip(global_bpm
);
973 if(global_grid_nu
== 0 || global_grid_nv
== 0)
974 return; /*no points need to be output*/
975 du
= (global_grid_u1
- global_grid_u0
) / (REAL
)global_grid_nu
;
976 dv
= (global_grid_v1
- global_grid_v0
) / (REAL
)global_grid_nv
;
978 if(global_grid_nu
>= global_grid_nv
){
980 for(i
=umin
; i
<umax
; i
++){
981 REAL u1
= (i
==global_grid_nu
)? global_grid_u1
:(global_grid_u0
+ i
*du
);
982 REAL u2
= ((i
+1) == global_grid_nu
)? global_grid_u1
: (global_grid_u0
+(i
+1)*du
);
985 for(j
=vmax
; j
>=vmin
; j
--){
986 REAL v1
= (j
== global_grid_nv
)? global_grid_v1
: (global_grid_v0
+j
*dv
);
996 for(i
=vmin
; i
<vmax
; i
++){
997 REAL v1
= (i
==global_grid_nv
)? global_grid_v1
:(global_grid_v0
+ i
*dv
);
998 REAL v2
= ((i
+1) == global_grid_nv
)? global_grid_v1
: (global_grid_v0
+(i
+1)*dv
);
1001 for(j
=umax
; j
>=umin
; j
--){
1002 REAL u1
= (j
== global_grid_nu
)? global_grid_u1
: (global_grid_u0
+j
*du
);
1016 glEvalMesh2((GLenum
) GL_FILL
, (GLint
) umin
, (GLint
) umax
,
1017 (GLint
) vmin
, (GLint
) vmax
);
1020 glEvalMesh2((GLenum
) GL_LINE
, (GLint
) umin
, (GLint
) umax
,
1021 (GLint
) vmin
, (GLint
) vmax
);
1024 glEvalMesh2((GLenum
) GL_POINT
, (GLint
) umin
, (GLint
) umax
,
1025 (GLint
) vmin
, (GLint
) vmax
);
1033 STAT_num_of_quad_strips
+= (umax
-umin
)*(vmax
-vmin
);
1037 /*-------------------------------------------------------------------------
1038 * evalcoord2f - evaluate a point on a surface
1039 *-------------------------------------------------------------------------
1042 OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u
, REAL v
)
1046 #ifdef NO_EVALUATION
1054 /*-------------------------------------------------------------------------
1055 * evalpoint2i - evaluate a grid point
1056 *-------------------------------------------------------------------------
1059 OpenGLSurfaceEvaluator::evalpoint2i(long u
, long v
)
1061 #ifdef NO_EVALUATION
1069 OpenGLSurfaceEvaluator::point2i( long u
, long v
)
1071 #ifdef NO_EVALUATION
1075 #ifdef USE_INTERNAL_EVAL
1076 inEvalPoint2( (int)u
, (int)v
);
1080 if(output_triangles
)
1085 du
= (global_grid_u1
- global_grid_u0
) / (REAL
)global_grid_nu
;
1086 dv
= (global_grid_v1
- global_grid_v0
) / (REAL
)global_grid_nv
;
1087 fu
= (u
==global_grid_nu
)? global_grid_u1
:(global_grid_u0
+ u
*du
);
1088 fv
= (v
== global_grid_nv
)? global_grid_v1
: (global_grid_v0
+v
*dv
);
1092 glEvalPoint2((GLint
) u
, (GLint
) v
);
1098 STAT_num_of_eval_vertices
++;
1106 OpenGLSurfaceEvaluator::coord2f( REAL u
, REAL v
)
1108 #ifdef NO_EVALUATION
1112 #ifdef USE_INTERNAL_EVAL
1113 inEvalCoord2f( u
, v
);
1117 if(output_triangles
)
1118 bezierPatchMeshInsertUV(global_bpm
, u
,v
);
1120 glEvalCoord2f((GLfloat
) u
, (GLfloat
) v
);
1127 STAT_num_of_eval_vertices
++;
1134 OpenGLSurfaceEvaluator::newtmeshvert( long u
, long v
)
1136 #ifdef NO_EVALUATION
1143 vertexCache
[0]->invoke(this);
1144 vertexCache
[1]->invoke(this);
1151 vertexCache
[which
]->saveEvalPoint(u
, v
);
1160 OpenGLSurfaceEvaluator::newtmeshvert( REAL u
, REAL v
)
1162 #ifdef NO_EVALUATION
1169 vertexCache
[0]->invoke(this);
1170 vertexCache
[1]->invoke(this);
1177 vertexCache
[which
]->saveEvalCoord(u
, v
);
1188 OpenGLSurfaceEvaluator::putCallBack(GLenum which
, _GLUfuncptr fn
)
1192 case GLU_NURBS_BEGIN
:
1193 beginCallBackN
= (void (GLAPIENTRY
*) (GLenum
)) fn
;
1196 endCallBackN
= (void (GLAPIENTRY
*) (void)) fn
;
1198 case GLU_NURBS_VERTEX
:
1199 vertexCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1201 case GLU_NURBS_NORMAL
:
1202 normalCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1204 case GLU_NURBS_COLOR
:
1205 colorCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1207 case GLU_NURBS_TEXTURE_COORD
:
1208 texcoordCallBackN
= (void (GLAPIENTRY
*) (const GLfloat
*)) fn
;
1210 case GLU_NURBS_BEGIN_DATA
:
1211 beginCallBackData
= (void (GLAPIENTRY
*) (GLenum
, void*)) fn
;
1213 case GLU_NURBS_END_DATA
:
1214 endCallBackData
= (void (GLAPIENTRY
*) (void*)) fn
;
1216 case GLU_NURBS_VERTEX_DATA
:
1217 vertexCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1219 case GLU_NURBS_NORMAL_DATA
:
1220 normalCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1222 case GLU_NURBS_COLOR_DATA
:
1223 colorCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1225 case GLU_NURBS_TEXTURE_COORD_DATA
:
1226 texcoordCallBackData
= (void (GLAPIENTRY
*) (const GLfloat
*, void*)) fn
;
1234 OpenGLSurfaceEvaluator::beginCallBack(GLenum which
, void *data
)
1236 if(beginCallBackData
)
1237 beginCallBackData(which
, data
);
1238 else if(beginCallBackN
)
1239 beginCallBackN(which
);
1243 OpenGLSurfaceEvaluator::endCallBack(void *data
)
1246 endCallBackData(data
);
1247 else if(endCallBackN
)
1252 OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat
*vert
, void* data
)
1254 if(vertexCallBackData
)
1255 vertexCallBackData(vert
, data
);
1256 else if(vertexCallBackN
)
1257 vertexCallBackN(vert
);
1262 OpenGLSurfaceEvaluator::normalCallBack(const GLfloat
*normal
, void* data
)
1264 if(normalCallBackData
)
1265 normalCallBackData(normal
, data
);
1266 else if(normalCallBackN
)
1267 normalCallBackN(normal
);
1271 OpenGLSurfaceEvaluator::colorCallBack(const GLfloat
*color
, void* data
)
1273 if(colorCallBackData
)
1274 colorCallBackData(color
, data
);
1275 else if(colorCallBackN
)
1276 colorCallBackN(color
);
1280 OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat
*texcoord
, void* data
)
1282 if(texcoordCallBackData
)
1283 texcoordCallBackData(texcoord
, data
);
1284 else if(texcoordCallBackN
)
1285 texcoordCallBackN(texcoord
);