1 /*
2  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice including the dates of first publication and
13  * either this permission notice or a reference to
14  * http://oss.sgi.com/projects/FreeB/
15  * shall be included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * Except as contained in this notice, the name of Silicon Graphics, Inc.
26  * shall not be used in advertising or otherwise to promote the sale, use or
27  * other dealings in this Software without prior written authorization from
28  * Silicon Graphics, Inc.
29  */
30 
31 /*
32  * glsurfeval.h
33  *
34  */
35 
36 #ifndef __gluglsurfeval_h_
37 #define __gluglsurfeval_h_
38 
39 #include "basicsurfeval.h"
40 #include "bezierPatchMesh.h" //in case output triangles
41 #include <GL/gl.h>
42 #include <GL/glu.h>
43 
44 class SurfaceMap;
45 class OpenGLSurfaceEvaluator;
46 class StoredVertex;
47 
48 #define TYPECOORD	1
49 #define TYPEPOINT	2
50 
51 /* Cache up to 3 vertices from tmeshes */
52 #define VERTEX_CACHE_SIZE	3
53 
54 /*for internal evaluator callback stuff*/
55 #ifndef IN_MAX_BEZIER_ORDER
56 #define IN_MAX_BEZIER_ORDER 40 /*XXX should be bigger than machine order*/
57 #endif
58 
59 #ifndef IN_MAX_DIMENSION
60 #define IN_MAX_DIMENSION 4
61 #endif
62 
63 typedef struct surfEvalMachine{
64   REAL uprime;//cached previusly evaluated uprime.
65   REAL vprime;
66   int k; /*the dimension*/
67   REAL u1;
68   REAL u2;
69   int ustride;
70   int uorder;
71   REAL v1;
72   REAL v2;
73   int vstride;
74   int vorder;
75   REAL ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION];
76   REAL ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/
77   REAL vcoeff[IN_MAX_BEZIER_ORDER];
78   REAL ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/
79   REAL vcoeffDeriv[IN_MAX_BEZIER_ORDER];
80 } surfEvalMachine;
81 
82 
83 
84 class StoredVertex {
85 public:
StoredVertex()86     		StoredVertex() { type = 0; coord[0] = 0; coord[1] = 0; point[0] = 0; point[1] = 0; }
~StoredVertex(void)87 		~StoredVertex(void) {}
saveEvalCoord(REAL x,REAL y)88     void	saveEvalCoord(REAL x, REAL y)
89 		    {coord[0] = x; coord[1] = y; type = TYPECOORD; }
saveEvalPoint(long x,long y)90     void	saveEvalPoint(long x, long y)
91 		    {point[0] = x; point[1] = y; type = TYPEPOINT; }
92     void	invoke(OpenGLSurfaceEvaluator *eval);
93 
94 private:
95     int		type;
96     REAL	coord[2];
97     long	point[2];
98 };
99 
100 class OpenGLSurfaceEvaluator : public BasicSurfaceEvaluator {
101 public:
102 			OpenGLSurfaceEvaluator();
103     			virtual ~OpenGLSurfaceEvaluator( void );
104     void		polymode( long style );
105     void		range2f( long, REAL *, REAL * );
106     void		domain2f( REAL, REAL, REAL, REAL );
addMap(SurfaceMap *)107     void		addMap( SurfaceMap * ) { }
108 
109     void		enable( long );
110     void		disable( long );
111     void		bgnmap2f( long );
112     void		map2f( long, REAL, REAL, long, long,
113 				     REAL, REAL, long, long, REAL * );
114     void		mapgrid2f( long, REAL, REAL, long, REAL, REAL );
115     void		mapmesh2f( long, long, long, long, long );
116     void		evalcoord2f( long, REAL, REAL );
117     void		evalpoint2i( long, long );
118     void		endmap2f( void );
119 
120     void	 	bgnline( void );
121     void	 	endline( void );
122     void	 	bgnclosedline( void );
123     void	 	endclosedline( void );
124     void	 	bgntmesh( void );
125     void	 	swaptmesh( void );
126     void	 	endtmesh( void );
127     void	 	bgnqstrip( void );
128     void	 	endqstrip( void );
129 
130     void                bgntfan( void );
131     void                endtfan( void );
132     void                evalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
133                                    int n_lower, REAL v_lower, REAL* lower_val);
134     void                evalVStrip(int n_left, REAL u_left, REAL* left_val,
135                                    int n_right, REAL u_right, REAL* right_val);
136 
137     void		coord2f( REAL, REAL );
138     void		point2i( long, long );
139 
140     void		newtmeshvert( REAL, REAL );
141     void		newtmeshvert( long, long );
142 
143 #ifdef _WIN32
144     void 	        putCallBack(GLenum which, void (GLAPIENTRY *fn)() );
145 #else
146     void 	        putCallBack(GLenum which, _GLUfuncptr fn );
147 #endif
148 
get_vertices_call_back()149     int                 get_vertices_call_back()
150       {
151 	return output_triangles;
152       }
put_vertices_call_back(int flag)153     void                put_vertices_call_back(int flag)
154       {
155 	output_triangles = flag;
156       }
157 
put_callback_auto_normal(int flag)158     void                 put_callback_auto_normal(int flag)
159       {
160         callback_auto_normal = flag;
161       }
162 
get_callback_auto_normal()163    int                   get_callback_auto_normal()
164      {
165         return callback_auto_normal;
166       }
167 
set_callback_userData(void * data)168    void                  set_callback_userData(void* data)
169      {
170        userData = data;
171      }
172 
173     /**************begin for LOD_eval_list***********/
174     void LOD_eval_list(int level);
175 
176 
177 
178 
179 private:
180     StoredVertex	*vertexCache[VERTEX_CACHE_SIZE];
181     int			tmeshing;
182     int			which;
183     int			vcount;
184 
185     GLint              gl_polygon_mode[2];/*to save and restore so that
186 					 *no side effect
187 					 */
188     bezierPatchMesh        *global_bpm; //for output triangles
189     int                output_triangles; //true 1 or false 0
190 
191 
192 
193     void (GLAPIENTRY *beginCallBackN) (GLenum type);
194     void (GLAPIENTRY *endCallBackN)   (void);
195     void (GLAPIENTRY *vertexCallBackN) (const GLfloat *vert);
196     void (GLAPIENTRY *normalCallBackN) (const GLfloat *normal);
197     void (GLAPIENTRY *colorCallBackN) (const GLfloat *color);
198     void (GLAPIENTRY *texcoordCallBackN) (const GLfloat *texcoord);
199 
200     void (GLAPIENTRY *beginCallBackData) (GLenum type, void* data);
201     void (GLAPIENTRY *endCallBackData)   (void* data);
202     void (GLAPIENTRY *vertexCallBackData) (const GLfloat *vert, void* data);
203     void (GLAPIENTRY *normalCallBackData) (const GLfloat *normal, void* data);
204     void (GLAPIENTRY *colorCallBackData) (const GLfloat *color, void* data);
205     void (GLAPIENTRY *texcoordCallBackData) (const GLfloat *texcoord, void* data);
206 
207     void               beginCallBack (GLenum type, void* data);
208     void               endCallBack   (void* data);
209     void               vertexCallBack (const GLfloat *vert, void* data);
210     void               normalCallBack (const GLfloat *normal, void* data);
211     void               colorCallBack (const GLfloat *color, void* data);
212     void               texcoordCallBack (const GLfloat *texcoord, void* data);
213 
214 
215     void* userData; //the opaque pointer for Data callback functions.
216 
217    /*LOD evaluation*/
218    void LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
219 		     int level);
220    void LOD_eval(int num_vert, REAL* verts, int type, int level);
221 
222   int LOD_eval_level; //set by LOD_eval_list()
223 
224    /*************begin for internal evaluators*****************/
225 
226  /*the following global variables are only defined in this file.
227  *They are used to cache the precomputed Bezier polynomial values.
228  *These calues may be used consecutively in which case we don't have
229  *recompute these values again.
230  */
231  int global_uorder; /*store the uorder in the previous evaluation*/
232  int global_vorder; /*store the vorder in the previous evaluation*/
233  REAL global_uprime;
234  REAL global_vprime;
235  REAL global_vprime_BV;
236  REAL global_uprime_BU;
237  int global_uorder_BV; /*store the uorder in the previous evaluation*/
238  int global_vorder_BV; /*store the vorder in the previous evaluation*/
239  int global_uorder_BU; /*store the uorder in the previous evaluation*/
240  int global_vorder_BU; /*store the vorder in the previous evaluation*/
241 
242  REAL global_ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/
243  REAL global_vcoeff[IN_MAX_BEZIER_ORDER];
244  REAL global_ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/
245  REAL global_vcoeffDeriv[IN_MAX_BEZIER_ORDER];
246 
247  REAL global_BV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
248  REAL global_PBV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
249  REAL global_BU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
250  REAL global_PBU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
251  REAL* global_baseData;
252 
253  int    global_ev_k; /*the dimension*/
254  REAL global_ev_u1;
255  REAL global_ev_u2;
256  int    global_ev_ustride;
257  int    global_ev_uorder;
258  REAL global_ev_v1;
259  REAL global_ev_v2;
260  int    global_ev_vstride;
261  int    global_ev_vorder;
262  REAL global_ev_ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION];
263 
264  REAL  global_grid_u0;
265  REAL  global_grid_u1;
266  int     global_grid_nu;
267  REAL  global_grid_v0;
268  REAL  global_grid_v1;
269  int     global_grid_nv;
270 
271 /*functions*/
272  void inDoDomain2WithDerivs(int k, REAL u, REAL v,
273 				REAL u1, REAL u2, int uorder,
274 				REAL v1,  REAL v2, int vorder,
275 				REAL *baseData,
276 				REAL *retPoint, REAL *retdu, REAL *retdv);
277  void inPreEvaluate(int order, REAL vprime, REAL *coeff);
278  void inPreEvaluateWithDeriv(int order, REAL vprime, REAL *coeff, REAL *coeffDeriv);
279  void inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv);
280  void inComputeNormal2(REAL *pu, REAL *pv, REAL *n);
281  void inDoEvalCoord2(REAL u, REAL v,
282 		     REAL *retPoint, REAL *retNormal);
283  void inDoEvalCoord2NOGE(REAL u, REAL v,
284 		     REAL *retPoint, REAL *retNormal);
285  void inMap2f(int k,
286 	      REAL ulower,
287 	      REAL uupper,
288 	      int ustride,
289 	      int uorder,
290 	      REAL vlower,
291 	      REAL vupper,
292 	      int vstride,
293 	      int vorder,
294 	      REAL *ctlPoints);
295 
296  void inMapGrid2f(int nu, REAL u0, REAL u1,
297 		  int nv, REAL v0, REAL v1);
298 
299  void inEvalMesh2(int lowU, int lowV, int highU, int highV);
300  void inEvalPoint2(int i, int j);
301  void inEvalCoord2f(REAL u, REAL v);
302 
303 void inEvalULine(int n_points, REAL v, REAL* u_vals,
304 	int stride, REAL ret_points[][3], REAL ret_normals[][3]);
305 
306 void inEvalVLine(int n_points, REAL u, REAL* v_vals,
307 	int stride, REAL ret_points[][3], REAL ret_normals[][3]);
308 
309 void inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
310                        int n_lower, REAL v_lower, REAL* lower_val
311                        );
312 void inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val);
313 
314 void inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData);
315 void inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData);
inPreEvaluateBV_intfac(REAL v)316 void inPreEvaluateBV_intfac(REAL v )
317   {
318    inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);
319   }
320 
inPreEvaluateBU_intfac(REAL u)321 void inPreEvaluateBU_intfac(REAL u)
322   {
323     inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
324   }
325 
326 void inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
327 			     REAL u1, REAL u2, int uorder,
328 			     REAL v1, REAL v2, int vorder,
329 			     REAL *baseData,
330 			     REAL *retPoint, REAL* retdu, REAL *retdv);
331 
332 void inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
333 			     REAL u1, REAL u2, int uorder,
334 			     REAL v1, REAL v2, int vorder,
335 			     REAL *baseData,
336 			     REAL *retPoint, REAL* retdu, REAL *retdv);
337 
338 
339 void inDoEvalCoord2NOGE_BV(REAL u, REAL v,
340 			   REAL *retPoint, REAL *retNormal);
341 
342 void inDoEvalCoord2NOGE_BU(REAL u, REAL v,
343 			   REAL *retPoint, REAL *retNormal);
344 
345 void inBPMEval(bezierPatchMesh* bpm);
346 void inBPMListEval(bezierPatchMesh* list);
347 
348 /*-------------begin for surfEvalMachine -------------*/
349 surfEvalMachine em_vertex;
350 surfEvalMachine em_normal;
351 surfEvalMachine em_color;
352 surfEvalMachine em_texcoord;
353 
354 int auto_normal_flag; //whether to output normla or not in callback
355                       //determined by GL_AUTO_NORMAL and callback_auto_normal
356 int callback_auto_normal; //GLU_CALLBACK_AUTO_NORMAL_EXT
357 int vertex_flag;
358 int normal_flag;
359 int color_flag;
360 int texcoord_flag;
361 
362 void inMap2fEM(int which, //0:vert,1:norm,2:color,3:tex
363 	       int dimension,
364 	      REAL ulower,
365 	      REAL uupper,
366 	      int ustride,
367 	      int uorder,
368 	      REAL vlower,
369 	      REAL vupper,
370 	      int vstride,
371 	      int vorder,
372 	      REAL *ctlPoints);
373 
374 void inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
375 				REAL *retPoint, REAL *retdu, REAL *retdv);
376 void inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
377 				REAL *retPoint);
378  void inDoEvalCoord2EM(REAL u, REAL v);
379 
380 void inBPMEvalEM(bezierPatchMesh* bpm);
381 void inBPMListEvalEM(bezierPatchMesh* list);
382 
383 /*-------------end for surfEvalMachine -------------*/
384 
385 
386    /*************end for internal evaluators*****************/
387 
388 };
389 
invoke(OpenGLSurfaceEvaluator * eval)390 inline void StoredVertex::invoke(OpenGLSurfaceEvaluator *eval)
391 {
392     switch(type) {
393       case TYPECOORD:
394 	eval->coord2f(coord[0], coord[1]);
395 	break;
396       case TYPEPOINT:
397 	eval->point2i(point[0], point[1]);
398 	break;
399       default:
400 	break;
401     }
402 }
403 
404 #endif /* __gluglsurfeval_h_ */
405