88 #include <libFreeWRL.h>
90 #include "../vrml_parser/Structs.h"
91 #include "../vrml_parser/CRoutes.h"
92 #include "../main/headers.h"
93 #include "../vrml_parser/CParseGeneral.h"
94 #include "../lib/scenegraph/Vector.h"
96 #include "../world_script/JScript.h"
97 #include "../world_script/CScripts.h"
98 #include "../vrml_parser/CFieldDecls.h"
99 #include "../opengl/OpenGL_Utils.h"
100 #include "../scenegraph/Component_Shape.h"
101 #include "../opengl/Textures.h"
102 #include "Component_ProgrammableShaders.h"
103 #include "../scenegraph/RenderFuncs.h"
107 #define MAX_EFFECTS 32
113 void *Component_ProgrammableShaders_constructor(){
118 void Component_ProgrammableShaders_init(
struct tComponent_ProgrammableShaders *t){
121 t->prv = Component_ProgrammableShaders_constructor();
124 p->effect_stack = newStack(
struct X3D_Node*);
128 void Component_ProgrammableShaders_clear(
struct tComponent_ProgrammableShaders *t){
132 deleteVector(
struct X3D_Node*,p->effect_stack);
141 #define SUPPORT_GLSL_ONLY \
142 if (strcmp(node->language->strptr,"GLSL")) { \
143 ConsoleMessage ("Shaders: support only GLSL shading language, got :%s:, skipping...",node->language->strptr); \
144 node->isValid = FALSE; \
155 #define LOCATE_SHADER_PARTS(myNodeType, myField) \
156 for (i=0; i<node->myField.n; i++) { \
157 struct X3D_##myNodeType *prog; \
158 prog = (struct X3D_##myNodeType *) node->myField.p[i]; \
159 vertShaderSource[i] = NULL; \
160 fragShaderSource[i] = NULL; \
163 if (prog->_nodeType == NODE_##myNodeType) { \
166 if (!((strcmp (prog->type->strptr,"VERTEX")) && (strcmp(prog->type->strptr,"FRAGMENT")))) { \
167 char *myText = NULL; \
170 cptr = prog->url.p[0]->strptr; \
171 if (cptr == NULL) { \
172 ConsoleMessage ("error reading url for :%s:",stringNodeType(NODE_##myNodeType)); \
174 } else { myText = cptr; \
177 if (!strcmp(prog->type->strptr,"VERTEX")) { \
178 vertShaderSource[i] = STRDUP(myText); \
179 haveVertShaderText = TRUE; \
181 fragShaderSource[i] = STRDUP(myText); \
182 haveFragShaderText = TRUE; \
187 ConsoleMessage ("%s, invalid Type, got \"%s\"",stringNodeType(NODE_##myNodeType), prog->type->strptr); \
188 node->isValid = FALSE; \
191 ConsoleMessage ("Shader, expected \"%s\", got \"%s\"",stringNodeType(NODE_##myNodeType), stringNodeType(prog->_nodeType)); \
192 node->isValid = FALSE; \
199 static int shader_checkType(
struct FieldDecl * myField,
200 GLuint myShader, GLint myUniform,
char *namePtr) {
215 glGetProgramiv(myShader,GL_ACTIVE_UNIFORMS,&gp);
217 for (i=0; i<gp; i++) {
218 glGetActiveUniform(myShader,i,(GLsizei)90,&len,&size,&type,ch);
220 if (strcmp(ch,namePtr)==0) {
226 glGetActiveUniform(myShader,myUniform,(GLsizei)90,&len,&size,&type,ch);
232 switch (fieldDecl_getType(myField)) {
233 case FIELDTYPE_SFFloat: retval = type == GL_FLOAT;
break;
234 case FIELDTYPE_MFFloat: retval = type == GL_FLOAT;
break;
235 case FIELDTYPE_SFRotation: retval = type == GL_FLOAT_VEC4;
break;
236 case FIELDTYPE_MFRotation: retval = type == GL_FLOAT_VEC4;
break;
237 case FIELDTYPE_SFVec3f: retval = type == GL_FLOAT_VEC3;
break;
238 case FIELDTYPE_MFVec3f: retval = type == GL_FLOAT_VEC3;
break;
239 case FIELDTYPE_MFInt32:
240 case FIELDTYPE_SFInt32: retval = type == GL_INT;
break;
241 case FIELDTYPE_MFBool:
242 case FIELDTYPE_SFBool: retval = type == GL_BOOL;
break;
243 case FIELDTYPE_SFNode:
break;
244 case FIELDTYPE_MFNode:
break;
245 case FIELDTYPE_SFColor: retval = type == GL_FLOAT_VEC3;
break;
246 case FIELDTYPE_MFColor: retval = type == GL_FLOAT_VEC3;
break;
247 case FIELDTYPE_SFColorRGBA: retval = type == GL_FLOAT_VEC4;
break;
248 case FIELDTYPE_MFColorRGBA: retval = type == GL_FLOAT_VEC4;
break;
249 case FIELDTYPE_SFTime: retval = type == GL_FLOAT;
break;
250 case FIELDTYPE_MFTime:
break;
251 case FIELDTYPE_SFString:
break;
252 case FIELDTYPE_MFString:
break;
253 case FIELDTYPE_SFVec2f: retval = type == GL_FLOAT_VEC2;
break;
254 case FIELDTYPE_MFVec2f: retval = type == GL_FLOAT_VEC2;
break;
255 case FIELDTYPE_SFImage:
break;
256 case FIELDTYPE_FreeWRLPTR:
break;
257 case FIELDTYPE_SFVec3d: retval = type == GL_FLOAT_VEC3;
break;
258 case FIELDTYPE_MFVec3d:
break;
259 case FIELDTYPE_SFDouble: retval = type == GL_FLOAT;
break;
260 case FIELDTYPE_MFDouble:
break;
261 case FIELDTYPE_SFMatrix3f:
break;
262 case FIELDTYPE_MFMatrix3f:
break;
263 case FIELDTYPE_SFMatrix3d:
break;
264 case FIELDTYPE_MFMatrix3d:
break;
265 case FIELDTYPE_SFMatrix4f:
break;
266 case FIELDTYPE_MFMatrix4f:
break;
267 case FIELDTYPE_SFMatrix4d:
break;
268 case FIELDTYPE_MFMatrix4d:
break;
269 case FIELDTYPE_SFVec2d: retval = type == GL_FLOAT_VEC2;
break;
270 case FIELDTYPE_MFVec2d:
break;
271 case FIELDTYPE_SFVec4f: retval = type == GL_FLOAT_VEC4;
break;
272 case FIELDTYPE_MFVec4f:
break;
273 case FIELDTYPE_SFVec4d: retval = type == GL_FLOAT_VEC4;
break;
274 case FIELDTYPE_MFVec4d:
break;
280 ConsoleMessage (
"Shader type check: X3D type and shader type not compatible for variable :%s:",ch);
283 printf (
"shaderCheck mode %d (%s) type %d (%s) name %d\n",fieldDecl_getAccessType(myField),
284 stringPROTOKeywordType(fieldDecl_getAccessType(myField)),
285 fieldDecl_getType(myField), stringFieldtypeType(fieldDecl_getType(myField)),
286 fieldDecl_getIndexName(myField));
288 printf (
"len %d size %d type %d ch %s\n",len,size,type,ch);
291 case GL_FLOAT: printf (
"GL_FLOAT\n");
break;
292 case GL_FLOAT_VEC2: printf (
"GL_FLOAT_VEC2\n");
break;
293 case GL_FLOAT_VEC3: printf (
"GL_FLOAT_VEC3\n");
break;
294 case GL_FLOAT_VEC4: printf (
"GL_FLOAT_VEC4\n");
break;
295 case GL_INT: printf (
"GL_INT\n");
break;
296 case GL_INT_VEC2: printf (
"GL_INT_VEC2\n");
break;
297 case GL_INT_VEC3: printf (
"GL_INT_VEC3\n");
break;
298 case GL_INT_VEC4: printf (
"GL_INT_VEC4\n");
break;
299 case GL_BOOL: printf (
"GL_BOOL\n");
break;
300 case GL_BOOL_VEC2: printf (
"GL_BOOL_VEC2\n");
break;
301 case GL_BOOL_VEC3: printf (
"GL_BOOL_VEC3\n");
break;
302 case GL_BOOL_VEC4: printf (
"GL_BOOL_VEC4\n");
break;
303 case GL_FLOAT_MAT2: printf (
"GL_FLOAT_MAT2\n");
break;
304 case GL_FLOAT_MAT3: printf (
"GL_FLOAT_MAT3\n");
break;
305 case GL_FLOAT_MAT4: printf (
"GL_FLOAT_MAT4\n");
break;
318 case GL_SAMPLER_2D: printf (
"GL_SAMPLER_2D\n");
break;
319 case GL_SAMPLER_CUBE: printf (
"GL_SAMPLER_CUBE\n");
break;
320 default :{printf (
"not decoded yet, probably a matrix type\n");}
331 GLint shaderVariable = fieldDecl_getshaderVariableID(myField->fieldDecl);
334 printf (
"sendValueToShader... ft %s\n",stringFieldtypeType(fieldDecl_getType(myField->fieldDecl)));
335 printf (
"shaderVariableID is %d\n",shaderVariable);
339 if (shaderVariable == INT_ID_UNDEFINED)
return;
342 switch (fieldDecl_getType(myField->fieldDecl)) {
344 #define SF_FLOATS_TO_SHADER(ttt,ty1,ty2) \
345 case FIELDTYPE_SF##ty1: \
346 GLUNIFORM##ttt##FV(shaderVariable, 1, myField->value.sf##ty2.c); \
349 #define SF_DOUBLES_TO_SHADER(ttt,ty1,ty2) \
350 case FIELDTYPE_SF##ty1: {float val[4]; int i; \
351 for (i=0; i<ttt; i++) { val[i] = (float) (myField->value.sf##ty2.c[i]); } \
352 GLUNIFORM##ttt##FV(shaderVariable, 1, val); \
355 #define SF_FLOAT_TO_SHADER(ty1,ty2) \
356 case FIELDTYPE_SF##ty1: \
357 GLUNIFORM1F(shaderVariable, myField->value.sf##ty2); \
360 #define SF_DOUBLE_TO_SHADER(ty1,ty2) \
361 case FIELDTYPE_SF##ty1: {float val = myField->value.sf##ty2; \
362 GLUNIFORM1F(shaderVariable, val); \
365 #define MF_FLOATS_TO_SHADER(ttt,ty1,ty2) \
366 case FIELDTYPE_MF##ty1: \
367 GLUNIFORM##ttt##FV(shaderVariable, myField->value.mf##ty2.n, (float *)myField->value.mf##ty2.p); \
371 #define SF_INTS_TO_SHADER(ty1,ty2) \
372 case FIELDTYPE_SF##ty1: \
373 GLUNIFORM1I(shaderVariable, myField->value.sf##ty2); \
376 #define MF_INTS_TO_SHADER(ty1,ty2) \
377 case FIELDTYPE_MF##ty1: \
378 GLUNIFORM1IV(shaderVariable, (GLsizei) myField->value.mf##ty2.n, (const GLint *)myField->value.mf##ty2.p); \
382 SF_FLOAT_TO_SHADER(Float,
float)
383 SF_DOUBLE_TO_SHADER(Double,
float)
384 SF_DOUBLE_TO_SHADER(Time,
float)
386 SF_FLOATS_TO_SHADER(2,Vec2f,vec2f)
387 SF_FLOATS_TO_SHADER(3,Vec3f,vec3f)
388 SF_FLOATS_TO_SHADER(3,Color,color)
389 SF_FLOATS_TO_SHADER(4,ColorRGBA,colorrgba)
390 SF_FLOATS_TO_SHADER(4,Rotation,rotation)
391 SF_FLOATS_TO_SHADER(4,Vec4f,vec4f)
392 SF_DOUBLES_TO_SHADER(2,Vec2d, vec2d)
393 SF_DOUBLES_TO_SHADER(3,Vec3d, vec3d)
394 SF_DOUBLES_TO_SHADER(4,Vec4d, vec4d)
396 MF_FLOATS_TO_SHADER(1,Float,
float)
398 MF_FLOATS_TO_SHADER(2,Vec2f,vec2f)
399 MF_FLOATS_TO_SHADER(3,Color,color)
400 MF_FLOATS_TO_SHADER(3,Vec3f,vec3f)
401 MF_FLOATS_TO_SHADER(4,ColorRGBA,colorrgba)
402 MF_FLOATS_TO_SHADER(4,Rotation,rotation)
404 SF_INTS_TO_SHADER(Bool,
bool)
405 SF_INTS_TO_SHADER(Int32,int32)
406 MF_INTS_TO_SHADER(Bool,
bool)
407 MF_INTS_TO_SHADER(Int32,int32)
415 case FIELDTYPE_SFNode:
416 case FIELDTYPE_SFImage:
417 case FIELDTYPE_FreeWRLPTR:
418 case FIELDTYPE_SFString:
419 case FIELDTYPE_SFMatrix3d:
420 case FIELDTYPE_SFMatrix4d:
423 case FIELDTYPE_MFNode:
424 case FIELDTYPE_MFTime:
425 case FIELDTYPE_MFString:
426 case FIELDTYPE_MFDouble:
427 case FIELDTYPE_MFVec3d:
428 case FIELDTYPE_MFMatrix3f:
429 case FIELDTYPE_MFMatrix3d:
430 case FIELDTYPE_MFMatrix4f:
431 case FIELDTYPE_MFMatrix4d:
432 case FIELDTYPE_MFVec2d:
433 case FIELDTYPE_MFVec4d:
434 default : printf ("can not send a shader variable of %s yet\n",stringFieldtypeType(fieldDecl_getType(myField->fieldDecl)));
479 void getField_ToShader(struct
X3D_Node *node,
int toOffset, union
anyVrml *toAny,
int type) {
488 GLuint currentShader = 0;
490 struct CRStruct *CRoutes = getCRoutes();
501 parents = node->_parentVector;
503 while(i < vectorSize(parents)){
507 if( ap->_nodeType == NODE_Proto) ap = vector_get(
struct X3D_Appearance *,ap->_parentVector, 0);
508 if (ap->_nodeType == NODE_Appearance) {
509 for (j=0; j<vectorSize(ap->_parentVector); j++) {
512 if (sh->_nodeType == NODE_Shape) {
514 shaderflags.base = sh->_shaderflags_base;
515 shaderflags.effects = sh->_shaderflags_effects;
516 shaderflags.usershaders = sh->_shaderflags_usershaders;
521 if(ap->_nodeType == NODE_ProgramShader){
523 parents = ap->_parentVector;
529 if(!shaderflags.base && !shaderflags.usershaders){
538 enableGlobalShader(getMyShaders(shaderflags));
553 switch(node->_nodeType){
554 case NODE_ComposedShader:
555 myObj[0] = (
struct Shader_Script *)(X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields);
560 case NODE_PackagedShader:
561 myObj[0] = (
struct Shader_Script *)(X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields);
563 case NODE_ProgramShader:{
566 for (i=0; i<X3D_PROGRAMSHADER(node)->programs.n; i++) {
567 struct X3D_ShaderProgram *ps = X3D_SHADERPROGRAM(X3D_PROGRAMSHADER(node)->programs.p[i]);
570 myObj[i] = (
struct Shader_Script *)ps->_shaderUserDefinedFields;
575 case NODE_ShaderProgram:
577 myObj[0] = (
struct Shader_Script *)(X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields);
580 ConsoleMessage (
"getField_ToShader, unhandled type??");
596 if (myObj[0] == NULL)
return;
599 for (i=0; i<numObjs; i++) {
600 if (!myObj[i]->loaded) {
607 for (j=0; j<numObjs; j++) {
609 toField = vector_get(
struct ScriptFieldDecl*, myObj[j]->fields, toOffset);
610 fromFieldID = fieldDecl_getshaderVariableID(toField->fieldDecl);
612 for(i=0; i!=vectorSize(myObj[j]->fields); ++i) {
613 GLint shaderVariable;
619 myf = curField->fieldDecl;
620 shaderVariable = fieldDecl_getshaderVariableID(myf);
638 if (fromFieldID == fieldDecl_getShaderScriptIndex(myf)) {
649 sourceData = &toAny->sffloat;
652 #define ROUTE_SF_FLOAT_TO_SHADER(ty1) \
653 case FIELDTYPE_SF##ty1: \
654 GLUNIFORM1F(shaderVariable, *((float*)sourceData)); \
657 #define ROUTE_SF_DOUBLE_TO_SHADER(ty1) \
658 case FIELDTYPE_SF##ty1: {float val = (float) *((double *)sourceData); \
659 GLUNIFORM1F(shaderVariable, val); \
662 #define ROUTE_SF_INTS_TO_SHADER(ty1) \
663 case FIELDTYPE_SF##ty1: \
664 GLUNIFORM1I(shaderVariable, *((int*)sourceData)); \
667 #define ROUTE_SF_FLOATS_TO_SHADER(ttt,ty1) \
668 case FIELDTYPE_SF##ty1: \
669 GLUNIFORM##ttt##FV(shaderVariable, 1, (float*)sourceData); \
672 #define ROUTE_SF_DOUBLES_TO_SHADER(ttt,ty1) \
673 case FIELDTYPE_SF##ty1: {float val[4]; int i; double *fp = (double*)sourceData; \
674 for (i=0; i<ttt; i++) { val[i] = (float) (*fp); fp++; } \
675 GLUNIFORM##ttt##FV(shaderVariable, 1, val); \
679 #define ROUTE_MF_FLOATS_TO_SHADER(ttt,ty1) \
680 case FIELDTYPE_MF##ty1: { struct Multi_##ty1 *sd = (struct Multi_##ty1*) sourceData; \
681 printf ("MF_FLOATS_TO_SHADER, sv %d, sd->n %d\n",shaderVariable,sd->n); \
682 GLUNIFORM##ttt##FV(shaderVariable, sd->n, (const GLfloat *)sd->p); \
685 #define ROUTE_MF_INTS_TO_SHADER(ttt,ty1) \
686 case FIELDTYPE_MF##ty1: { struct Multi_##ty1 *sd = (struct Multi_##ty1*) sourceData; \
687 GLUNIFORM##ttt##IV(shaderVariable, sd->n, (const GLint *)sd->p); \
693 switch (JSparamnames[fromFieldID].type) {
694 ROUTE_SF_FLOAT_TO_SHADER(Float)
695 ROUTE_SF_DOUBLE_TO_SHADER(Double)
696 ROUTE_SF_DOUBLE_TO_SHADER(Time)
697 ROUTE_SF_INTS_TO_SHADER(Bool)
698 ROUTE_SF_INTS_TO_SHADER(Int32)
700 ROUTE_SF_FLOATS_TO_SHADER(2,Vec2f)
701 ROUTE_SF_FLOATS_TO_SHADER(3,Vec3f)
702 ROUTE_SF_FLOATS_TO_SHADER(3,Color)
703 ROUTE_SF_FLOATS_TO_SHADER(4,ColorRGBA)
704 ROUTE_SF_FLOATS_TO_SHADER(4,Rotation)
705 ROUTE_SF_FLOATS_TO_SHADER(4,Vec4f)
706 ROUTE_SF_DOUBLES_TO_SHADER(2,Vec2d)
707 ROUTE_SF_DOUBLES_TO_SHADER(3,Vec3d)
708 ROUTE_SF_DOUBLES_TO_SHADER(4,Vec4d)
710 ROUTE_MF_FLOATS_TO_SHADER(1,Float)
711 ROUTE_MF_FLOATS_TO_SHADER(2,Vec2f)
712 ROUTE_MF_FLOATS_TO_SHADER(3,Color)
713 ROUTE_MF_FLOATS_TO_SHADER(3,Vec3f)
714 ROUTE_MF_FLOATS_TO_SHADER(4,ColorRGBA)
715 ROUTE_MF_FLOATS_TO_SHADER(4,Rotation)
717 ROUTE_MF_INTS_TO_SHADER(1,Bool)
718 ROUTE_MF_INTS_TO_SHADER(1,Int32)
722 case FIELDTYPE_SFNode:
723 case FIELDTYPE_MFNode:
724 case FIELDTYPE_MFTime:
725 case FIELDTYPE_SFString:
726 case FIELDTYPE_MFString:
727 case FIELDTYPE_SFImage:
728 case FIELDTYPE_FreeWRLPTR:
729 case FIELDTYPE_MFVec3d:
730 case FIELDTYPE_MFDouble:
731 case FIELDTYPE_SFMatrix3f:
732 case FIELDTYPE_MFMatrix3f:
733 case FIELDTYPE_SFMatrix3d:
734 case FIELDTYPE_MFMatrix3d:
735 case FIELDTYPE_SFMatrix4f:
736 case FIELDTYPE_MFMatrix4f:
737 case FIELDTYPE_SFMatrix4d:
738 case FIELDTYPE_MFMatrix4d:
739 case FIELDTYPE_MFVec2d:
740 case FIELDTYPE_MFVec4d:
741 ConsoleMessage ("shader field type %s not routable yet",stringFieldtypeType(JSparamnames[fromFieldID].type));
744 ConsoleMessage (
"shader field type %s not routable yet",stringFieldtypeType(JSparamnames[fromFieldID].type));
750 finishedWithGlobalShader();
756 static void send_fieldToShader (GLuint myShader,
struct X3D_Node *node) {
762 if (node->_nodeType==NODE_ShaderProgram) me = (
struct Shader_Script *) X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields;
763 else if (node->_nodeType == NODE_ComposedShader) me = (
struct Shader_Script *) X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields;
764 else if (node->_nodeType == NODE_Effect) me = (
struct Shader_Script *) X3D_EFFECT(node)->_shaderUserDefinedFields;
766 printf (
"send_fieldToShader, expected a ShaderProgram or ComposedShader, got %s\n",
767 stringNodeType(node->_nodeType));
773 printf (
"Shader_Script has node of %p ",me->ShaderScriptNode);
774 printf (
"of type %s ",stringNodeType(me->ShaderScriptNode->_nodeType));
775 printf (
"and has %d as a vector size ",vectorSize(me->fields));
776 if (me->loaded) printf (
"locked and loaded ");
else printf (
"needs loading, I guess ");
782 for (i=0; i<MAX_MULTITEXTURE; i++) {
783 char myShaderTextureName[200];
786 sprintf (myShaderTextureName,
"X3D_Texture%d",(
int) i);
787 myVar = GET_UNIFORM(myShader,myShaderTextureName);
788 if (myVar != INT_ID_UNDEFINED) {
790 GLUNIFORM1I(myVar,(
int) i);
795 if (me == NULL)
return;
802 for(i=0; i!=vectorSize(me->fields); ++i) {
811 myf = curField->fieldDecl;
812 namePtr = fieldDecl_getShaderScriptName(myf);
817 printf (
"looking for field name %s...\n",namePtr);
818 printf(
"fieldDecl mode %d (%s) type %d (%s) name %d\n",myf->PKWmode,
819 stringPROTOKeywordType(myf->PKWmode), myf->fieldType, stringFieldtypeType(myf->fieldType),myf->lexerNameIndex);
826 myVar = GET_UNIFORM(myShader,namePtr);
828 if (myVar == INT_ID_UNDEFINED) {
829 if (GET_ATTRIB(myShader,fieldDecl_getShaderScriptName(myf)) != INT_ID_UNDEFINED)
830 ConsoleMessage (
"Shader variable :%s: is declared as an attribute; we can not do much with this",fieldDecl_getShaderScriptName(myf));
832 ConsoleMessage (
"Shader variable :%s: is either not declared or not used in the shader program",fieldDecl_getShaderScriptName(myf));
836 shader_checkType(myf,myShader,myVar,namePtr);
840 fieldDecl_setshaderVariableID(myf,myVar);
842 if ((fieldDecl_getAccessType(myf)==PKW_initializeOnly) || (fieldDecl_getAccessType(myf)==PKW_inputOutput)) {
843 sendValueToShader(curField);
880 void sendInitialFieldsToShader(
struct X3D_Node * node) {
885 myShader = getAppearanceProperties()->currentShaderProperties->myShaderProgram;
888 switch (node->_nodeType) {
889 case NODE_ProgramShader: {
892 for (i=0; i<X3D_PROGRAMSHADER(node)->programs.n; i++) {
894 printf (
"ProgramShader, activate %d isSelected %d isValid %d TRUE %d FALSE %d\n",
895 X3D_PROGRAMSHADER(node)->activate,X3D_PROGRAMSHADER(node)->isSelected,
896 X3D_PROGRAMSHADER(node)->isValid, TRUE, FALSE);
900 struct X3D_ShaderProgram *part = X3D_SHADERPROGRAM(X3D_PROGRAMSHADER(node)->programs.p[i]);
903 printf (
"sendInitial, have part %p\n",part);
906 send_fieldToShader(myShader, X3D_NODE(part));
908 X3D_PROGRAMSHADER(node)->_initialized = TRUE;
913 case NODE_ComposedShader: {
915 send_fieldToShader(myShader, X3D_NODE(node));
916 X3D_COMPOSEDSHADER(node)->_initialized = TRUE;
931 static void tellShapeNodeToRecompile (
struct X3D_Node *node) {
935 if (node->_nodeType == NODE_Shape) {
938 for (i=0; i<vectorSize(node->_parentVector); i++) {
939 struct X3D_Node * parent = vector_get(
struct X3D_Node*, node->_parentVector, i);
941 if (parent == NULL)
return;
942 tellShapeNodeToRecompile(parent);
949 LOADER_INITIAL_STATE=0,
950 LOADER_REQUEST_RESOURCE,
951 LOADER_FETCHING_RESOURCE,
958 static void *thread_compile_ComposedShader(
void *args) {
963 GLchar **vertShaderSource;
964 GLchar **fragShaderSource;
969 int haveVertShaderText;
970 int haveFragShaderText;
972 inArgs = (
struct myArgs *) args;
974 node = X3D_COMPOSEDSHADER(inArgs->node);
978 fwl_setCurrentHandle(tg,__FILE__,__LINE__);
981 haveVertShaderText = FALSE;
982 haveFragShaderText = FALSE;
985 ConsoleMessage(
"called compile_ComposedShader(%p)\n",(
void *)node);
989 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
991 if (node->_shaderUserNumber < 0) {
992 ConsoleMessage (
"out of user defined shader slots - can not run");
997 vertShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->parts.n);
998 fragShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->parts.n);
1001 node->isValid = TRUE;
1010 for (i=0; i<node->parts.n; i++) {
1013 vertShaderSource[i] = NULL;
1014 fragShaderSource[i] = NULL;
1017 if (prog->_nodeType == NODE_ShaderPart) {
1020 if (!((strcmp (prog->type->strptr,
"VERTEX")) && (strcmp(prog->type->strptr,
"FRAGMENT")))) {
1021 char *myText = NULL;
1024 cptr = prog->url.p[0]->strptr;
1026 ConsoleMessage (
"error reading url for :%s:",stringNodeType(NODE_ShaderPart));
1031 if (!strcmp(prog->type->strptr,
"VERTEX")) {
1032 vertShaderSource[i] = STRDUP(myText);
1033 haveVertShaderText = TRUE;
1035 fragShaderSource[i] = STRDUP(myText);
1036 haveFragShaderText = TRUE;
1042 ConsoleMessage (
"%s, invalid Type, got \"%s\"",stringNodeType(NODE_ShaderPart), prog->type->strptr);
1043 node->isValid = FALSE;
1046 ConsoleMessage (
"Shader, expected \"%s\", got \"%s\"",stringNodeType(NODE_ShaderPart), stringNodeType(prog->_nodeType));
1047 node->isValid = FALSE;
1067 if (node->isValid) {
1069 sendShaderTextToEngine(node->_shaderUserNumber,node->parts.n,vertShaderSource,fragShaderSource);
1071 ConsoleMessage (
"shader node is NOT valid");
1072 FREE_IF_NZ(vertShaderSource);
1073 FREE_IF_NZ(fragShaderSource);
1077 ZERO_THREAD(node->_shaderLoadThread);
1078 node->_retrievedURLData = (haveFragShaderText && haveVertShaderText);
1080 tellShapeNodeToRecompile(X3D_NODE(node));
1088 static void *thread_compile_ProgramShader (
void *args){
1093 GLchar **vertShaderSource;
1094 GLchar **fragShaderSource;
1095 int i, node_isValid;
1099 int haveVertShaderText;
1100 int haveFragShaderText;
1102 inArgs = (
struct myArgs *) args;
1103 node = X3D_PROGRAMSHADER(inArgs->node);
1107 fwl_setCurrentHandle(tg,__FILE__,__LINE__);
1109 haveVertShaderText = FALSE;
1110 haveFragShaderText = FALSE;
1113 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
1115 if (node->_shaderUserNumber < 0) {
1116 ConsoleMessage (
"out of user defined shader slots - can not run");
1122 vertShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->programs.n);
1123 fragShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->programs.n);
1126 node->isValid = FALSE;
1127 node_isValid = TRUE;
1132 if (strcmp(node->language->strptr,
"GLSL")) {
1133 ConsoleMessage (
"Shaders: support only GLSL shading language, got :%s:, skipping...",node->language->strptr);
1134 node_isValid = FALSE;
1140 LOCATE_SHADER_PARTS(ShaderProgram,programs)
1144 for (i=0; i<node->programs.n; i++) {
1147 vertShaderSource[i] = NULL;
1148 fragShaderSource[i] = NULL;
1151 if (prog->_nodeType == NODE_ShaderProgram) {
1153 if (!((strcmp (prog->type->strptr,
"VERTEX")) && (strcmp(prog->type->strptr,
"FRAGMENT")))) {
1154 char *myText = NULL;
1156 cptr = prog->url.p[0]->strptr;
1158 ConsoleMessage (
"error reading url for :%s:",stringNodeType(NODE_ShaderProgram));
1163 if (!strcmp(prog->type->strptr,
"VERTEX")) {
1164 vertShaderSource[i] = STRDUP(myText);
1165 haveVertShaderText = TRUE;
1167 fragShaderSource[i] = STRDUP(myText);
1168 haveFragShaderText = TRUE;
1174 ConsoleMessage (
"%s, invalid Type, got \"%s\"",stringNodeType(NODE_ShaderProgram), prog->type->strptr);
1175 node_isValid = FALSE;
1178 ConsoleMessage (
"Shader, expected \"%s\", got \"%s\"",stringNodeType(NODE_ShaderProgram), stringNodeType(prog->_nodeType));
1179 node_isValid = FALSE;
1188 sendShaderTextToEngine(node->_shaderUserNumber,node->programs.n,vertShaderSource,fragShaderSource);
1190 FREE_IF_NZ(vertShaderSource);
1191 FREE_IF_NZ(fragShaderSource);
1195 ZERO_THREAD(node->_shaderLoadThread);
1196 node->_retrievedURLData = (haveFragShaderText && haveVertShaderText);
1198 tellShapeNodeToRecompile(X3D_NODE(node));
1199 node->isValid = node_isValid;
1205 node->url.p[0]->strptr = STRDUP(buffer);
1219 switch (res->type) {
1225 buffer = res->URLrequest;
1237 of = res->openned_files;
1243 buffer = (
char*)of->fileData;
1249 return shader_initCode(ss, buffer);
1258 switch (node->__loadstatus) {
1259 case LOADER_INITIAL_STATE:
1261 if (node->url.n == 0) {
1262 node->__loadstatus = LOADER_STABLE;
1265 char * sc = shader_initCodeFromMFUri(&node->url);
1267 node->url.p[0]->strptr = sc;
1269 node->__loadstatus = LOADER_LOADED;
1271 res = resource_create_multi(&(node->url));
1272 res->media_type = resm_fshader;
1273 node->__loadstatus = LOADER_REQUEST_RESOURCE;
1274 node->__loadResource = res;
1279 case LOADER_REQUEST_RESOURCE:
1280 res = node->__loadResource;
1281 resource_identify(node->_parentResource, res);
1284 res->actions = resa_download | resa_load;
1285 resitem_enqueue(ml_new(res));
1287 node->__loadstatus = LOADER_FETCHING_RESOURCE;
1290 case LOADER_FETCHING_RESOURCE:
1291 res = node->__loadResource;
1296 if (res->status == ress_loaded) {
1298 res->whereToPlaceData = X3D_NODE(node);
1299 res->offsetFromWhereToPlaceData = 0;
1300 res->actions = resa_process;
1301 node->__loadstatus = LOADER_PROCESSING;
1302 res->complete = FALSE;
1305 resitem_enqueue(ml_new(res));
1306 }
else if ((res->status == ress_failed) || (res->status == ress_invalid)) {
1308 printf (
"resource failed to load\n");
1309 node->__loadstatus = LOADER_STABLE;
1314 case LOADER_PROCESSING:
1315 res = node->__loadResource;
1320 if (res->status == ress_parsed) {
1321 node->__loadstatus = LOADER_LOADED;
1323 node->__loadstatus = LOADER_STABLE;
1331 case LOADER_COMPILED:
1337 return node->__loadstatus == LOADER_COMPILED;
1340 int shaderprograms_loaded_but_not_compiled(
struct Multi_Node *programs){
1341 int i, retval = TRUE;
1342 for(i=0;i<programs->n;i++){
1344 retval = retval && !shaderprogram_compiled(sp) && shaderprogram_loaded(sp);
1349 void set_shaderprograms_compiled(
struct Multi_Node *programs){
1351 for(i=0;i<programs->n;i++){
1353 sp->__loadstatus = LOADER_COMPILED;
1359 if(shaderprograms_loaded_but_not_compiled(&node->parts)){
1361 args = MALLOC(
struct myArgs *,
sizeof (
struct myArgs));
1362 args->node = X3D_NODE(node);
1368 if (TEST_NULL_THREAD(node->_shaderLoadThread)) {
1369 pthread_create (&(node->_shaderLoadThread), NULL,
1370 &thread_compile_ComposedShader, (
void *)args);
1374 thread_compile_ComposedShader(args);
1376 set_shaderprograms_compiled(&node->parts);
1383 if(shaderprograms_loaded_but_not_compiled(&node->programs)){
1384 set_shaderprograms_compiled(&node->programs);
1385 args = MALLOC(
struct myArgs *,
sizeof (
struct myArgs));
1386 args->node = X3D_NODE(node);
1390 if (TEST_NULL_THREAD(node->_shaderLoadThread)) {
1391 pthread_create (&(node->_shaderLoadThread), NULL,
1392 &thread_compile_ProgramShader, (
void *)args);
1396 thread_compile_ProgramShader(args);
1403 ConsoleMessage (
"found PackagedShader, do not support this structure, as we support only GLSL");
1404 node->isValid = FALSE;
1412 if (node->isValid) setUserShaderNode(X3D_NODE(node));
1421 setUserShaderNode(X3D_NODE(node));
1430 int getNextFreeEffectSlot() {
1436 if (p->effectCount == MAX_EFFECTS)
return -1;
1438 rv = p->effectCount;
1443 void compile_Effect (
struct X3D_Effect *node) {
1450 for(i=0;i<node->parts.n;i++){
1451 is_valid = is_valid && shaderprogram_loaded(X3D_SHADERPROGRAM(node->parts.p[i]));
1453 node->isValid = is_valid;
1454 if(node->isValid) MARK_NODE_COMPILED
1456 static int effect_stack_count = 0;
1459 void popShaderFlags();
1461 void sib_prep_Effect (
struct X3D_Node *parent,
struct X3D_Node *sibAffector) {
1473 effect_stack_count++;
1475 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeEffectSlot();
1477 shaderflags = getShaderFlags();
1478 shaderflags.effects |= 1L << node->_shaderUserNumber;
1479 pushShaderFlags(shaderflags);
1480 stack_push(
struct X3D_Node*,p->effect_stack,sibAffector);
1484 void sib_fin_Effect (
struct X3D_Node *parent,
struct X3D_Node *sibAffector) {
1491 effect_stack_count--;
1493 stack_pop(
struct X3D_Node*,p->effect_stack);
1498 Stack *getEffectStack(){
1501 return p->effect_stack;
1503 void update_effect_uniforms(){
1504 Stack * effect_stack;
1505 effect_stack = getEffectStack();
1506 if(effect_stack && effect_stack->n){
1508 for(i=0;i<effect_stack->n;i++){
1510 if (effect->isValid) {
1511 if (!effect->_initialized) {
1512 sendInitialFieldsToShader(X3D_NODE(effect));