FreeWRL / FreeX3D 4.3.0
Tess.c
1/*
2
3
4???
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27#include <config.h>
28#include <system.h>
29#include <display.h>
30#include <internal.h>
31
32#include <libFreeWRL.h>
33
34#include "../vrml_parser/Structs.h"
35#include "../main/headers.h"
36#include "LinearAlgebra.h"
37
38
39#if defined(_MSC_VER)
40typedef void (__stdcall *_GLUfuncptr)();
41#endif
42
43/* WIN32 p.411 openGL programmers guide - windows needs CALLBACK, unix not */
44#ifndef CALLBACK
45#define CALLBACK
46#endif
47
48
49/*********************************************************************
50 * General tessellation functions
51 *
52 * to use the tessellation function, you have to
53 * let global_tess_polyrep point towards a structure.
54 * global_tess_polyrep->ntri is the first index number which will
55 * be filled by the routines (which is the number of triangles
56 * already represented in global_tess_polyrep)
57 * global_tess_polyrep->cindex and global_tess_polyrep->coords have
58 * to point towards enough memory.
59 * (And you have to give gluTessVertex a third argument, in which
60 * the new coords are written, it has to be a vector of
61 * GLDOUBLE s with enough space)
62 * After calling gluTessEndPolygon() these vector will be filled.
63 * global_tess_polyrep->ntri will contain the absolute
64 * number of triangles in global_tess_polyrep after tessellation.
65 */
66
67
68typedef struct pTess{
69 int global_IFS_Coords[TESS_MAX_COORDS]; //200,000
70}* ppTess;
71void *Tess_constructor(){
72 void *v = MALLOCV(sizeof(struct pTess));
73 memset(v,0,sizeof(struct pTess));
74 return v;
75}
76void Tess_init(struct tTess *t){
77 //public
78//int global_IFS_Coord_count=0;
79
80 //private
81 t->prv = Tess_constructor();
82 {
83 ppTess p = (ppTess)t->prv;
84 t->global_IFS_Coords = p->global_IFS_Coords;
85 t->text_IFS_Coords = p->global_IFS_Coords;
86 }
87}
88//ppTess p = (ppTess)gglobal()->Tess.prv;
89
90/* OpenGL-ES 2.0 does not have tessellator */
91/* and now all the callback functions, which will be called
92 by OpenGL automatically, if the Polygon is specified */
93
94void CALLBACK FW_tess_begin(GLenum e) {
95 /*printf(" FW_tess_begin e = %s\n", (e == GL_TRIANGLES ? "GL_TRIANGLES" : "UNKNOWN")); */
96 /* we only should get GL_TRIANGLES as type, because
97 we defined the edge_flag callback */
98 /* check, if the structure is there */
99 if(e!=GL_TRIANGLES)
100 freewrlDie("Something went wrong while tessellating!");
101}
102
103void CALLBACK FW_tess_end(void) {
104 /*printf("FW_tess_end: Tesselation done.\n"); */
105 /* nothing to do */
106}
107
108void CALLBACK FW_tess_edgeflag(GLenum flag) {
109 /*printf("FW_tess_edgeflag: An edge was done (flag = %d).\n", flag); */
110 /* nothing to do, this function has to be registered
111 so that only GL_TRIANGLES are used */
112}
113
114void CALLBACK FW_IFS_tess_vertex(void *p) {
115 int *dp;
116 ttglobal tg = gglobal();
117 dp =(int*)p;
118
119 if (tg->Tess.global_IFS_Coord_count == TESS_MAX_COORDS) {
120 /* printf ("FW_IFS_tess_vertex, too many coordinates in this face, change TESS_MAX_COORDS\n"); */
121 /*
122 global_IFS_Coord_count++;
123 global_IFS_Coords[global_IFS_Coord_count] =
124 global_IFS_Coords[global_IFS_Coord_count-1];
125 */
126 } else {
127 //printf ("FW_IFS_tess_vertex, global_ifs_coord count %d, pointer %d\n",tg->Tess.global_IFS_Coord_count,*dp);
128 //if(*dp < 0){
129 // printf("dp pointer = %p\n",dp);
130 //}
131 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = *dp;
132 }
133
134}
135
136void CALLBACK FW_tess_error(GLenum e) {
137 /* Prints out tesselation errors. Older versions of at least MESA would
138 give errors, so for now at least, lets just ignore them.
139 */
140 printf("FW_tess_error %d: >%s<\n",(int) e,GL_ERROR_MSG);
141}
142
143
144
145void CALLBACK FW_tess_combine_text_data (GLDOUBLE c[3], GLfloat *d[4], GLfloat w[4], void **out,void *polygondata) {
146/* Component_Text Combiner
147 printf("FW_tess_combine data\n");
148 printf("combine c:%lf %lf %lf\ndw: %f %f %f %f\n\n",
149 c[0],c[1],c[2],w[0],w[1],w[2],w[3]);
150 printf ("vertex 0 %lf %lf %lf, 1 %lf %lf %lf, 2 %lf %lf %lf, 3 %lf %lf %lf\n",
151 *d[0]->x,*d[0]->y,*d[0]->z,
152 *d[1]->x,*d[1]->y,*d[1]->z,
153 *d[2]->x,*d[2]->y,*d[2]->z,
154 *d[3]->x,*d[3]->y,*d[3]->z);
155
156 printf ("d %d %d %d %d\n",d[0],d[1],d[2],d[3]);
157 printf ("d %f %f %f %f\n",*d[0],*d[1],*d[2],*d[3]);
158 printf ("new coord %d\n",nv);
159*/
160 if(0){
161 GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*3);
162
163 nv[0] = c[0];
164 nv[1] = c[1];
165 nv[2] = c[2];
166 *out = nv;
167 }else{
168 int FW_pointctr, RAI_indx;
169 text_combiner_data *cbdata;
170 float *coords;
171 //GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*6);
172 ttglobal tg = gglobal();
173 cbdata = (text_combiner_data*) polygondata;
174
175 //OpenGL Redbook says we must malloc a new point.
176 //but in our Component_Text system, that just means adding it to our
177 //over-malloced list of points actualCoords[]
178 // and to a few other lists of indexes etc as we do in FW_NewVertexPoint() in Component_Text
179 FW_pointctr = *(cbdata->counter);
180 RAI_indx = *(cbdata->riaindex);
181 tg->Tess.global_IFS_Coords[RAI_indx] = FW_pointctr;
182 coords = (float *)cbdata->coords;
183 coords[FW_pointctr*3+0] = (float)c[0];
184 coords[FW_pointctr*3+1] = (float)c[1];
185 coords[FW_pointctr*3+2] = (float)c[2];
186 cbdata->ria[(*cbdata->riaindex)] = FW_pointctr;
187 *out = &cbdata->ria[(*cbdata->riaindex)]; //tell FW_IFS_tess_vertex the index of the new point
188 //printf("combiner, out pointer = %p nv pointer = %p\n",out,*out);
189 //THE SECRET TO COMBINDER SUCCESS? *out == (p) in FW_IFS_tess_vertex(void *p)
190 *(cbdata->counter) = FW_pointctr + 1;
191 (*cbdata->riaindex)++;
192 }
193}
194
195
196void CALLBACK FW_tess_combine_extrusion_data (GLDOUBLE c[3], GLfloat *d[4], GLfloat w[4], void **out,void *polygondata) {
197/* Component_Text Combiner
198 printf("FW_tess_combine data\n");
199 printf("combine c:%lf %lf %lf\ndw: %f %f %f %f\n\n",
200 c[0],c[1],c[2],w[0],w[1],w[2],w[3]);
201 printf ("vertex 0 %lf %lf %lf, 1 %lf %lf %lf, 2 %lf %lf %lf, 3 %lf %lf %lf\n",
202 *d[0]->x,*d[0]->y,*d[0]->z,
203 *d[1]->x,*d[1]->y,*d[1]->z,
204 *d[2]->x,*d[2]->y,*d[2]->z,
205 *d[3]->x,*d[3]->y,*d[3]->z);
206
207 printf ("d %d %d %d %d\n",d[0],d[1],d[2],d[3]);
208 printf ("d %f %f %f %f\n",*d[0],*d[1],*d[2],*d[3]);
209 printf ("new coord %d\n",nv);
210*/
211 if(0){
212 GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*3);
213
214 nv[0] = c[0];
215 nv[1] = c[1];
216 nv[2] = c[2];
217 *out = nv;
218 }else{
219 int FW_pointctr, RAI_indx;
220 polyrep_combiner_data *cbdata;
221 float *coords;
222 //GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*6);
223 ttglobal tg = gglobal();
224 cbdata = (polyrep_combiner_data*) polygondata;
225
226 //OpenGL Redbook says we must malloc a new point.
227 //but in our Component_Text system, that just means adding it to our
228 //over-malloced list of points actualCoords[]
229 // and to a few other lists of indexes etc as we do in FW_NewVertexPoint() in Component_Text
230 FW_pointctr = *(cbdata->counter);
231 RAI_indx = *(cbdata->riaindex);
232 tg->Tess.global_IFS_Coords[RAI_indx] = FW_pointctr;
233 coords = (float *)cbdata->coords;
234 coords[FW_pointctr*3+0] = (float)c[0];
235 coords[FW_pointctr*3+1] = (float)c[1];
236 coords[FW_pointctr*3+2] = (float)c[2];
237 cbdata->ria[(*cbdata->riaindex)] = FW_pointctr;
238 *out = &cbdata->ria[(*cbdata->riaindex)]; //tell FW_IFS_tess_vertex the index of the new point
239 //printf("combiner, out pointer = %p nv pointer = %p\n",out,*out);
240 //THE SECRET TO COMBINDER SUCCESS? *out == (p) in FW_IFS_tess_vertex(void *p)
241 *(cbdata->counter) = FW_pointctr + 1;
242 (*cbdata->riaindex)++;
243 }
244}
245
246void CALLBACK FW_tess_combine_polyrep_data (GLDOUBLE c[3], GLfloat *d[4], GLfloat w[4], void **out,void *polygondata) {
247/* PolyRep Combiner (not properly implemented as of Aug 5, 2016)
248 printf("FW_tess_combine data\n");
249 printf("combine c:%lf %lf %lf\ndw: %f %f %f %f\n\n",
250 c[0],c[1],c[2],w[0],w[1],w[2],w[3]);
251 printf ("vertex 0 %lf %lf %lf, 1 %lf %lf %lf, 2 %lf %lf %lf, 3 %lf %lf %lf\n",
252 *d[0]->x,*d[0]->y,*d[0]->z,
253 *d[1]->x,*d[1]->y,*d[1]->z,
254 *d[2]->x,*d[2]->y,*d[2]->z,
255 *d[3]->x,*d[3]->y,*d[3]->z);
256
257 printf ("d %d %d %d %d\n",d[0],d[1],d[2],d[3]);
258 printf ("d %f %f %f %f\n",*d[0],*d[1],*d[2],*d[3]);
259 printf ("new coord %d\n",nv);
260*/
261 if(1){
262 ttglobal tg = gglobal();
263
264 GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*3);
265
266 nv[0] = c[0];
267 nv[1] = c[1];
268 nv[2] = c[2];
269 //printf("combiner point %p %f %f %f\n",nv,nv[0],nv[1],nv[2]);
270 //tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = *nv;
271
272 *out = nv;
273 // doesn't render right: http://dug9.users.sourceforge.net/web3d/tests/CAD/test_IFS_concave_combiner.x3d
274 /*
275 geometry DEF FUNNYU IndexedFaceSet {
276 convex FALSE
277 solid FALSE
278 coordIndex [ 0 1 2 3 4 5 6 7 -1]
279 coord Coordinate {
280 # x-swap-x inner bottom u point criss crossed to force combiner
281 point [ -2 -2 0, -2 2 0, -1 2 0, 1 -1 0, -1 -1 0, 1 2 0, 2 2 0, 2 -2 0,]
282 }
283 }
284 */
285 //printf("$"); //debugging
286 }else{
287 //Aug 3, 2016 this doesn't work, didn't pick through polyrep, don't use.
288 /*
289 Current polyrep Algo: ignor opengl tips on combiner, and instead try and capture the index into
290 the original node coord, texcoord, normal via
291 tg->Tess.global_IFS_Coords[tg->Tess.global_IFS_Coord_count++] = *dp;
292 in the vertex callback, as we do for Text
293 Complication: when adding a point, the result may be more triangles, for which there needs to be more
294 normals and texcoords etc.
295
296 Hypothesis: the node orig-to-triangle approach in genpolyrep was to save memory back in 2003. We don't need it now.
297 Proposed polyrep algo A:
298 1. copy node orig data to packed
299 a) de-index
300 b) convert to double for tess
301 c) pack ie [double xyz float rgb float norm float texcoord] for tess, in over-malloced packed array
302 2. tesselate
303 a) add combiner generated pack-points to the bottom of packed array
304 b) out= weighted combined as redbook shows
305 3. copy tesselated to polyrep
306 a) convert to float
307 b) un-pack
308 c) copy unpacked to polyrep for shader
309
310 Proposed polyrep algo B:
311 1. in combiner, malloc combiner points, texcoords, normals, color-per-vertex on extension arrays
312 pass index into extension arrays to *out with a -ve sentinal value, for capture by global_IFS_Coords[] in vertex callback
313 2. in make_polyrep and make_extrusion, when using global_IFS_Coords[] array, watch for -ve index and
314 de-index from the extension arrays
315
316 Proposed polyrep algo C?
317 - when setting the vertexes, instead of giving [double xyz float rgb], give [double xyz int index]
318 - then in here, the 4 float *d points coming in will deliver index.
319 - then (somehow) use those indexes
320
321
322 */
323 //polyrep_combiner_data *cbdata;
324 }
325}
326void CALLBACK FW_tess_combine_polyrep2_data (GLDOUBLE c[3], GLfloat *d[4], GLfloat w[4], void **out,void *polygondata) {
327 //2020 variant for make_polyrep > IFS
328 ttglobal tg = gglobal();
329 int FW_pointctr, RAI_indx;
330 polyrep_combiner_data *cbdata;
331 struct SFVec3f *coords;
332 cbdata = (polyrep_combiner_data*) polygondata;
333
334 //OpenGL Redbook says we must malloc a new point.
335 //but in our Component_Text system, that just means adding it to our
336 //over-malloced list of points actualCoords[]
337 // and to a few other lists of indexes etc as we do in FW_NewVertexPoint() in Component_Text
338 FW_pointctr = *(cbdata->counter);
339 RAI_indx = *(cbdata->riaindex);
340 tg->Tess.global_IFS_Coords[RAI_indx] = FW_pointctr;
341 coords = (struct SFVec3f *)cbdata->coords;
342 printf("combiner compute intersection %lf %lf %lf\n",c[0],c[1],c[2]);
343 double2float(coords[FW_pointctr].c, c, 3);
344 cbdata->ria[(*cbdata->riaindex)] = FW_pointctr;
345 *out = &cbdata->ria[(*cbdata->riaindex)]; //tell FW_IFS_tess_vertex the index of the new point
346 //printf("combiner, out pointer = %p nv pointer = %p\n",out,*out);
347 //THE SECRET TO COMBINDER SUCCESS? *out == (p) in FW_IFS_tess_vertex(void *p)
348 *(cbdata->counter) = FW_pointctr + 1;
349 (*cbdata->riaindex)++;
350
351
352
353}
354
355/* Some tesselators will give back garbage. Lets try and remove it */
356/* Text handles errors better itself, so this is just used for Extrusions and IndexedFaceSets */
357void verify_global_IFS_Coords(int max) {
358 int count;
359 ttglobal tg = gglobal();
360
361 for (count = 0; count < tg->Tess.global_IFS_Coord_count; count++) {
362 /*printf ("verifying count %d; val is %d, max %d\n",
363 count,global_IFS_Coords[count],max); */
364 if ((tg->Tess.global_IFS_Coords[count] < 0) ||
365 (tg->Tess.global_IFS_Coords[count] >= max)) {
366
367 if (count == 0) {
368 tg->Tess.global_IFS_Coords[count] = 0;
369 } else {
370 tg->Tess.global_IFS_Coords[count] = tg->Tess.global_IFS_Coords[count-1];
371 }
372
373 }
374 }
375}
376
377void CALLBACK FW_tess_combine (GLDOUBLE c[3], void *d[4], GLfloat w[4], void **out) {
378 GLDOUBLE *nv = MALLOC(GLDOUBLE *, sizeof(GLDOUBLE)*3);
379 /*printf("FW_tess_combine c:%lf %lf %lf\ndw: %f %f %f %f\n\n",
380 c[0],c[1],c[2],w[0],w[1],w[2],w[3]); */
381 nv[0] = c[0];
382 nv[1] = c[1];
383 nv[2] = c[2];
384 *out = nv;
385}
386
387
388/* next function has to be called once, after an OpenGL context is made
389 and before tessellation is started */
390
391void CALLBACK XXtessA() { printf ("GLU_TESS_BEGIN\n"); }
392void CALLBACK XXtessB() { printf ("GLU_TESS_BEGIN_DATA\n"); }
393void CALLBACK XXtessC() { printf ("GLU_TESS_EDGE\n"); }
394void CALLBACK XXtessD() { printf ("GLU_TESS_EDGE_FLAG_DATA\n"); }
395void CALLBACK XXtessE() { printf ("GLU_TESS_VERTEX\n"); }
396void CALLBACK XXtessF() { printf ("GLU_TESS_VERTEX_DATA\n"); }
397void CALLBACK XXtessG() { printf ("GLU_TESS_END\n"); }
398void CALLBACK XXtessH() { printf ("GLU_TESS_END_DATA\n"); }
399void CALLBACK XXtessI() { printf ("GLU_TESS_COMBINE_DATA\n"); }
400void CALLBACK XXtessJ() { printf ("GLU_TESS_ERROR\n"); }
401void CALLBACK XXtessK() { printf ("GLU_TESS_ERROR_DATA\n"); }
402
403
404void new_tessellation(void) {
405 ttglobal tg = gglobal();
406 tg->Tess.global_tessobj=FW_GLU_NEW_TESS();
407 if(!tg->Tess.global_tessobj)
408 freewrlDie("Got no memory for Tessellation Object!");
409
410 /* register the CallBackfunctions */
411 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_TESS_BEGIN,(_GLUfuncptr)FW_tess_begin);
412 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_TESS_EDGE_FLAG,(_GLUfuncptr)FW_tess_edgeflag);
413 //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_VERTEX,(_GLUfuncptr)FW_IFS_tess_vertex);
414 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_TESS_VERTEX,(_GLUfuncptr)FW_IFS_tess_vertex);
415 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_TESS_ERROR,(_GLUfuncptr)FW_tess_error);
416 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_TESS_END,(_GLUfuncptr)FW_tess_end);
417 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_polyrep_data); //default combiner, Text must reset to this after doing its own FW_tess_combine_text_data
418 //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE,(_GLUfuncptr)FW_tess_combine);
419
420 /* Unused right now. */
421/*
422 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_BEGIN, (_GLUfuncptr)XXtessA);
423 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_BEGIN_DATA,(_GLUfuncptr)XXtessB);
424 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_EDGE_FLAG,(_GLUfuncptr)XXtessC);
425 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_EDGE_FLAG_DATA,(_GLUfuncptr)XXtessD);
426 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_VERTEX,(_GLUfuncptr)XXtessE);
427 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_VERTEX_DATA,(_GLUfuncptr)XXtessF);
428 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_END,(_GLUfuncptr)XXtessG);
429 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_END_DATA,(_GLUfuncptr)XXtessH);
430 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)XXtessI);
431 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_ERROR,(_GLUfuncptr)XXtessJ);
432 FW_GLU_TESS_CALLBACK(global_tessobj, GLU_TESS_ERROR_DATA,(_GLUfuncptr)XXtessK);
433*/
434/* */
435}
436//void register_Text_combiner(){
437// //called before tesselating Text in Component_Text.c
438// ttglobal tg = gglobal();
439// if(tg->Tess.text_tessobj){
440// //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)NULL);
441// FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_text_data);
442// }
443//}
444//void register_Polyrep_combiner(){
445// //called after tesselating Text in Component_Text.c, so in make_polyrep and make_extrusion in GenPolyrep.c this will be the default
446// ttglobal tg = gglobal();
447// if(tg->Tess.global_tessobj){
448// //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)NULL);
449// FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_polyrep_data);
450// }
451//}
452/* next function should be called once at the end, but where? */
453void set_tess_callbacks(int variant){
454 ttglobal tg = gglobal();
455 if(variant == 1){
456 //make_extrusion
457 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_extrusion_data); //default combiner, Text must reset to this after doing its own FW_tess_combine_text_data
458 } else if(variant == 2){
459 //make_polyrep > IFS > fancy
460 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_polyrep2_data); //default combiner, Text must reset to this after doing its own FW_tess_combine_text_data
461 }else{
462 //make_polyrep > IFS - simple
463 FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_polyrep_data); //default combiner, Text must reset to this after doing its own FW_tess_combine_text_data
464 }
465}
466void destruct_tessellation(void) {
467 ttglobal tg = gglobal();
468 FW_GLU_DELETETESS(tg->Tess.global_tessobj);
469 printf("Tessellation Object deleted!\n");
470}
471
472void destruct_text_tessellation(void) {
473 ttglobal tg = gglobal();
474 FW_GLU_DELETETESS(tg->Tess.text_tessobj);
475 printf("Tessellation Object deleted!\n");
476}
477
478void CALLBACK FW_text_tess_vertex(void *p) {
479 int *dp;
480 ttglobal tg = gglobal();
481 dp =(int*)p;
482
483 if (tg->Tess.text_IFS_Coord_count == TESS_MAX_COORDS) {
484 /* printf ("FW_IFS_tess_vertex, too many coordinates in this face, change TESS_MAX_COORDS\n"); */
485 /*
486 global_IFS_Coord_count++;
487 global_IFS_Coords[global_IFS_Coord_count] =
488 global_IFS_Coords[global_IFS_Coord_count-1];
489 */
490 } else {
491 //printf ("FW_IFS_tess_vertex, global_ifs_coord count %d, pointer %d\n",tg->Tess.global_IFS_Coord_count,*dp);
492 //if(*dp < 0){
493 // printf("dp pointer = %p\n",dp);
494 //}
495 tg->Tess.text_IFS_Coords[tg->Tess.text_IFS_Coord_count++] = *dp;
496 }
497
498}
499
500
501void new_text_tessellation(void) {
502 ttglobal tg = gglobal();
503 tg->Tess.text_tessobj=FW_GLU_NEW_TESS();
504 if(!tg->Tess.text_tessobj)
505 freewrlDie("Got no memory for Tessellation Object!");
506
507 /* register the CallBackfunctions */
508 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj,GLU_TESS_BEGIN,(_GLUfuncptr)FW_tess_begin);
509 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj,GLU_TESS_EDGE_FLAG,(_GLUfuncptr)FW_tess_edgeflag);
510 //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj,GLU_VERTEX,(_GLUfuncptr)FW_IFS_tess_vertex);
511 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj,GLU_TESS_VERTEX,(_GLUfuncptr)FW_text_tess_vertex);
512 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj,GLU_TESS_ERROR,(_GLUfuncptr)FW_tess_error);
513 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj,GLU_TESS_END,(_GLUfuncptr)FW_tess_end);
514 FW_GLU_TESS_CALLBACK(tg->Tess.text_tessobj, GLU_TESS_COMBINE_DATA,(_GLUfuncptr)FW_tess_combine_text_data); //default combiner, Text must reset to this after doing its own FW_tess_combine_text_data
515 //FW_GLU_TESS_CALLBACK(tg->Tess.global_tessobj, GLU_TESS_COMBINE,(_GLUfuncptr)FW_tess_combine);
516
517}
Definition Tess.c:68