FreeWRL / FreeX3D 4.3.0
Component_Shape.c
1/*
2
3
4X3D Shape Component
5
6*/
7
8
9/****************************************************************************
10 This file is part of the FreeWRL/FreeX3D Distribution.
11
12 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13
14 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26****************************************************************************/
27
28
29
30#include <config.h>
31#include <system.h>
32#include <display.h>
33#include <internal.h>
34
35#include <libFreeWRL.h>
36
37#include "../vrml_parser/Structs.h"
38#include "../main/headers.h"
39#include "../opengl/Frustum.h"
40#include "../opengl/Material.h"
41#include "../opengl/OpenGL_Utils.h"
42#include "../opengl/Textures.h"
43#include "Component_ProgrammableShaders.h"
44#include "Component_Shape.h"
45#include "RenderFuncs.h"
46
47#define NOTHING 0
48
49typedef struct pComponent_Shape{
50
51 struct matpropstruct appearanceProperties;
52
53 /* pointer for a TextureTransform type of node */
54 struct X3D_Node * this_textureTransform; /* do we have some kind of textureTransform? */
55
56 /* for doing shader material properties */
57 struct X3D_TwoSidedMaterial *material_twoSided;
58 struct X3D_Material *material_oneSided;
59
60 /* Any user defined shaders here? */
61 struct X3D_Node * userShaderNode;
62 int modulation;
63
65
66static void *Component_Shape_constructor(){
67 void *v = MALLOCV(sizeof(struct pComponent_Shape));
68 memset(v,0,sizeof(struct pComponent_Shape));
69 return v;
70}
71void Component_Shape_init(struct tComponent_Shape *t){
72 //public
73 //private
74 t->prv = Component_Shape_constructor();
75 {
77 p->modulation = 1; //0 per specs 1 blend texture and mat 2 blend mat x cpv x texture
78 }
79
80}
81void fwl_set_modulation(int modulation){
82 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
83 p->modulation = modulation; //0 per specs 1 blend texture and mat 2 blend mat x cpv x texture
84}
85int fwl_get_modulation(){
86 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
87 return p->modulation; //0 per specs 1 blend texture and mat 2 blend mat x cpv x texture
88}
89//getters
90struct matpropstruct *getAppearanceProperties(){
91 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
92
93 return &p->appearanceProperties;
94}
95
96// see if the Appearance node has a valid Shader node as a child.
97static int hasUserDefinedShader(struct X3D_Node *node) {
98#define NO_SHADER 99999
99 unsigned int rv = NO_SHADER;
100
101 if (node==NULL) return 0;
102
103 //ConsoleMessage ("hasUserDeginedShader, node ptr %p",node);
104 //ConsoleMessage ("hasUserDefinedShader, nodeType %s",stringNodeType(node->_nodeType));
105 if (node->_nodeType == NODE_Appearance) {
106 struct X3D_Appearance *ap;
107 POSSIBLE_PROTO_EXPANSION(struct X3D_Appearance *, node, ap);
108 //ConsoleMessage ("appearance node shaders is %d %p",ap->shaders.n, ap->shaders.p);
109
110 if (ap && ap->shaders.n != 0) {
111 struct X3D_ComposedShader *cps;
112
113 /* ok - what kind of node is here, and are there more than two? */
114 if (ap->shaders.n > 1) {
115 ConsoleMessage ("warning, Appearance->shaders has more than 1 node, using only first one");
116 }
117
118 POSSIBLE_PROTO_EXPANSION(struct X3D_ComposedShader *, ap->shaders.p[0], cps);
119
120 //ConsoleMessage ("node type of shaders is :%s:",stringNodeType(cps->_nodeType));
121 if(cps){
122 if (cps->_nodeType == NODE_ComposedShader) {
123 // might be set in compile_Shader already
124 //ConsoleMessage ("cps->_initialized %d",cps->_initialized);
125 //ConsoleMessage ("cps->_retrievedURLData %d",cps->_retrievedURLData);
126
127 if (cps->_retrievedURLData) {
128 if (cps->_shaderUserNumber == -1) cps->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
129 rv = cps->_shaderUserNumber;
130 }
131 } else if (cps->_nodeType == NODE_PackagedShader) {
132 // might be set in compile_Shader already
133 if (X3D_PACKAGEDSHADER(cps)->_retrievedURLData) {
134 if (X3D_PACKAGEDSHADER(cps)->_shaderUserNumber == -1)
135 X3D_PACKAGEDSHADER(cps)->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
136 rv = X3D_PACKAGEDSHADER(cps)->_shaderUserNumber;
137 }
138 } else if (cps->_nodeType == NODE_ProgramShader) {
139 // might be set in compile_Shader already
140 if (X3D_PROGRAMSHADER(cps)->_retrievedURLData) {
141 if (X3D_PROGRAMSHADER(cps)->_shaderUserNumber == -1)
142 X3D_PROGRAMSHADER(cps)->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
143
144 rv = X3D_PROGRAMSHADER(cps)->_shaderUserNumber;
145 }
146 } else {
147 ConsoleMessage ("shader field of Appearance is a %s, ignoring",stringNodeType(cps->_nodeType));
148 }
149 }
150
151 }
152 }
153
154 //ConsoleMessage ("and ste is %d",ste);
155
156 // ok - did we find an integer between 0 and some MAX_SUPPORTED_USER_SHADERS value?
157 if (rv == NO_SHADER) rv = 0;
158 //else rv = USER_DEFINED_SHADER_START * (rv+1);
159
160 //ConsoleMessage ("rv is going to be %x",rv);
161
162 //ConsoleMessage ("hasUserDefinedShader, returning %p",*shaderTableEntry);
163 return rv;
164}
165int hasGeneratedCubeMapTexture(struct X3D_Appearance *appearance){
166 int ret = FALSE;
167 struct X3D_Appearance *tmpN;
168 POSSIBLE_PROTO_EXPANSION(struct X3D_Appearance *, X3D_NODE(appearance),tmpN)
169 if(tmpN && tmpN->texture)
170 if(tmpN->texture->_nodeType == NODE_GeneratedCubeMapTexture) ret = TRUE;
171 return ret;
172}
173// Save the shader node from the render_*Shader so that we can send in parameters when required
174void setUserShaderNode(struct X3D_Node *me) {
175 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
176 p->userShaderNode = me;
177}
178
179struct X3D_Node *getThis_textureTransform(){
180 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
181 return p->this_textureTransform;
182}
183void clear_bound_textures();
184void child_Appearance (struct X3D_Appearance *node) {
185 struct X3D_Node *tmpN;
186 ttglobal tg = gglobal();
187
188 /* printf ("in Appearance, this %d, nodeType %d\n",node, node->_nodeType);
189 printf (" vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
190 render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision); */
191 //clear_bound_textures();
192 /* Render the material node... */
193 RENDER_MATERIAL_SUBNODES(node->material);
194
195 if (node->fillProperties) {
196 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->fillProperties,tmpN);
197 render_node(tmpN);
198 }
199
200 /* set line widths - if we have line a lineProperties node */
201 if (node->lineProperties) {
202 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->lineProperties,tmpN);
203 render_node(tmpN);
204 }
205
206 if(node->texture) {
207 /* we have to do a glPush, then restore, later */
208 /* glPushAttrib(GL_ENABLE_BIT); */
209
210 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
211
212
213 /* is there a TextureTransform? if no texture, fugutaboutit */
214 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->textureTransform,p->this_textureTransform);
215
216 /* now, render the texture */
217 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->texture,tmpN);
218 tg->RenderFuncs.texturenode = (void*)tmpN;
219
220 render_node(tmpN);
221 }
222
223 /* shaders here/supported?? */
224 if (node->shaders.n !=0) {
225 int count;
226 int foundGoodShader = FALSE;
227
228 for (count=0; count<node->shaders.n; count++) {
229 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->shaders.p[count], tmpN);
230
231 /* have we found a valid shader yet? */
232 if(tmpN){
233 if (foundGoodShader) {
234 /* printf ("skipping shader %d of %d\n",count, node->shaders.n); */
235 /* yes, just tell other shaders that they are not selected */
236 SET_SHADER_SELECTED_FALSE(tmpN);
237 } else {
238 /* render this node; if it is valid, then we call this one the selected one */
239 SET_FOUND_GOOD_SHADER(tmpN);
240 DEBUG_SHADER("running shader (%s) %d of %d\n",
241 stringNodeType(X3D_NODE(tmpN)->_nodeType),count, node->shaders.n);
242 render_node(tmpN);
243 }
244 }
245 }
246 }
247
248 /* castle Effects here/supported?? */
249 if (node->effects.n !=0) {
250 //int count;
251 //int foundGoodShader = FALSE;
252 prep_sibAffectors(X3D_NODE(node),&node->effects);
253
254 //for (count=0; count<node->effects.n; count++) {
255 // POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->effects.p[count], tmpN);
256 //
257 // /* have we found a valid shader yet? */
258 // if(tmpN){
259 // //if (foundGoodShader) {
260 // // /* printf ("skipping shader %d of %d\n",count, node->shaders.n); */
261 // // /* yes, just tell other shaders that they are not selected */
262 // // SET_SHADER_SELECTED_FALSE(tmpN);
263 // //} else {
264 // // /* render this node; if it is valid, then we call this one the selected one */
265 // // SET_FOUND_GOOD_SHADER(tmpN);
266 // DEBUG_SHADER("running shader (%s) %d of %d\n",
267 // stringNodeType(X3D_NODE(tmpN)->_nodeType),count, node->effects.n);
268 // //render_node(tmpN);
269 // prep_sibAffectors(node,&node->effects);
270 // //}
271 // }
272 //}
273 }
274
275}
276
277
278void render_Material (struct X3D_Material *node) {
279 COMPILE_IF_REQUIRED
280 {
281 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
282
283 /* record this node for OpenGL-ES and OpenGL-3.1 operation */
284 p->material_oneSided = node;
285 }
286}
287struct X3D_Material *get_material_oneSided(){
288 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
289 return p->material_oneSided;
290}
291struct X3D_TwoSidedMaterial *get_material_twoSided(){
292 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
293 return p->material_twoSided;
294}
295
296/* bounds check the material node fields */
297void compile_Material (struct X3D_Material *node) {
298 int i;
299 float trans;
300
301 /* verify that the numbers are within range */
302 if (node->ambientIntensity < 0.0f) node->ambientIntensity=0.0f;
303 if (node->ambientIntensity > 1.0f) node->ambientIntensity=1.0f;
304 if (node->shininess < 0.0f) node->shininess=0.0f;
305 if (node->shininess > 1.0f) node->shininess=1.0f;
306 if (node->transparency < 0.0f) node->transparency=MIN_NODE_TRANSPARENCY;
307 if (node->transparency >= 1.0f) node->transparency=MAX_NODE_TRANSPARENCY;
308
309 for (i=0; i<3; i++) {
310 if (node->diffuseColor.c[i] < 0.0f) node->diffuseColor.c[i]=0.0f;
311 if (node->diffuseColor.c[i] > 1.0f) node->diffuseColor.c[i]=1.0f;
312 if (node->emissiveColor.c[i] < 0.0f) node->emissiveColor.c[i]=0.0f;
313 if (node->emissiveColor.c[i] > 1.0f) node->emissiveColor.c[i]=1.0f;
314 if (node->specularColor.c[i] < 0.0f) node->specularColor.c[i]=0.0f;
315 if (node->specularColor.c[i] > 1.0f) node->specularColor.c[i]=1.0f;
316 }
317
318 /* set the transparency here for the material */
319 /* Remember, VRML/X3D transparency 0.0 = solid; OpenGL 1.0 = solid, so we reverse it... */
320 trans = 1.0f - node->transparency;
321
322 /* we now keep verified params in a structure that maps to Shaders well...
323 struct gl_MaterialParameters {
324 vec4 emission;
325 vec4 ambient;
326 vec4 diffuse;
327 vec4 specular;
328 float shininess;
329 };
330 which is stored in the _verifiedColor[17] array here.
331 emission [0]..[3];
332 ambient [4]..[7];
333 diffuse [8]..[11];
334 specular [12]..[15];
335 shininess [16]
336*/
337 /* first, put in the transparency */
338 node->_verifiedColor.p[3] = trans;
339 node->_verifiedColor.p[7] = trans;
340 node->_verifiedColor.p[11] = trans;
341 node->_verifiedColor.p[15] = trans;
342
343 /* DiffuseColor */
344 memcpy((void *)(&node->_verifiedColor.p[8]), node->diffuseColor.c, sizeof (float) * 3);
345
346 /* Ambient - diffuseColor * ambientIntensity */
347 for(i=0; i<3; i++) { node->_verifiedColor.p[i+4] = node->_verifiedColor.p[i+8] * node->ambientIntensity; }
348
349 /* Specular */
350 memcpy((void *)(&node->_verifiedColor.p[12]), node->specularColor.c, sizeof (float) * 3);
351
352 /* Emissive */
353 memcpy((void *)(&node->_verifiedColor.p[0]), node->emissiveColor.c, sizeof (float) * 3);
354
355 /* Shininess */
356 node->_verifiedColor.p[16] = node->shininess * 128.0f;
357
358#define MAX_SHIN 128.0f
359#define MIN_SHIN 0.01f
360 if ((node->_verifiedColor.p[16] > MAX_SHIN) || (node->_verifiedColor.p[16] < MIN_SHIN)) {
361 if (node->_verifiedColor.p[16]>MAX_SHIN){node->_verifiedColor.p[16] = MAX_SHIN;}else{node->_verifiedColor.p[16]=MIN_SHIN;}
362 }
363#undef MAX_SHIN
364#undef MIN_SHIN
365
366 MARK_NODE_COMPILED
367}
368
369#define CHECK_COLOUR_FIELD(aaa) \
370 case NODE_##aaa: { \
371 struct X3D_##aaa *me = (struct X3D_##aaa *)realNode; \
372 if (me->color == NULL) return NOTHING; /* do not add any properties here */\
373 else return COLOUR_MATERIAL_SHADER; \
374 break; \
375 }
376#define CHECK_FOGCOORD_FIELD(aaa) \
377 case NODE_##aaa: { \
378 struct X3D_##aaa *me = (struct X3D_##aaa *)realNode; \
379 if (me->fogCoord == NULL) return NOTHING; /* do not add any properties here */\
380 else return HAVE_FOG_COORDS; \
381 break; \
382 }
383
384
385/* if this is a LineSet, PointSet, etc... */
386// http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/lighting.html#Lightingoff
387// 'shapes that represent points or lines are unlit
388static bool getIfLinePoints(struct X3D_Node *realNode) {
389 if (realNode == NULL) return false;
390 switch (realNode->_nodeType) {
391 case NODE_IndexedLineSet:
392 case NODE_LineSet:
393 case NODE_PointSet:
394 case NODE_Polyline2D:
395 case NODE_Polypoint2D:
396 case NODE_Circle2D:
397 case NODE_Arc2D:
398 return true;
399 }
400 return false; // do not add any capabilites here.
401}
402
403/* is the texCoord field a TextureCoordinateGenerator or not? */
404struct X3D_Node *getGeomTexCoordField(struct X3D_Node *realGeomNode){
405 struct X3D_Node *tc = NULL;
406 int *fieldOffsetsPtr = NULL;
407
408 //ConsoleMessage ("getShapeTextureCoordGen, node type %s\n",stringNodeType(realNode->_nodeType));
409 if (realGeomNode == NULL) return tc;
410
411 fieldOffsetsPtr = (int *)NODE_OFFSETS[realGeomNode->_nodeType];
412 /*go thru all field*/
413 while (*fieldOffsetsPtr != -1) {
414 if (*fieldOffsetsPtr == FIELDNAMES_texCoord) {
415 // get the pointer stored here...
416 memcpy(&tc,offsetPointer_deref(void*, realGeomNode,*(fieldOffsetsPtr+1)),sizeof(struct X3D_Node *));
417 break;
418 }
419 fieldOffsetsPtr += FIELDOFFSET_LENGTH;
420 }
421 return tc;
422
423}
424static int getShapeTextureCoordGen(struct X3D_Node *realNode) {
425 struct X3D_Node *tc = NULL;
426 tc = getGeomTexCoordField(realNode);
427 if (tc != NULL) {
428 if (tc->_nodeType == NODE_TextureCoordinateGenerator) return HAVE_TEXTURECOORDINATEGENERATOR;
429 }
430 return 0;
431}
432
433
434/* Some shapes have Color nodes - if so, then we have other shaders */
435static int getShapeColourShader (struct X3D_Node *myGeom) {
436 struct X3D_Node *realNode;
437
438 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *,myGeom,realNode);
439
440 if (realNode == NULL) return NOTHING;
441
442 /* go through each node type that can have a Color node, and if it is not NULL
443 we know we have a Color node */
444
445 switch (realNode->_nodeType) {
446 CHECK_COLOUR_FIELD(IndexedFaceSet);
447 CHECK_COLOUR_FIELD(IndexedLineSet);
448 CHECK_COLOUR_FIELD(IndexedTriangleFanSet);
449 CHECK_COLOUR_FIELD(IndexedTriangleSet);
450 CHECK_COLOUR_FIELD(IndexedTriangleStripSet);
451 CHECK_COLOUR_FIELD(LineSet);
452 CHECK_COLOUR_FIELD(PointSet);
453 CHECK_COLOUR_FIELD(TriangleFanSet);
454 CHECK_COLOUR_FIELD(TriangleStripSet);
455 CHECK_COLOUR_FIELD(TriangleSet);
456 CHECK_COLOUR_FIELD(ElevationGrid);
457 CHECK_COLOUR_FIELD(GeoElevationGrid);
458 CHECK_COLOUR_FIELD(QuadSet);
459 CHECK_COLOUR_FIELD(IndexedQuadSet);
460 }
461
462 /* if we are down here, we KNOW we do not have a color field */
463 return NOTHING; /* do not add any capabilites here */
464}
465/* Some shapes have Color nodes - if so, then we have other shaders */
466static int getShapeFogShader (struct X3D_Node *myGeom) {
467 struct X3D_Node *realNode;
468
469 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *,myGeom,realNode);
470
471 if (realNode == NULL) return NOTHING;
472
473 /* go through each node type that can have a Color node, and if it is not NULL
474 we know we have a Color node */
475
476 switch (realNode->_nodeType) {
477 CHECK_FOGCOORD_FIELD(IndexedFaceSet);
478 CHECK_FOGCOORD_FIELD(IndexedLineSet);
479 CHECK_FOGCOORD_FIELD(IndexedTriangleFanSet);
480 CHECK_FOGCOORD_FIELD(IndexedTriangleSet);
481 CHECK_FOGCOORD_FIELD(IndexedTriangleStripSet);
482 CHECK_FOGCOORD_FIELD(LineSet);
483 CHECK_FOGCOORD_FIELD(PointSet);
484 CHECK_FOGCOORD_FIELD(TriangleFanSet);
485 CHECK_FOGCOORD_FIELD(TriangleStripSet);
486 CHECK_FOGCOORD_FIELD(TriangleSet);
487 CHECK_FOGCOORD_FIELD(ElevationGrid);
488 //CHECK_FOGCOORD_FIELD(GeoElevationGrid);
489 CHECK_FOGCOORD_FIELD(QuadSet);
490 CHECK_FOGCOORD_FIELD(IndexedQuadSet);
491 }
492
493 /* if we are down here, we KNOW we do not have a color field */
494 return NOTHING; /* do not add any capabilites here */
495}
496
497static int getAppearanceShader (struct X3D_Node *myApp) {
498 struct X3D_Appearance *realAppearanceNode;
499 struct X3D_Node *realMaterialNode;
500
501
502 int retval = NOTHING;
503
504 /* if there is no appearance node... */
505 if (myApp == NULL) return retval;
506
507 POSSIBLE_PROTO_EXPANSION(struct X3D_Appearance *, myApp,realAppearanceNode);
508 if (!realAppearanceNode || realAppearanceNode->_nodeType != NODE_Appearance) return retval;
509
510 if (realAppearanceNode->material != NULL) {
511 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, realAppearanceNode->material,realMaterialNode);
512 if(realMaterialNode) {
513 if (realMaterialNode->_nodeType == NODE_Material) {
514 retval |= MATERIAL_APPEARANCE_SHADER;
515 }
516 if (realMaterialNode->_nodeType == NODE_TwoSidedMaterial) {
517 retval |= TWO_MATERIAL_APPEARANCE_SHADER;
518 }
519 }
520 }
521
522
523 if (realAppearanceNode->fillProperties != NULL) {
524 struct X3D_Node *fp;
525 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, realAppearanceNode->fillProperties,fp);
526 if(fp){
527 if (fp->_nodeType != NODE_FillProperties) {
528 ConsoleMessage("getAppearanceShader, fillProperties has a node type of %s",stringNodeType(fp->_nodeType));
529 } else {
530 // is this a FillProperties node, but is it enabled?
531 if (X3D_FILLPROPERTIES(fp)->_enabled)
532 retval |= FILL_PROPERTIES_SHADER;
533 }
534 }
535 }
536
537
538 if (realAppearanceNode->texture != NULL) {
539 //printf ("getAppearanceShader - rap node is %s\n",stringNodeType(realAppearanceNode->texture->_nodeType));
540 struct X3D_Node *tex;
541
542 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, realAppearanceNode->texture,tex);
543 if(tex){
544 if ((tex->_nodeType == NODE_ImageTexture) ||
545 (tex->_nodeType == NODE_MovieTexture) ||
546 (tex->_nodeType == NODE_PixelTexture) ){
547 retval |= ONE_TEX_APPEARANCE_SHADER;
548 } else if( (tex->_nodeType == NODE_PixelTexture3D) ||
549 (tex->_nodeType == NODE_ComposedTexture3D) ||
550 (tex->_nodeType == NODE_ImageTexture3D) ) {
551 retval |= ONE_TEX_APPEARANCE_SHADER;
552 retval |= TEX3D_SHADER; //VOLUME by default
553 if(tex->_nodeType == NODE_ComposedTexture3D)
554 retval |= TEX3D_LAYER_SHADER; //else VOLUME
555 } else if (tex->_nodeType == NODE_MultiTexture) {
556 retval |= MULTI_TEX_APPEARANCE_SHADER;
557 } else if ((tex->_nodeType == NODE_ComposedCubeMapTexture) ||
558 (tex->_nodeType == NODE_ImageCubeMapTexture) ||
559 (tex->_nodeType == NODE_GeneratedCubeMapTexture)) {
560 retval |= HAVE_CUBEMAP_TEXTURE;
561 } else {
562 ConsoleMessage ("getAppearanceShader, texture field %s not supported yet\n",
563 stringNodeType(tex->_nodeType));
564 }
565 }
566 }
567
568 #ifdef SHAPE_VERBOSE
569 printf ("getAppearanceShader, returning %x\n",retval);
570 #endif //SHAPE_VERBOSE
571
572 return retval;
573}
574
575
576/* find info on the appearance of this Shape and create a shader */
577/*
578 The possible sequence of a properly constructed appearance field is:
579
580 Shape.appearance -> Appearance
581
582 Appearance.fillProperties -> FillProperties
583 Appearance.lineProperties -> LineProperties
584 Appearance.material -> Material
585 -> TwoSidedMaterial
586 Appearance.shaders -> ComposedShader
587 Appearance.shaders -> PackagedShader
588 Appearance.shaders -> ProgramShader
589
590 Appearance.texture -> Texture
591 Appearance.texture -> MultiTexture
592 Appearance.textureTransform ->
593
594*/
595
596/* now works with our pushing matricies (norm, proj, modelview) but not for complete shader appearance replacement */
597void render_FillProperties (struct X3D_FillProperties *node) {
598 GLfloat hatchX;
599 GLfloat hatchY;
600 GLint algor;
601 GLint hatched;
602 GLint filled;
603
604 struct matpropstruct *me= getAppearanceProperties();
605
606 hatchX = 0.80f; hatchY = 0.80f;
607 algor = node->hatchStyle; filled = node->filled; hatched = node->hatched;
608 switch (node->hatchStyle) {
609 case 0: break; /* bricking - not standard X3D */
610 case 1: hatchX = 1.0f; break; /* horizontal lines */
611 case 2: hatchY = 1.0f; break; /* vertical lines */
612 case 3: hatchY=1.0f; break; /* positive sloped lines */
613 case 4: hatchY=1.0f; break; /* negative sloped lines */
614 case 5: break; /* square pattern */
615 case 6: hatchY = 1.0f; break; /* diamond pattern */
616
617 default :{
618 node->hatched = FALSE; /* woops - something wrong here disable */
619 }
620 }
621
622 me->filledBool = filled;
623 me->hatchedBool = hatched;
624 me->hatchPercent[0] = hatchX;
625 me->hatchPercent[1] = hatchY;
626 me->hatchScale[0] = node->_hatchScale.c[0];
627 me->hatchScale[1] = node->_hatchScale.c[1];
628 me->algorithm = algor;
629 me->hatchColour[0]=node->hatchColor.c[0]; me->hatchColour[1]=node->hatchColor.c[1]; me->hatchColour[2] = node->hatchColor.c[2];
630 me->hatchColour[3] = 1.0;
631}
632
633
634void render_LineProperties (struct X3D_LineProperties *node) {
635 #ifdef NEED_TO_ADD_TO_SHADER
636 much of this was working in older versions of FreeWRL,
637 before we went to 100% shader based code. Check FreeWRL
638 from (say) 2011 to see what the shader code looked like
639
640 GLushort pat;
641 #endif
642
643 if (node->applied) {
644 //ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
645
646 if (node->linewidthScaleFactor > 1.0) {
647 struct matpropstruct *me;
648 glLineWidth(node->linewidthScaleFactor);
649 me= getAppearanceProperties();
650 me->pointSize = node->linewidthScaleFactor;
651 }
652
653
654 #ifdef NEED_TO_ADD_TO_SHADER
655 if (node->linetype > 1) {
656 pat = 0xffff; /* can not support fancy line types - this is the default */
657 switch (node->linetype) {
658 case 2: pat = 0xff00; break; /* dashed */
659 case 3: pat = 0x4040; break; /* dotted */
660 case 4: pat = 0x04ff; break; /* dash dot */
661 case 5: pat = 0x44fe; break; /* dash dot dot */
662 case 6: pat = 0x0100; break; /* optional */
663 case 7: pat = 0x0100; break; /* optional */
664 case 10: pat = 0xaaaa; break; /* optional */
665 case 11: pat = 0x0170; break; /* optional */
666 case 12: pat = 0x0000; break; /* optional */
667 case 13: pat = 0x0000; break; /* optional */
668 default: {}
669 }
670 }
671 #endif
672 }
673}
674
675textureTableIndexStruct_s *getTableTableFromTextureNode(struct X3D_Node *textureNode);
676
677int getImageChannelCountFromTTI(struct X3D_Node *appearanceNode ){
678 //int channels, imgalpha, isLit, isUnlitGeometry, hasColorNode, whichShapeColorShader;
679 int channels, imgalpha, haveTexture;
680 struct X3D_Appearance *appearance;
681 channels = 0;
682 imgalpha = 0;
683 haveTexture = 0;
684 POSSIBLE_PROTO_EXPANSION(struct X3D_Appearance*,appearanceNode,appearance);
685
686 if(appearance){
687 //do I need possible proto expansione of texture, or will compile_appearance have done that?
688 if(appearance->texture){
689 //mutli-texture? should loop over multitexture->texture nodes?
690 // --to get to get max channels or hasAlpha, or need channels for each one?
691 // H0: if nay of the multitextures has an alpha, then its alpha replaces material alpha
692 // H1: multitexture alpha is only for composing textures, assumed to take material alpha
693 if(appearance->texture->_nodeType == NODE_MultiTexture ||
694 appearance->texture->_nodeType == NODE_ComposedTexture3D ){
695 int k;
696 struct Multi_Node * mtex = NULL;
697 switch(appearance->texture->_nodeType){
698 case NODE_MultiTexture: mtex = &((struct X3D_MultiTexture*)appearance->texture)->texture; break;
699 case NODE_ComposedTexture3D: mtex = &((struct X3D_ComposedTexture3D*)appearance->texture)->texture; break;
700 }
701 channels = 0;
702 imgalpha = 0;
703 if(mtex)
704 for(k=0;k<mtex->n;k++){
705 textureTableIndexStruct_s *tti = getTableTableFromTextureNode(mtex->p[k]);
706 haveTexture = 1;
707 if(tti){
708 //new Aug 6, 2016, check LoadTextures.c for your platform channel counting
709 //NoImage=0, Luminance=1, LuminanceAlpha=2, RGB=3, RGBA=4
710 //PROBLEM: if tti isn't loaded -with #channels, alpha set-, we don't want to compile child
711 channels = max(channels,tti->channels);
712 imgalpha = max(tti->hasAlpha,imgalpha);
713 //if(tti->status < TEX_NEEDSBINDING)
714 // printf("."); //should Unmark node compiled
715 }
716 }
717 }else if(appearance->texture->_nodeType == NODE_ComposedCubeMapTexture){
718 int k;
719 struct X3D_Node* p[6];
720 struct X3D_ComposedCubeMapTexture * ccmt;
721 ccmt = (struct X3D_ComposedCubeMapTexture *)appearance->texture;
722 p[0] = ccmt->top;
723 p[1] = ccmt->left;
724 p[2] = ccmt->front;
725 p[3] = ccmt->right;
726 p[4] = ccmt->back;
727 p[5] = ccmt->bottom;
728 for(k=0;k<6;k++){
729 if(p[k]){
730 textureTableIndexStruct_s *tti = getTableTableFromTextureNode(p[k]);
731 haveTexture = 1;
732 if(tti){
733 //new Aug 6, 2016, check LoadTextures.c for your platform channel counting
734 //NoImage=0, Luminance=1, LuminanceAlpha=2, RGB=3, RGBA=4
735 //PROBLEM: if tti isn't loaded -with #channels, alpha set-, we don't want to compile child
736 channels = max(channels,tti->channels);
737 imgalpha = max(tti->hasAlpha,imgalpha);
738 }
739 }
740 }
741 }else{
742 //single texture:
743 textureTableIndexStruct_s *tti = getTableTableFromTextureNode(appearance->texture);
744 haveTexture = 1;
745 if(tti){
746 //new Aug 6, 2016, check LoadTextures.c for your platform channel counting
747 //NoImage=0, Luminance=1, LuminanceAlpha=2, RGB=3, RGBA=4
748 //PROBLEM: if tti isn't loaded -with #channels, alpha set-, we don't want to compile child
749 channels = tti->channels;
750 imgalpha = tti->hasAlpha;
751 //if(tti->status < TEX_NEEDSBINDING)
752 // printf("."); //should Unmark node compiled
753 }
754 }
755 }
756 }
757 channels = haveTexture ? channels : 0; //-1;
758 return channels;
759}
760
761
762//unsigned int getShaderFlags();
763shaderflagsstruct getShaderFlags();
764struct X3D_Node *getFogParams();
765void update_effect_uniforms();
766bool setupShaderB();
767void textureTransform_start();
768void reallyDraw();
769void resend_textureprojector_matrix();
770
771void child_Shape (struct X3D_Shape *node) {
772 struct X3D_Node *tmpNG;
773 //int channels;
774 struct X3D_Virt *v;
775
777 ttglobal tg = gglobal();
778 struct fw_MaterialParameters defaultMaterials = {
779 {0.0f, 0.0f, 0.0f, 1.0f}, /* Emission */
780 {0.0f, 0.0f, 0.0f, 1.0f}, /* Ambient */
781 {0.8f, 0.8f, 0.8f, 1.0f}, /* Diffuse */
782 {0.0f, 0.0f, 0.0f, 1.0f}, /* Specular */
783 10.0f}; /* Shininess */
784
785 COMPILE_IF_REQUIRED
786
787 /* JAS - if not collision, and render_geom is not set, no need to go further */
788 /* printf ("child_Shape vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
789 render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision); */
790
791 if(!(node->geometry)) { return; }
792
793 RECORD_DISTANCE
794
795 if((renderstate()->render_collision) || (renderstate()->render_sensitive)) {
796 /* only need to forward the call to the child */
797 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *,node->geometry,tmpNG);
798 render_node(tmpNG);
799 return;
800 }
801 p = (ppComponent_Shape)tg->Component_Shape.prv;
802
803 /* initialization. This will get overwritten if there is a texture in an Appearance
804 node in this shape (see child_Appearance) */
805 tg->RenderFuncs.last_texture_type = NOTEXTURE;
806 tg->RenderFuncs.shapenode = node;
807
808 /* copy the material stuff in preparation for copying all to the shader */
809 memcpy (&p->appearanceProperties.fw_FrontMaterial, &defaultMaterials, sizeof (struct fw_MaterialParameters));
810 memcpy (&p->appearanceProperties.fw_BackMaterial, &defaultMaterials, sizeof (struct fw_MaterialParameters));
811
812 if((renderstate()->render_cube) && hasGeneratedCubeMapTexture((struct X3D_Appearance*)node->appearance))
813 return; //don't draw if this node uses a generatedcubemaptexture and its a cubemaptexture generation pass; is there more optimal place to do this?
814
815 /* now, are we rendering blended nodes or normal nodes?*/
816 if (renderstate()->render_blend == (node->_renderFlags & VF_Blend)) {
817 int isUserShader; //colorSource, isLit, alphaSource,
819 //unsigned int shader_requirements;
820 shaderflagsstruct shader_requirements;
821 memset(&shader_requirements,0,sizeof(shaderflagsstruct));
822
823 //prep_Appearance
824 RENDER_MATERIAL_SUBNODES(node->appearance); //child_Appearance
825
826
827
828 if (p->material_oneSided != NULL) {
829 memcpy (&p->appearanceProperties.fw_FrontMaterial, p->material_oneSided->_verifiedColor.p, sizeof (struct fw_MaterialParameters));
830 memcpy (&p->appearanceProperties.fw_BackMaterial, p->material_oneSided->_verifiedColor.p, sizeof (struct fw_MaterialParameters));
831 /* copy the emissive colour over for lines and points */
832 memcpy(p->appearanceProperties.emissionColour,p->material_oneSided->_verifiedColor.p, 3*sizeof(float));
833
834 } else if (p->material_twoSided != NULL) {
835 memcpy (&p->appearanceProperties.fw_FrontMaterial, p->material_twoSided->_verifiedFrontColor.p, sizeof (struct fw_MaterialParameters));
836 memcpy (&p->appearanceProperties.fw_BackMaterial, p->material_twoSided->_verifiedBackColor.p, sizeof (struct fw_MaterialParameters));
837 /* copy the emissive colour over for lines and points */
838 memcpy(p->appearanceProperties.emissionColour,p->material_twoSided->_verifiedFrontColor.p, 3*sizeof(float));
839 } else {
840 /* no materials selected.... */
841 }
842
843 /* enable the shader for this shape */
844 //ConsoleMessage("turning shader on %x",node->_shaderTableEntry);
845
846 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->geometry,tmpNG);
847
848 shader_requirements.base = node->_shaderflags_base; //_shaderTableEntry;
849 shader_requirements.effects = node->_shaderflags_effects;
850 shader_requirements.usershaders = node->_shaderflags_usershaders;
851 isUserShader = shader_requirements.usershaders ? TRUE : FALSE; // >= USER_DEFINED_SHADER_START ? TRUE : FALSE;
852 //if(!p->userShaderNode || !(shader_requirements >= USER_DEFINED_SHADER_START)){
853 if(!isUserShader){
854 //for Luminance and Luminance-Alpha images, we have to tinker a bit in the Vertex shader
855 // New concept of operations Aug 26, 2016
856 // in the specs there are some things that can replace other things (but not the reverse)
857 // Texture can repace CPV, diffuse and 111
858 // CPV can replace diffuse and 111
859 // diffuse can replace 111
860 // Texture > CPV > Diffuse > (1,1,1)
861 // so there's a kind of order / sequence to it.
862 // There can be a flag at each step saying if you want to replace the prior value (otherwise modulate)
863 // Diffuse replacing or modulating (111) is the same thing, no flag needed
864 // Therefore we need at most 2 flags for color:
865 // TEXTURE_REPLACE_PRIOR and CPV_REPLACE_PRIOR.
866 // and other flag for alpha: ALPHA_REPLACE_PRIOR (same as ! WANT_TEXALPHA)
867 // if all those are false, then its full modulation.
868 // our WANT_LUMINANCE is really == ! TEXTURE_REPLACE_PRIOR
869 // we are missing a CPV_REPLACE_PRIOR, or more precisely this is a default burned into the shader
870
871 int channels;
872 //modulation:
873 //- for Castle-style full-modulation of texture x CPV x mat.diffuse
874 // and texalpha x (1-mat.trans), set 2
875 //- for specs table 17-2 RGB Tex replaces CPV with modulation
876 // of table 17-2 entries with mat.diffuse and (1-mat.trans) set 1
877 //- for specs table 17-3 as written and ignoring modulation sentences
878 // so CPV replaces diffuse, texture replaces CPV and diffuse- set 0
879 // testing: KelpForest SharkLefty.x3d has CPV, ImageTexture RGB, and mat.diffuse
880 // 29C.wrl has mat.transparency=1 and LumAlpha image, modulate=0 shows sphere, 1,2 inivisble
881 // test all combinations of: modulation {0,1,2} x shadingStyle {gouraud,phong}: 0 looks bright texture only, 1 texture and diffuse, 2 T X C X D
882 int modulation = p->modulation; //freewrl default 1 (dug9 Aug 27, 2016 interpretation of Lighting specs)
883 channels = getImageChannelCountFromTTI(node->appearance);
884
885 if(modulation == 0)
886 shader_requirements.base |= MAT_FIRST; //strict use of table 17-3, CPV can replace mat.diffuse, so texture > cpv > diffuse > 111
887
888 if(shader_requirements.base & COLOUR_MATERIAL_SHADER){
889 //printf("has a color node\n");
890 //lets turn it off, and see if we get texture
891 //shader_requirements &= ~(COLOUR_MATERIAL_SHADER);
892 if(modulation == 0)
893 shader_requirements.base |= CPV_REPLACE_PRIOR;
894 }
895
896 if(channels && (channels == 3 || channels == 4) && modulation < 2)
897 shader_requirements.base |= TEXTURE_REPLACE_PRIOR;
898 //if the image has a real alpha, we may want to turn off alpha modulation,
899 // see comment about modulate in Compositing_Shaders.c
900 if(channels && (channels == 2 || channels == 4) && modulation == 0)
901 shader_requirements.base |= TEXALPHA_REPLACE_PRIOR;
902
903 //getShaderFlags() are from non-leaf-node shader influencers:
904 // fog, local_lights, clipplane, Effect/EffectPart (for CastlePlugs) ...
905 // - as such they may be different for the same shape node DEF/USEd in different branches of the scenegraph
906 // - so they are ORd here before selecting a shader permutation
907 shader_requirements.base |= getShaderFlags().base;
908 shader_requirements.effects |= getShaderFlags().effects;
909 //if(shader_requirements & FOG_APPEARANCE_SHADER)
910 // printf("fog in child_shape\n");
911 }
912 //printf("child_shape shader_requirements base %d effects %d user %d\n",shader_requirements.base,shader_requirements.effects,shader_requirements.usershaders);
913 scap = getMyShaders(shader_requirements);
914 enableGlobalShader(scap);
915 //enableGlobalShader (getMyShader(shader_requirements)); //node->_shaderTableEntry));
916
917 //see if we have to set up a TextureCoordinateGenerator type here
918 if (tmpNG && tmpNG->_intern) {
919 if (tmpNG->_intern->tcoordtype == NODE_TextureCoordinateGenerator) {
920 getAppearanceProperties()->texCoordGeneratorType = tmpNG->_intern->texgentype;
921 //ConsoleMessage("shape, matprop val %d, geom val %d",getAppearanceProperties()->texCoordGeneratorType, node->geometry->_intern->texgentype);
922 }
923 }
924 //userDefined = (whichOne >= USER_DEFINED_SHADER_START) ? TRUE : FALSE;
925 //if (p->userShaderNode != NULL && shader_requirements >= USER_DEFINED_SHADER_START) {
926 if(isUserShader && p->userShaderNode){
927 //we come in here right after a COMPILE pass in APPEARANCE which renders the shader, which sets p->userShaderNode
928 //if nothing changed with appearance -no compile pass- we don't come in here again
929 //ConsoleMessage ("have a shader of type %s",stringNodeType(p->userShaderNode->_nodeType));
930 switch (p->userShaderNode->_nodeType) {
931 case NODE_ComposedShader:
932 if (X3D_COMPOSEDSHADER(p->userShaderNode)->isValid) {
933 if (!X3D_COMPOSEDSHADER(p->userShaderNode)->_initialized) {
934 sendInitialFieldsToShader(p->userShaderNode);
935 }
936 }
937 break;
938 case NODE_ProgramShader:
939 if (X3D_PROGRAMSHADER(p->userShaderNode)->isValid) {
940 if (!X3D_PROGRAMSHADER(p->userShaderNode)->_initialized) {
941 sendInitialFieldsToShader(p->userShaderNode);
942 }
943 }
944
945 break;
946 case NODE_PackagedShader:
947 if (X3D_PACKAGEDSHADER(p->userShaderNode)->isValid) {
948 if (!X3D_PACKAGEDSHADER(p->userShaderNode)->_initialized) {
949 sendInitialFieldsToShader(p->userShaderNode);
950 }
951 }
952
953 break;
954 }
955 }
956 //update effect field uniforms
957 if(shader_requirements.effects){
958 update_effect_uniforms();
959 }
960
961
962 #ifdef SHAPEOCCLUSION
963 beginOcclusionQuery((struct X3D_VisibilitySensor*)node,renderstate()->render_geom); //BEGINOCCLUSIONQUERY;
964 #endif
965 //call stack to get from child_shape to sendMaterialsToShader and sendLightInfo as of Aug 13, 2016
966 //child_shape
967 //- render_node
968 //-- render_indexedfaceset (or other specific shape)
969 //--- render_polyrep
970 //---- sendArraysToGPU (or sendElementsToGPU)
971 //----- setupShader
972 //------ sendMaterialsToShader
973 // Uniforms being sent for materials and hatching
974 //--------- sendLightInfo
975 // Uniforms sent for lights
976 //----- glDrawArrays/glDrawElements
977
978 resend_textureprojector_matrix();
979 textureTransform_start();
980 setupShaderB();
981 render_node(tmpNG);
982
983 //printf("%s",stringNodeType(tmpNG->_nodeType));
984 reallyDraw();
985 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
986 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
987 textureTransform_end();
988
989 #ifdef SHAPEOCCLUSION
990 endOcclusionQuery((struct X3D_VisibilitySensor*)node,renderstate()->render_geom); //ENDOCCLUSIONQUERY;
991 #endif
992
993 //fin_Appearance
994 if(node->appearance){
995 struct X3D_Appearance *tmpA;
996 POSSIBLE_PROTO_EXPANSION(struct X3D_Appearance *,node->appearance,tmpA);
997 if(tmpA->effects.n)
998 fin_sibAffectors(X3D_NODE(tmpA),&tmpA->effects);
999 }
1000
1001 }
1002
1003 /* any shader turned on? if so, turn it off */
1004
1005 //ConsoleMessage("turning shader off");
1006 finishedWithGlobalShader();
1007 p->material_twoSided = NULL;
1008 p->material_oneSided = NULL;
1009 p->userShaderNode = NULL;
1010 tg->RenderFuncs.shapenode = NULL;
1011
1012 /* load the identity matrix for textures. This is necessary, as some nodes have TextureTransforms
1013 and some don't. So, if we have a TextureTransform, loadIdentity */
1014
1015 if (p->this_textureTransform) {
1016 p->this_textureTransform = NULL;
1017 FW_GL_MATRIX_MODE(GL_TEXTURE);
1018 FW_GL_LOAD_IDENTITY();
1019 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1020 }
1021
1022 /* LineSet, PointSets, set the width back to the original. */
1023 {
1024 float gl_linewidth = tg->Mainloop.gl_linewidth;
1025 glLineWidth(gl_linewidth);
1026 p->appearanceProperties.pointSize = gl_linewidth;
1027 }
1028
1029 /* did the lack of an Appearance or Material node turn lighting off? */
1030 LIGHTING_ON;
1031
1032 /* turn off face culling */
1033 DISABLE_CULL_FACE;
1034}
1035
1036void compile_Shape (struct X3D_Shape *node) {
1037 int whichAppearanceShader = 0;
1038 int whichShapeColorShader = 0;
1039 int whichShapeFogShader = 0;
1040 bool isUnlitGeometry = false;
1041 int hasTextureCoordinateGenerator = 0;
1042 int whichUnlitGeometry = 0;
1043 struct X3D_Node *tmpN = NULL;
1044 struct X3D_Node *tmpG = NULL;
1045 // struct X3D_Appearance *appearance = NULL;
1046 int userDefinedShader = 0;
1047// int colorSource, alphaSource, channels, isLit;
1048
1049
1050 // ConsoleMessage ("**** Compile Shape ****");
1051
1052
1053 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->geometry,tmpG);
1054 whichShapeColorShader = getShapeColourShader(tmpG);
1055 whichShapeFogShader = getShapeFogShader(tmpG);
1056
1057 isUnlitGeometry = getIfLinePoints(tmpG);
1058 hasTextureCoordinateGenerator = getShapeTextureCoordGen(tmpG);
1059
1060 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->appearance,tmpN);
1061
1062
1063 /* first - does appearance have a shader node? */
1064 userDefinedShader = hasUserDefinedShader(tmpN);
1065
1066 //Aug 26 2016 change: don't fiddle around with flags here, rather report the state of the node
1067 // - then do any fiddling in child_shape, when we have the channel count and modulation flag
1068 if(isUnlitGeometry)
1069 whichUnlitGeometry = HAVE_LINEPOINTS_COLOR;
1070 whichAppearanceShader = getAppearanceShader(tmpN);
1071
1072 /* in case we had no appearance, etc, we do the bland NO_APPEARANCE_SHADER */
1073 //node->_shaderTableEntry=
1074 node->_shaderflags_base = (whichShapeColorShader | whichShapeFogShader | whichAppearanceShader |
1075 hasTextureCoordinateGenerator | whichUnlitGeometry ); //| userDefinedShader);
1076 node->_shaderflags_usershaders = userDefinedShader;
1077 node->_shaderflags_effects = 0;
1078
1079
1080 //if (node->_shaderTableEntry == NOTHING)
1081 // node->_shaderTableEntry = NO_APPEARANCE_SHADER;
1082
1083 if (node->_shaderflags_base == NOTHING)
1084 node->_shaderflags_base = NO_APPEARANCE_SHADER;
1085
1086
1087 //printf ("compile_Shape, node->_shaderTableEntry is %x\n",node->_shaderTableEntry);
1088
1089 MARK_NODE_COMPILED
1090}
1091
1092
1093void compile_TwoSidedMaterial (struct X3D_TwoSidedMaterial *node) {
1094 int i;
1095 float trans;
1096
1097 /* verify that the numbers are within range */
1098 if (node->ambientIntensity < 0.0) node->ambientIntensity=0.0f;
1099 if (node->ambientIntensity > 1.0) node->ambientIntensity=1.0f;
1100 if (node->shininess < 0.0) node->shininess=0.0f;
1101 if (node->shininess > 1.0) node->shininess=1.0f;
1102 if (node->transparency < 0.0) node->transparency=MIN_NODE_TRANSPARENCY;
1103 if (node->transparency >= 1.0) node->transparency=MAX_NODE_TRANSPARENCY;
1104
1105 if (node->backAmbientIntensity < 0.0) node->backAmbientIntensity=0.0f;
1106 if (node->backAmbientIntensity > 1.0) node->backAmbientIntensity=1.0f;
1107 if (node->backShininess < 0.0) node->backShininess=0.0f;
1108 if (node->backShininess > 1.0) node->backShininess=1.0f;
1109 if (node->backTransparency < 0.0) node->backTransparency=0.0f;
1110 if (node->backTransparency > 1.0) node->backTransparency=1.0f;
1111
1112 for (i=0; i<3; i++) {
1113 if (node->diffuseColor.c[i] < 0.0) node->diffuseColor.c[i]=0.0f;
1114 if (node->diffuseColor.c[i] > 1.0) node->diffuseColor.c[i]=1.0f;
1115 if (node->emissiveColor.c[i] < 0.0) node->emissiveColor.c[i]=0.0f;
1116 if (node->emissiveColor.c[i] > 1.0) node->emissiveColor.c[i]=1.0f;
1117 if (node->specularColor.c[i] < 0.0) node->specularColor.c[i]=0.0f;
1118 if (node->specularColor.c[i] > 1.0) node->specularColor.c[i]=1.0f;
1119
1120 if (node->backDiffuseColor.c[i] < 0.0) node->backDiffuseColor.c[i]=0.0f;
1121 if (node->backDiffuseColor.c[i] > 1.0) node->backDiffuseColor.c[i]=1.0f;
1122 if (node->backEmissiveColor.c[i] < 0.0) node->backEmissiveColor.c[i]=0.0f;
1123 if (node->backEmissiveColor.c[i] > 1.0) node->backEmissiveColor.c[i]=1.0f;
1124 if (node->backSpecularColor.c[i] < 0.0) node->backSpecularColor.c[i]=0.0f;
1125 if (node->backSpecularColor.c[i] > 1.0) node->backSpecularColor.c[i]=1.0f;
1126 }
1127
1128 /* first, put in the transparency */
1129 trans = 1.0f - node->transparency;
1130 node->_verifiedFrontColor.p[3] = trans;
1131 node->_verifiedFrontColor.p[7] = trans;
1132 node->_verifiedFrontColor.p[11] = trans;
1133 node->_verifiedFrontColor.p[15] = trans;
1134 trans = 1.0f - node->backTransparency;
1135 node->_verifiedBackColor.p[3] = trans;
1136 node->_verifiedBackColor.p[7] = trans;
1137 node->_verifiedBackColor.p[11] = trans;
1138 node->_verifiedBackColor.p[15] = trans;
1139
1140
1141 /* DiffuseColor */
1142 memcpy((void *)(&node->_verifiedFrontColor.p[8]), node->diffuseColor.c, sizeof (float) * 3);
1143
1144 /* Ambient - diffuseFrontColor * ambientIntensity */
1145 for(i=0; i<4; i++) { node->_verifiedFrontColor.p[i+4] = node->_verifiedFrontColor.p[i+8] * node->ambientIntensity; }
1146
1147 /* Specular */
1148 memcpy((void *)(&node->_verifiedFrontColor.p[12]), node->specularColor.c, sizeof (float) * 3);
1149
1150 /* Emissive */
1151 memcpy((void *)(&node->_verifiedFrontColor.p[0]), node->emissiveColor.c, sizeof (float) * 3);
1152
1153 /* Shininess */
1154 node->_verifiedFrontColor.p[16] = node->shininess * 128.0f;
1155
1156#define MAX_SHIN 128.0f
1157#define MIN_SHIN 0.01f
1158 if ((node->_verifiedFrontColor.p[16] > MAX_SHIN) || (node->_verifiedFrontColor.p[16] < MIN_SHIN)) {
1159 if (node->_verifiedFrontColor.p[16]>MAX_SHIN){node->_verifiedFrontColor.p[16] = MAX_SHIN;}else{node->_verifiedFrontColor.p[16]=MIN_SHIN;}
1160 }
1161#undef MAX_SHIN
1162#undef MIN_SHIN
1163
1164 if (node->separateBackColor) {
1165
1166 /* DiffuseColor */
1167 memcpy((void *)(&node->_verifiedBackColor.p[8]), node->backDiffuseColor.c, sizeof (float) * 3);
1168
1169 /* Ambient - diffuseBackColor * ambientIntensity */
1170 for(i=0; i<3; i++) { node->_verifiedBackColor.p[i+4] = node->_verifiedBackColor.p[i+8] * node->ambientIntensity; }
1171
1172 /* Specular */
1173 memcpy((void *)(&node->_verifiedBackColor.p[12]), node->backSpecularColor.c, sizeof (float) * 3);
1174
1175 /* Emissive */
1176 memcpy((void *)(&node->_verifiedBackColor.p[0]), node->backEmissiveColor.c, sizeof (float) * 3);
1177
1178 /* Shininess */
1179 node->_verifiedBackColor.p[16] = node->shininess * 128.0f;
1180
1181#define MAX_SHIN 128.0f
1182#define MIN_SHIN 0.01f
1183 if ((node->_verifiedBackColor.p[16] > MAX_SHIN) || (node->_verifiedBackColor.p[16] < MIN_SHIN)) {
1184 if (node->_verifiedBackColor.p[16]>MAX_SHIN){node->_verifiedBackColor.p[16] = MAX_SHIN;}else{node->_verifiedBackColor.p[16]=MIN_SHIN;}
1185 }
1186#undef MAX_SHIN
1187#undef MIN_SHIN
1188
1189 } else {
1190 /* just copy the front materials to the back */
1191 memcpy(node->_verifiedBackColor.p, node->_verifiedFrontColor.p, sizeof (float) * 17);
1192 }
1193
1194
1195 MARK_NODE_COMPILED
1196}
1197
1198void render_TwoSidedMaterial (struct X3D_TwoSidedMaterial *node) {
1199
1200 COMPILE_IF_REQUIRED
1201 {
1202 ppComponent_Shape p = (ppComponent_Shape)gglobal()->Component_Shape.prv;
1203
1204 /* record this node for OpenGL-ES and OpenGL-3.1 operation */
1205 p->material_twoSided = node;
1206 }
1207}
1208