source: trunk/src/opengl/glu/nurbs/interface/glsurfeval.cpp

Last change on this file was 3079, checked in by jeroen, 26 years ago

* empty log message *

File size: 32.2 KB
Line 
1/* $Id: glsurfeval.cpp,v 1.3 2000-03-11 09:05:02 jeroen Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34*/
35
36/*
37 * glsurfeval.c++
38 *
39 * $Date: 2000-03-11 09:05:02 $ $Revision: 1.3 $
40 * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/interface/glsurfeval.cpp,v 1.3 2000-03-11 09:05:02 jeroen Exp $
41 */
42
43/* Polynomial Evaluator Interface */
44#include "gluos.h"
45#include "gl.h"
46#include "glu.h"
47#include <stdio.h>
48#include "glimports.h"
49#include "glrenderer.h"
50#include "glsurfeval.h"
51#include "nurbsconsts.h"
52#include "bezierPatchMesh.h"
53
54//extern int surfcount;
55//int surfcount=0;
56
57#define USE_INTERNAL_EVAL /* use internal evaluator*/
58
59/*whether do evaluation or not*/
60/*#define NO_EVALUATION*/
61
62//#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too
63
64/*for statistics*/
65//#define STATISTICS
66#ifdef STATISTICS
67static int STAT_num_of_triangles=0;
68static int STAT_num_of_eval_vertices=0;
69static int STAT_num_of_quad_strips=0;
70#endif
71
72/*for output triangles*/
73/*#define OUTPUT_TRIANGLES*/
74
75
76/*#define FOR_CHRIS*/
77#ifdef FOR_CHRIS
78extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val,
79 int n_lower, REAL v_lower, REAL* lower_val);}
80
81extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val,
82 int n_right, REAL u_right, REAL* right_val);
83 }
84#endif
85
86
87/**************begin for LOD_eval_list***********/
88void OpenGLSurfaceEvaluator::LOD_eval_list(int level)
89{
90 if(level == 0)
91 LOD_eval_level = 1;
92 else if(level == 1)
93 LOD_eval_level = 2;
94 else if(level == 2)
95 LOD_eval_level = 4;
96 else
97 LOD_eval_level = 8;
98
99 inBPMListEvalEM(global_bpm);
100}
101
102
103OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
104{
105 int i;
106
107 for (i=0; i<VERTEX_CACHE_SIZE; i++) {
108 vertexCache[i] = new StoredVertex;
109 }
110 tmeshing = 0;
111 which = 0;
112 vcount = 0;
113
114 global_uorder = 0;
115 global_vorder = 0;
116 global_uprime = -1.0;
117 global_vprime = -1.0;
118 global_vprime_BV = -1.0;
119 global_uprime_BU = -1.0;
120 global_uorder_BU = 0;
121 global_vorder_BU = 0;
122 global_uorder_BV = 0;
123 global_vorder_BV = 0;
124 global_baseData = NULL;
125
126 global_bpm = NULL;
127 output_triangles = 0; //don't output triangles by default
128
129 //no default callback functions
130 beginCallBackN = NULL;
131 endCallBackN = NULL;
132 vertexCallBackN = NULL;
133 normalCallBackN = NULL;
134 colorCallBackN = NULL;
135 texcoordCallBackN = NULL;
136 beginCallBackData = NULL;
137 endCallBackData = NULL;
138 vertexCallBackData = NULL;
139 normalCallBackData = NULL;
140 colorCallBackData = NULL;
141 texcoordCallBackData = NULL;
142
143 userData = NULL;
144
145 auto_normal_flag = 0;
146 callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0
147 vertex_flag = 0;
148 normal_flag = 0;
149 color_flag = 0;
150 texcoord_flag = 0;
151
152 em_vertex.uprime = -1.0;
153 em_vertex.vprime = -1.0;
154 em_normal.uprime = -1.0;
155 em_normal.vprime = -1.0;
156 em_color.uprime = -1.0;
157 em_color.vprime = -1.0;
158 em_texcoord.uprime = -1.0;
159 em_texcoord.vprime = -1.0;
160
161#ifdef USE_LOD
162 LOD_eval_level = 1;
163#endif
164}
165
166OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
167{
168 for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) {
169 delete vertexCache[ii];
170 vertexCache[ii]= 0;
171 }
172}
173
174/*---------------------------------------------------------------------------
175 * disable - turn off a map
176 *---------------------------------------------------------------------------
177 */
178void
179OpenGLSurfaceEvaluator::disable(long type)
180{
181 glDisable((GLenum) type);
182}
183
184/*---------------------------------------------------------------------------
185 * enable - turn on a map
186 *---------------------------------------------------------------------------
187 */
188void
189OpenGLSurfaceEvaluator::enable(long type)
190{
191 glEnable((GLenum) type);
192}
193
194/*-------------------------------------------------------------------------
195 * mapgrid2f - define a lattice of points with origin and offset
196 *-------------------------------------------------------------------------
197 */
198void
199OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1)
200{
201#ifdef USE_INTERNAL_EVAL
202 inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv,
203 (REAL) v0, (REAL) v1);
204#else
205
206 if(output_triangles)
207 {
208 global_grid_u0 = u0;
209 global_grid_u1 = u1;
210 global_grid_nu = nu;
211 global_grid_v0 = v0;
212 global_grid_v1 = v1;
213 global_grid_nv = nv;
214 }
215 else
216 glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv,
217 (GLdouble) v0, (GLdouble) v1);
218
219#endif
220}
221
222void
223OpenGLSurfaceEvaluator::polymode(long style)
224{
225 if(! output_triangles)
226 {
227 switch(style) {
228 default:
229 case N_MESHFILL:
230
231 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL);
232 break;
233 case N_MESHLINE:
234 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE);
235 break;
236 case N_MESHPOINT:
237 glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT);
238 break;
239 }
240 }
241}
242
243void
244OpenGLSurfaceEvaluator::bgnline(void)
245{
246 if(output_triangles)
247 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP);
248 else
249 glBegin((GLenum) GL_LINE_STRIP);
250}
251
252void
253OpenGLSurfaceEvaluator::endline(void)
254{
255 if(output_triangles)
256 bezierPatchMeshEndStrip(global_bpm);
257 else
258 glEnd();
259}
260
261void
262OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to)
263{
264}
265
266void
267OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi)
268{
269}
270
271void
272OpenGLSurfaceEvaluator::bgnclosedline(void)
273{
274 if(output_triangles)
275 bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP);
276 else
277 glBegin((GLenum) GL_LINE_LOOP);
278}
279
280void
281OpenGLSurfaceEvaluator::endclosedline(void)
282{
283 if(output_triangles)
284 bezierPatchMeshEndStrip(global_bpm);
285 else
286 glEnd();
287}
288
289
290
291
292
293void
294OpenGLSurfaceEvaluator::bgntmesh(void)
295{
296
297 tmeshing = 1;
298 which = 0;
299 vcount = 0;
300
301 if(output_triangles)
302 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES);
303 else
304 glBegin((GLenum) GL_TRIANGLES);
305
306}
307
308void
309OpenGLSurfaceEvaluator::swaptmesh(void)
310{
311 which = 1 - which;
312
313}
314
315void
316OpenGLSurfaceEvaluator::endtmesh(void)
317{
318 tmeshing = 0;
319
320
321 if(output_triangles)
322 bezierPatchMeshEndStrip(global_bpm);
323 else
324 glEnd();
325}
326
327void
328OpenGLSurfaceEvaluator::bgntfan(void)
329{
330
331 if(output_triangles)
332 bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN);
333 else
334 glBegin((GLenum) GL_TRIANGLE_FAN);
335
336}
337void
338OpenGLSurfaceEvaluator::endtfan(void)
339{
340 if(output_triangles)
341 bezierPatchMeshEndStrip(global_bpm);
342 else
343 glEnd();
344}
345
346void
347OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
348{
349#ifdef USE_INTERNAL_EVAL
350 inEvalUStrip(n_upper, v_upper, upper_val,
351 n_lower, v_lower, lower_val);
352#else
353
354#ifdef FOR_CHRIS
355 evalUStripExt(n_upper, v_upper, upper_val,
356 n_lower, v_lower, lower_val);
357 return;
358
359#endif
360 int i,j,k,l;
361 REAL leftMostV[2];
362
363 /*
364 *the algorithm works by scanning from left to right.
365 *leftMostV: the left most of the remaining verteces (on both upper and lower).
366 * it could an element of upperVerts or lowerVerts.
367 *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
368 *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
369 */
370
371 /*initialize i,j,and leftMostV
372 */
373 if(upper_val[0] <= lower_val[0])
374 {
375 i=1;
376 j=0;
377
378 leftMostV[0] = upper_val[0];
379 leftMostV[1] = v_upper;
380 }
381 else
382 {
383 i=0;
384 j=1;
385
386 leftMostV[0] = lower_val[0];
387 leftMostV[1] = v_lower;
388
389 }
390
391 /*the main loop.
392 *the invariance is that:
393 *at the beginning of each loop, the meaning of i,j,and leftMostV are
394 *maintained
395 */
396 while(1)
397 {
398 if(i >= n_upper) /*case1: no more in upper*/
399 {
400 if(j<n_lower-1) /*at least two vertices in lower*/
401 {
402 bgntfan();
403 coord2f(leftMostV[0], leftMostV[1]);
404// glNormal3fv(leftMostNormal);
405// glVertex3fv(leftMostXYZ);
406
407 while(j<n_lower){
408 coord2f(lower_val[j], v_lower);
409// glNormal3fv(lowerNormal[j]);
410// glVertex3fv(lowerXYZ[j]);
411 j++;
412
413 }
414 endtfan();
415 }
416 break; /*exit the main loop*/
417 }
418 else if(j>= n_lower) /*case2: no more in lower*/
419 {
420 if(i<n_upper-1) /*at least two vertices in upper*/
421 {
422 bgntfan();
423 coord2f(leftMostV[0], leftMostV[1]);
424// glNormal3fv(leftMostNormal);
425// glVertex3fv(leftMostXYZ);
426
427 for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
428 {
429 coord2f(upper_val[k], v_upper);
430// glNormal3fv(upperNormal[k]);
431// glVertex3fv(upperXYZ[k]);
432 }
433
434 endtfan();
435 }
436 break; /*exit the main loop*/
437 }
438 else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
439 {
440 if(upper_val[i] <= lower_val[j])
441 {
442 bgntfan();
443 coord2f(lower_val[j], v_lower);
444// glNormal3fv(lowerNormal[j]);
445// glVertex3fv(lowerXYZ[j]);
446
447 /*find the last k>=i such that
448 *upperverts[k][0] <= lowerverts[j][0]
449 */
450 k=i;
451
452 while(k<n_upper)
453 {
454 if(upper_val[k] > lower_val[j])
455 break;
456 k++;
457
458 }
459 k--;
460
461
462 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
463 {
464 coord2f(upper_val[l], v_upper);
465// glNormal3fv(upperNormal[l]);
466// glVertex3fv(upperXYZ[l]);
467
468 }
469 coord2f(leftMostV[0], leftMostV[1]);
470// glNormal3fv(leftMostNormal);
471// glVertex3fv(leftMostXYZ);
472
473 endtfan();
474
475 /*update i and leftMostV for next loop
476 */
477 i = k+1;
478
479 leftMostV[0] = upper_val[k];
480 leftMostV[1] = v_upper;
481// leftMostNormal = upperNormal[k];
482// leftMostXYZ = upperXYZ[k];
483 }
484 else /*upperVerts[i][0] > lowerVerts[j][0]*/
485 {
486 bgntfan();
487 coord2f(upper_val[i], v_upper);
488// glNormal3fv(upperNormal[i]);
489// glVertex3fv(upperXYZ[i]);
490
491 coord2f(leftMostV[0], leftMostV[1]);
492// glNormal3fv(leftMostNormal);
493// glVertex3fv(leftMostXYZ);
494
495
496 /*find the last k>=j such that
497 *lowerverts[k][0] < upperverts[i][0]
498 */
499 k=j;
500 while(k< n_lower)
501 {
502 if(lower_val[k] >= upper_val[i])
503 break;
504 coord2f(lower_val[k], v_lower);
505// glNormal3fv(lowerNormal[k]);
506// glVertex3fv(lowerXYZ[k]);
507
508 k++;
509 }
510 endtfan();
511
512 /*update j and leftMostV for next loop
513 */
514 j=k;
515 leftMostV[0] = lower_val[j-1];
516 leftMostV[1] = v_lower;
517
518// leftMostNormal = lowerNormal[j-1];
519// leftMostXYZ = lowerXYZ[j-1];
520 }
521 }
522 }
523 //clean up
524// free(upperXYZ);
525// free(lowerXYZ);
526// free(upperNormal);
527// free(lowerNormal);
528#endif
529
530}
531
532
533void
534OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
535{
536#ifdef USE_INTERNAL_EVAL
537 inEvalVStrip(n_left, u_left, left_val,
538 n_right, u_right, right_val);
539#else
540
541#ifdef FOR_CHRIS
542 evalVStripExt(n_left, u_left, left_val,
543 n_right, u_right, right_val);
544 return;
545
546#endif
547
548 int i,j,k,l;
549 REAL botMostV[2];
550 /*
551 *the algorithm works by scanning from bot to top.
552 *botMostV: the bot most of the remaining verteces (on both left and right).
553 * it could an element of leftVerts or rightVerts.
554 *i: leftVerts[i] is the first vertex to the top of botMostV on left line
555 *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
556 */
557
558 /*initialize i,j,and botMostV
559 */
560 if(left_val[0] <= right_val[0])
561 {
562 i=1;
563 j=0;
564
565 botMostV[0] = u_left;
566 botMostV[1] = left_val[0];
567 }
568 else
569 {
570 i=0;
571 j=1;
572
573 botMostV[0] = u_right;
574 botMostV[1] = right_val[0];
575 }
576
577 /*the main loop.
578 *the invariance is that:
579 *at the beginning of each loop, the meaning of i,j,and botMostV are
580 *maintained
581 */
582 while(1)
583 {
584 if(i >= n_left) /*case1: no more in left*/
585 {
586 if(j<n_right-1) /*at least two vertices in right*/
587 {
588 bgntfan();
589 coord2f(botMostV[0], botMostV[1]);
590 while(j<n_right){
591 coord2f(u_right, right_val[j]);
592// glNormal3fv(rightNormal[j]);
593// glVertex3fv(rightXYZ[j]);
594 j++;
595
596 }
597 endtfan();
598 }
599 break; /*exit the main loop*/
600 }
601 else if(j>= n_right) /*case2: no more in right*/
602 {
603 if(i<n_left-1) /*at least two vertices in left*/
604 {
605 bgntfan();
606 coord2f(botMostV[0], botMostV[1]);
607// glNormal3fv(botMostNormal);
608// glVertex3fv(botMostXYZ);
609
610 for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
611 {
612 coord2f(u_left, left_val[k]);
613// glNormal3fv(leftNormal[k]);
614// glVertex3fv(leftXYZ[k]);
615 }
616
617 endtfan();
618 }
619 break; /*exit the main loop*/
620 }
621 else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
622 {
623 if(left_val[i] <= right_val[j])
624 {
625 bgntfan();
626 coord2f(u_right, right_val[j]);
627// glNormal3fv(rightNormal[j]);
628// glVertex3fv(rightXYZ[j]);
629
630 /*find the last k>=i such that
631 *leftverts[k][0] <= rightverts[j][0]
632 */
633 k=i;
634
635 while(k<n_left)
636 {
637 if(left_val[k] > right_val[j])
638 break;
639 k++;
640
641 }
642 k--;
643
644
645 for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
646 {
647 coord2f(u_left, left_val[l]);
648// glNormal3fv(leftNormal[l]);
649// glVertex3fv(leftXYZ[l]);
650
651 }
652 coord2f(botMostV[0], botMostV[1]);
653// glNormal3fv(botMostNormal);
654// glVertex3fv(botMostXYZ);
655
656 endtfan();
657
658 /*update i and botMostV for next loop
659 */
660 i = k+1;
661
662 botMostV[0] = u_left;
663 botMostV[1] = left_val[k];
664// botMostNormal = leftNormal[k];
665// botMostXYZ = leftXYZ[k];
666 }
667 else /*left_val[i] > right_val[j])*/
668 {
669 bgntfan();
670 coord2f(u_left, left_val[i]);
671// glNormal3fv(leftNormal[i]);
672// glVertex3fv(leftXYZ[i]);
673
674 coord2f(botMostV[0], botMostV[1]);
675// glNormal3fv(botMostNormal);
676// glVertex3fv(botMostXYZ);
677
678
679 /*find the last k>=j such that
680 *rightverts[k][0] < leftverts[i][0]
681 */
682 k=j;
683 while(k< n_right)
684 {
685 if(right_val[k] >= left_val[i])
686 break;
687 coord2f(u_right, right_val[k]);
688// glNormal3fv(rightNormal[k]);
689// glVertex3fv(rightXYZ[k]);
690
691 k++;
692 }
693 endtfan();
694
695 /*update j and botMostV for next loop
696 */
697 j=k;
698 botMostV[0] = u_right;
699 botMostV[1] = right_val[j-1];
700
701// botMostNormal = rightNormal[j-1];
702// botMostXYZ = rightXYZ[j-1];
703 }
704 }
705 }
706 //clean up
707// free(leftXYZ);
708// free(leftNormal);
709// free(rightXYZ);
710// free(rightNormal);
711#endif
712}
713
714
715void
716OpenGLSurfaceEvaluator::bgnqstrip(void)
717{
718 if(output_triangles)
719 bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP);
720 else
721 glBegin((GLenum) GL_QUAD_STRIP);
722
723#ifdef STATISTICS
724 STAT_num_of_quad_strips++;
725#endif
726}
727
728void
729OpenGLSurfaceEvaluator::endqstrip(void)
730{
731 if(output_triangles)
732 bezierPatchMeshEndStrip(global_bpm);
733 else
734 glEnd();
735
736}
737
738/*-------------------------------------------------------------------------
739 * bgnmap2f - preamble to surface definition and evaluations
740 *-------------------------------------------------------------------------
741 */
742void
743OpenGLSurfaceEvaluator::bgnmap2f(long)
744{
745 if(output_triangles)
746 {
747 /*deallocate the space which may has been
748 *allocated by global_bpm previously
749 */
750 if(global_bpm != NULL) {
751 bezierPatchMeshListDelete(global_bpm);
752 global_bpm = NULL;
753 }
754
755
756 /*
757 auto_normal_flag = 1; //always output normal in callback mode.
758 //we could have used the following code,
759 //but Inspector doesn't have gl context
760 //before it calls tessellator.
761 //this way is temporary.
762 */
763 //NEWCALLBACK
764 //if one of the two normal callback functions are set,
765 //then set
766 if(normalCallBackN != NULL ||
767 normalCallBackData != NULL)
768 auto_normal_flag = 1;
769 else
770 auto_normal_flag = 0;
771
772 //initialize so that no maps initially
773 vertex_flag = 0;
774 normal_flag = 0;
775 color_flag = 0;
776 texcoord_flag = 0;
777
778 /*
779 if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE)
780 auto_normal_flag = 1;
781 else if (callback_auto_normal == 1)
782 auto_normal_flag = 1;
783 else
784 auto_normal_flag = 0;
785 */
786
787 //NEWCALLBACK: no need to worry about gl states when gling clalback
788 }
789 else
790 {
791 glPushAttrib((GLbitfield) GL_EVAL_BIT);
792
793 /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE
794 */
795 glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode);
796 }
797
798}
799
800/*-------------------------------------------------------------------------
801 * endmap2f - postamble to a map
802 *-------------------------------------------------------------------------
803 */
804void
805OpenGLSurfaceEvaluator::endmap2f(void)
806{
807
808 if(output_triangles)
809 {
810 //bezierPatchMeshListDelDeg(global_bpm);
811
812 // bezierPatchMeshListEval(global_bpm);
813
814 //surfcount++;
815 //printf("surfcount=%i\n", surfcount);
816 //if(surfcount == 8) exit(0);
817
818 inBPMListEvalEM(global_bpm);
819
820
821
822/*
823 global_bpm = bezierPatchMeshListReverse(global_bpm);
824 {
825 float *vertex_array;
826 float *normal_array;
827 int *length_array;
828 int *type_array;
829 int num_strips;
830 bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips);
831 drawStrips(vertex_array, normal_array, length_array, type_array, num_strips);
832 free(vertex_array);
833 free(normal_array);
834 free(length_array);
835 free(type_array);
836 }
837*/
838
839 //bezierPatchMeshListPrint(global_bpm);
840 //bezierPatchMeshListDraw(global_bpm);
841
842// printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm));
843
844#ifdef USE_LOD
845#else
846 bezierPatchMeshListDelete(global_bpm);
847 global_bpm = NULL;
848#endif
849
850 }
851else
852 {
853#ifndef USE_LOD
854glPopAttrib();
855#endif
856
857#ifdef STATISTICS
858 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#endif
860
861 /*to restore the gl_polygon_mode
862 */
863#ifndef USE_LOD
864 glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]);
865 glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]);
866#endif
867}
868
869}
870
871/*-------------------------------------------------------------------------
872 * map2f - pass a desription of a surface map
873 *-------------------------------------------------------------------------
874 */
875void
876OpenGLSurfaceEvaluator::map2f(
877 long _type,
878 REAL _ulower, /* u lower domain coord */
879 REAL _uupper, /* u upper domain coord */
880 long _ustride, /* interpoint distance */
881 long _uorder, /* parametric order */
882 REAL _vlower, /* v lower domain coord */
883 REAL _vupper, /* v upper domain coord */
884 long _vstride, /* interpoint distance */
885 long _vorder, /* parametric order */
886 REAL *pts) /* control points */
887{
888#ifdef USE_INTERNAL_EVAL
889 inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper,
890 (int) _ustride, (int) _uorder, (REAL) _vlower,
891 (REAL) _vupper, (int) _vstride, (int) _vorder,
892 (REAL *) pts);
893#else
894
895
896
897 if(output_triangles)
898 {
899 if(global_bpm == NULL)
900 global_bpm = bezierPatchMeshMake2(10,10);
901 if(
902 (global_bpm->bpatch == NULL &&
903 (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4))
904 ||
905 (global_bpm->bpatch_normal == NULL &&
906 (_type == GL_MAP2_NORMAL))
907 ||
908 (global_bpm->bpatch_color == NULL &&
909 (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4))
910 ||
911 (global_bpm->bpatch_texcoord == NULL &&
912 (_type == GL_MAP2_TEXTURE_COORD_1 ||
913 _type == GL_MAP2_TEXTURE_COORD_2 ||
914 _type == GL_MAP2_TEXTURE_COORD_3 ||
915 _type == GL_MAP2_TEXTURE_COORD_4 )
916 ))
917 {
918 bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
919 }
920 else /*new surface patch (with multiple maps) starts*/
921 {
922 bezierPatchMesh *temp = bezierPatchMeshMake2(10,10);
923 bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
924 global_bpm = bezierPatchMeshListInsert(global_bpm, temp);
925
926 /*
927 global_bpm = bezierPatchMeshListInsert(global_bpm,
928 bezierPatchMeshMake(
929 (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10));
930 */
931 }
932 }
933 else /*not output triangles*/
934 {
935 glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper,
936 (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower,
937 (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder,
938 (const GLfloat *) pts);
939 }
940
941#endif
942}
943
944
945/*-------------------------------------------------------------------------
946 * mapmesh2f - evaluate a mesh of points on lattice
947 *-------------------------------------------------------------------------
948 */
949void
950OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax)
951{
952#ifdef NO_EVALUATION
953return;
954#endif
955
956#ifdef USE_INTERNAL_EVAL
957 inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax);
958#else
959
960
961
962if(output_triangles)
963{
964#ifdef USE_LOD
965 bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON);
966 bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0);
967 bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1);
968 bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv);
969 bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin);
970 bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax);
971 bezierPatchMeshEndStrip(global_bpm);
972
973#else
974
975 REAL du, dv;
976 long i,j;
977 long row;
978 if(global_grid_nu == 0 || global_grid_nv == 0)
979 return; /*no points need to be output*/
980 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
981 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
982
983 if(global_grid_nu >= global_grid_nv){
984
985 for(i=umin; i<umax; i++){
986 REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
987 REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
988
989 bgnqstrip();
990 for(j=vmax; j>=vmin; j--){
991 REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
992
993 coord2f(u1, v1);
994 coord2f(u2, v1);
995 }
996 endqstrip();
997 }
998 }
999 else{
1000
1001 for(i=vmin; i<vmax; i++){
1002 REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
1003 REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
1004
1005 bgnqstrip();
1006 for(j=umax; j>=umin; j--){
1007 REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
1008 coord2f(u1, v2);
1009 coord2f(u1, v1);
1010 }
1011 endqstrip();
1012 }
1013 }
1014#endif
1015}
1016else
1017{
1018 switch(style) {
1019 default:
1020 case N_MESHFILL:
1021 glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax,
1022 (GLint) vmin, (GLint) vmax);
1023 break;
1024 case N_MESHLINE:
1025 glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax,
1026 (GLint) vmin, (GLint) vmax);
1027 break;
1028 case N_MESHPOINT:
1029 glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax,
1030 (GLint) vmin, (GLint) vmax);
1031 break;
1032 }
1033 }
1034
1035#endif
1036
1037#ifdef STATISTICS
1038 STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin);
1039#endif
1040}
1041
1042/*-------------------------------------------------------------------------
1043 * evalcoord2f - evaluate a point on a surface
1044 *-------------------------------------------------------------------------
1045 */
1046void
1047OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v)
1048{
1049
1050
1051#ifdef NO_EVALUATION
1052return;
1053#endif
1054
1055
1056 newtmeshvert(u, v);
1057}
1058
1059/*-------------------------------------------------------------------------
1060 * evalpoint2i - evaluate a grid point
1061 *-------------------------------------------------------------------------
1062 */
1063void
1064OpenGLSurfaceEvaluator::evalpoint2i(long u, long v)
1065{
1066#ifdef NO_EVALUATION
1067return;
1068#endif
1069
1070 newtmeshvert(u, v);
1071}
1072
1073void
1074OpenGLSurfaceEvaluator::point2i( long u, long v )
1075{
1076#ifdef NO_EVALUATION
1077return;
1078#else
1079
1080#ifdef USE_INTERNAL_EVAL
1081 inEvalPoint2( (int)u, (int)v);
1082#else
1083
1084
1085if(output_triangles)
1086{
1087
1088 REAL du, dv;
1089 REAL fu,fv;
1090 du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
1091 dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
1092 fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du);
1093 fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv);
1094 coord2f(fu,fv);
1095}
1096else
1097 glEvalPoint2((GLint) u, (GLint) v);
1098
1099
1100#endif
1101
1102#ifdef STATISTICS
1103 STAT_num_of_eval_vertices++;
1104#endif
1105
1106#endif
1107
1108}
1109
1110void
1111OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v )
1112{
1113#ifdef NO_EVALUATION
1114return;
1115#else
1116
1117#ifdef USE_INTERNAL_EVAL
1118 inEvalCoord2f( u, v);
1119#else
1120
1121
1122if(output_triangles)
1123 bezierPatchMeshInsertUV(global_bpm, u,v);
1124else
1125 glEvalCoord2f((GLfloat) u, (GLfloat) v);
1126
1127#endif
1128
1129
1130#ifdef STATISTICS
1131 STAT_num_of_eval_vertices++;
1132#endif
1133
1134#endif
1135}
1136
1137void
1138OpenGLSurfaceEvaluator::newtmeshvert( long u, long v )
1139{
1140#ifdef NO_EVALUATION
1141return;
1142#else
1143
1144 if (tmeshing) {
1145
1146 if (vcount == 2) {
1147 vertexCache[0]->invoke(this);
1148 vertexCache[1]->invoke(this);
1149 point2i( u, v);
1150
1151 } else {
1152 vcount++;
1153 }
1154
1155 vertexCache[which]->saveEvalPoint(u, v);
1156 which = 1 - which;
1157 } else {
1158 point2i( u, v);
1159 }
1160#endif
1161}
1162
1163void
1164OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v )
1165{
1166#ifdef NO_EVALUATION
1167return;
1168#else
1169 if (tmeshing) {
1170
1171
1172 if (vcount == 2) {
1173 vertexCache[0]->invoke(this);
1174 vertexCache[1]->invoke(this);
1175 coord2f(u,v);
1176
1177 } else {
1178 vcount++;
1179 }
1180
1181 vertexCache[which]->saveEvalCoord(u, v);
1182 which = 1 - which;
1183 } else {
1184
1185 coord2f( u, v);
1186 }
1187#endif
1188
1189}
1190
1191void
1192OpenGLSurfaceEvaluator::putCallBack(GLenum which, GLvoid (GLCALLBACK *fn)(...))
1193{
1194 switch(which)
1195 {
1196 case GLU_NURBS_BEGIN:
1197 beginCallBackN = (void (GLCALLBACK *) (GLenum)) fn;
1198 break;
1199 case GLU_NURBS_END:
1200 endCallBackN = (void (GLCALLBACK *) (void)) fn;
1201 break;
1202 case GLU_NURBS_VERTEX:
1203 vertexCallBackN = (void (GLCALLBACK *) (const GLfloat*)) fn;
1204 break;
1205 case GLU_NURBS_NORMAL:
1206 normalCallBackN = (void (GLCALLBACK *) (const GLfloat*)) fn;
1207 break;
1208 case GLU_NURBS_COLOR:
1209 colorCallBackN = (void (GLCALLBACK *) (const GLfloat*)) fn;
1210 break;
1211 case GLU_NURBS_TEXTURE_COORD:
1212 texcoordCallBackN = (void (GLCALLBACK *) (const GLfloat*)) fn;
1213 break;
1214 case GLU_NURBS_BEGIN_DATA:
1215 beginCallBackData = (void (GLCALLBACK *) (GLenum, void*)) fn;
1216 break;
1217 case GLU_NURBS_END_DATA:
1218 endCallBackData = (void (GLCALLBACK *) (void*)) fn;
1219 break;
1220 case GLU_NURBS_VERTEX_DATA:
1221 vertexCallBackData = (void (GLCALLBACK *) (const GLfloat*, void*)) fn;
1222 break;
1223 case GLU_NURBS_NORMAL_DATA:
1224 normalCallBackData = (void (GLCALLBACK *) (const GLfloat*, void*)) fn;
1225 break;
1226 case GLU_NURBS_COLOR_DATA:
1227 colorCallBackData = (void (GLCALLBACK *) (const GLfloat*, void*)) fn;
1228 break;
1229 case GLU_NURBS_TEXTURE_COORD_DATA:
1230 texcoordCallBackData = (void (GLCALLBACK *) (const GLfloat*, void*)) fn;
1231 break;
1232
1233 }
1234}
1235
1236
1237void
1238OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data)
1239{
1240 if(beginCallBackData)
1241 beginCallBackData(which, data);
1242 else if(beginCallBackN)
1243 beginCallBackN(which);
1244}
1245
1246void
1247OpenGLSurfaceEvaluator::endCallBack(void *data)
1248{
1249 if(endCallBackData)
1250 endCallBackData(data);
1251 else if(endCallBackN)
1252 endCallBackN();
1253}
1254
1255void
1256OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data)
1257{
1258 if(vertexCallBackData)
1259 vertexCallBackData(vert, data);
1260 else if(vertexCallBackN)
1261 vertexCallBackN(vert);
1262}
1263
1264
1265void
1266OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data)
1267{
1268 if(normalCallBackData)
1269 normalCallBackData(normal, data);
1270 else if(normalCallBackN)
1271 normalCallBackN(normal);
1272}
1273
1274void
1275OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data)
1276{
1277 if(colorCallBackData)
1278 colorCallBackData(color, data);
1279 else if(colorCallBackN)
1280 colorCallBackN(color);
1281}
1282
1283void
1284OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data)
1285{
1286 if(texcoordCallBackData)
1287 texcoordCallBackData(texcoord, data);
1288 else if(texcoordCallBackN)
1289 texcoordCallBackN(texcoord);
1290}
1291
1292
1293
1294
Note: See TracBrowser for help on using the repository browser.