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"
104#include "system_threads.h"
107#define MAX_EFFECTS 32
112}* ppComponent_ProgrammableShaders;
113void *Component_ProgrammableShaders_constructor(){
118void Component_ProgrammableShaders_init(
struct tComponent_ProgrammableShaders *t){
121 t->prv = Component_ProgrammableShaders_constructor();
123 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)t->prv;
124 p->effect_stack = newStack(
struct X3D_Node*);
128void Component_ProgrammableShaders_clear(
struct tComponent_ProgrammableShaders *t){
130 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)t->prv;
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; \
197int strcmproot(
char* a,
char* b) {
198 char* brackets = strstr(a,
"[0]");
199 printf(
"a=%s b=%s brackets =%s\n", a, b, brackets);
201 return strncmp(a, b, brackets - a);
206static int shader_checkType(
struct FieldDecl * myField,
207 GLuint myShader, GLint myUniform,
char *namePtr) {
222 glGetProgramiv(myShader,GL_ACTIVE_UNIFORMS,&gp);
223 ConsoleMessage (
"in shader %d, we have %d uniforms, looking for name :%s:",myShader,gp,namePtr);
224 for (i=0; i<gp; i++) {
225 glGetActiveUniform(myShader,i,(GLsizei)90,&len,&size,&type,ch);
226 ConsoleMessage(
" ....Uniform %d is name :%s: len %d size %d type %d",i,ch,len,size,type);
227 if (strcmproot(ch,namePtr)==0) {
228 ConsoleMessage (
"names match, breaking");
234 glGetActiveUniform(myShader,myUniform,(GLsizei)90,&len,&size,&type,ch);
240 switch (fieldDecl_getType(myField)) {
241 case FIELDTYPE_SFFloat: retval = type == GL_FLOAT;
break;
242 case FIELDTYPE_MFFloat: retval = type == GL_FLOAT;
break;
243 case FIELDTYPE_SFRotation: retval = type == GL_FLOAT_VEC4;
break;
244 case FIELDTYPE_MFRotation: retval = type == GL_FLOAT_VEC4;
break;
245 case FIELDTYPE_SFVec3f: retval = type == GL_FLOAT_VEC3;
break;
246 case FIELDTYPE_MFVec3f: retval = type == GL_FLOAT_VEC3;
break;
247 case FIELDTYPE_MFInt32:
248 case FIELDTYPE_SFInt32: retval = type == GL_INT;
break;
249 case FIELDTYPE_MFBool:
250 case FIELDTYPE_SFBool: retval = type == GL_BOOL;
break;
251 case FIELDTYPE_SFNode:
break;
252 case FIELDTYPE_MFNode:
break;
253 case FIELDTYPE_SFColor: retval = type == GL_FLOAT_VEC3;
break;
254 case FIELDTYPE_MFColor: retval = type == GL_FLOAT_VEC3;
break;
255 case FIELDTYPE_SFColorRGBA: retval = type == GL_FLOAT_VEC4;
break;
256 case FIELDTYPE_MFColorRGBA: retval = type == GL_FLOAT_VEC4;
break;
257 case FIELDTYPE_SFTime: retval = type == GL_FLOAT;
break;
258 case FIELDTYPE_MFTime:
break;
259 case FIELDTYPE_SFString:
break;
260 case FIELDTYPE_MFString:
break;
261 case FIELDTYPE_SFVec2f: retval = type == GL_FLOAT_VEC2;
break;
262 case FIELDTYPE_MFVec2f: retval = type == GL_FLOAT_VEC2;
break;
263 case FIELDTYPE_SFImage:
break;
264 case FIELDTYPE_FreeWRLPTR:
break;
265 case FIELDTYPE_SFVec3d: retval = type == GL_FLOAT_VEC3;
break;
266 case FIELDTYPE_MFVec3d:
break;
267 case FIELDTYPE_SFDouble: retval = type == GL_FLOAT;
break;
268 case FIELDTYPE_MFDouble:
break;
269 case FIELDTYPE_SFMatrix3f:
break;
270 case FIELDTYPE_MFMatrix3f:
break;
271 case FIELDTYPE_SFMatrix3d:
break;
272 case FIELDTYPE_MFMatrix3d:
break;
273 case FIELDTYPE_SFMatrix4f:
break;
274 case FIELDTYPE_MFMatrix4f:
break;
275 case FIELDTYPE_SFMatrix4d:
break;
276 case FIELDTYPE_MFMatrix4d:
break;
277 case FIELDTYPE_SFVec2d: retval = type == GL_FLOAT_VEC2;
break;
278 case FIELDTYPE_MFVec2d:
break;
279 case FIELDTYPE_SFVec4f: retval = type == GL_FLOAT_VEC4;
break;
280 case FIELDTYPE_MFVec4f:
break;
281 case FIELDTYPE_SFVec4d: retval = type == GL_FLOAT_VEC4;
break;
282 case FIELDTYPE_MFVec4d:
break;
288 ConsoleMessage (
"Shader type check: X3D type and shader type not compatible for variable :%s:",ch);
291 printf (
"shaderCheck mode %d (%s) type %d (%s) name %d\n",fieldDecl_getAccessType(myField),
292 stringPROTOKeywordType(fieldDecl_getAccessType(myField)),
293 fieldDecl_getType(myField), stringFieldtypeType(fieldDecl_getType(myField)),
294 fieldDecl_getIndexName(myField));
296 printf (
"len %d size %d type %d ch %s\n",len,size,type,ch);
299 case GL_FLOAT: printf (
"GL_FLOAT\n");
break;
300 case GL_FLOAT_VEC2: printf (
"GL_FLOAT_VEC2\n");
break;
301 case GL_FLOAT_VEC3: printf (
"GL_FLOAT_VEC3\n");
break;
302 case GL_FLOAT_VEC4: printf (
"GL_FLOAT_VEC4\n");
break;
303 case GL_INT: printf (
"GL_INT\n");
break;
304 case GL_INT_VEC2: printf (
"GL_INT_VEC2\n");
break;
305 case GL_INT_VEC3: printf (
"GL_INT_VEC3\n");
break;
306 case GL_INT_VEC4: printf (
"GL_INT_VEC4\n");
break;
307 case GL_BOOL: printf (
"GL_BOOL\n");
break;
308 case GL_BOOL_VEC2: printf (
"GL_BOOL_VEC2\n");
break;
309 case GL_BOOL_VEC3: printf (
"GL_BOOL_VEC3\n");
break;
310 case GL_BOOL_VEC4: printf (
"GL_BOOL_VEC4\n");
break;
311 case GL_FLOAT_MAT2: printf (
"GL_FLOAT_MAT2\n");
break;
312 case GL_FLOAT_MAT3: printf (
"GL_FLOAT_MAT3\n");
break;
313 case GL_FLOAT_MAT4: printf (
"GL_FLOAT_MAT4\n");
break;
326 case GL_SAMPLER_2D: printf (
"GL_SAMPLER_2D\n");
break;
327 case GL_SAMPLER_CUBE: printf (
"GL_SAMPLER_CUBE\n");
break;
328default :{printf (
"not decoded yet, probably a matrix type\n");}
339 GLint shaderVariable = fieldDecl_getshaderVariableID(myField->fieldDecl);
342 printf (
"sendValueToShader... ft %s\n",stringFieldtypeType(fieldDecl_getType(myField->fieldDecl)));
343 printf (
"shaderVariableID is %d\n",shaderVariable);
347 if (shaderVariable == INT_ID_UNDEFINED)
return;
350 switch (fieldDecl_getType(myField->fieldDecl)) {
352#define SF_FLOATS_TO_SHADER(ttt,ty1,ty2) \
353 case FIELDTYPE_SF##ty1: \
354 GLUNIFORM##ttt##FV(shaderVariable, 1, myField->value.sf##ty2.c); \
357#define SF_DOUBLES_TO_SHADER(ttt,ty1,ty2) \
358 case FIELDTYPE_SF##ty1: {float val[4]; int i; \
359 for (i=0; i<ttt; i++) { val[i] = (float) (myField->value.sf##ty2.c[i]); } \
360 GLUNIFORM##ttt##FV(shaderVariable, 1, val); \
363#define SF_FLOAT_TO_SHADER(ty1,ty2) \
364 case FIELDTYPE_SF##ty1: \
365 GLUNIFORM1F(shaderVariable, myField->value.sf##ty2); \
368#define SF_DOUBLE_TO_SHADER(ty1,ty2) \
369 case FIELDTYPE_SF##ty1: {float val = myField->value.sf##ty2; \
370 GLUNIFORM1F(shaderVariable, val); \
373#define MF_FLOATS_TO_SHADER(ttt,ty1,ty2) \
374 case FIELDTYPE_MF##ty1: \
375 GLUNIFORM##ttt##FV(shaderVariable, myField->value.mf##ty2.n, (float *)myField->value.mf##ty2.p); \
379#define SF_INTS_TO_SHADER(ty1,ty2) \
380 case FIELDTYPE_SF##ty1: \
381 GLUNIFORM1I(shaderVariable, myField->value.sf##ty2); \
384#define MF_INTS_TO_SHADER(ty1,ty2) \
385 case FIELDTYPE_MF##ty1: \
386 GLUNIFORM1IV(shaderVariable, (GLsizei) myField->value.mf##ty2.n, (const GLint *)myField->value.mf##ty2.p); \
390 SF_FLOAT_TO_SHADER(Float,
float)
391 SF_DOUBLE_TO_SHADER(Double,
float)
392 SF_DOUBLE_TO_SHADER(Time,
float)
394 SF_FLOATS_TO_SHADER(2,Vec2f,vec2f)
395 SF_FLOATS_TO_SHADER(3,Vec3f,vec3f)
396 SF_FLOATS_TO_SHADER(3,Color,color)
397 SF_FLOATS_TO_SHADER(4,ColorRGBA,colorrgba)
398 SF_FLOATS_TO_SHADER(4,Rotation,rotation)
399 SF_FLOATS_TO_SHADER(4,Vec4f,vec4f)
400 SF_DOUBLES_TO_SHADER(2,Vec2d, vec2d)
401 SF_DOUBLES_TO_SHADER(3,Vec3d, vec3d)
402 SF_DOUBLES_TO_SHADER(4,Vec4d, vec4d)
404 MF_FLOATS_TO_SHADER(1,Float,
float)
406 MF_FLOATS_TO_SHADER(2,Vec2f,vec2f)
407 MF_FLOATS_TO_SHADER(3,Color,color)
408 MF_FLOATS_TO_SHADER(3,Vec3f,vec3f)
409 MF_FLOATS_TO_SHADER(4,ColorRGBA,colorrgba)
410 MF_FLOATS_TO_SHADER(4,Rotation,rotation)
412 SF_INTS_TO_SHADER(Bool,
bool)
413 SF_INTS_TO_SHADER(Int32,int32)
414 MF_INTS_TO_SHADER(Bool,
bool)
415 MF_INTS_TO_SHADER(Int32,int32)
423 case FIELDTYPE_SFNode:
424 case FIELDTYPE_SFImage:
425 case FIELDTYPE_FreeWRLPTR:
426 case FIELDTYPE_SFString:
427 case FIELDTYPE_SFMatrix3d:
428 case FIELDTYPE_SFMatrix4d:
431 case FIELDTYPE_MFNode:
432 case FIELDTYPE_MFTime:
433 case FIELDTYPE_MFString:
434 case FIELDTYPE_MFDouble:
435 case FIELDTYPE_MFVec3d:
436 case FIELDTYPE_MFMatrix3f:
437 case FIELDTYPE_MFMatrix3d:
438 case FIELDTYPE_MFMatrix4f:
439 case FIELDTYPE_MFMatrix4d:
440 case FIELDTYPE_MFVec2d:
441 case FIELDTYPE_MFVec4d:
442 default : printf (
"can not send a shader variable of %s yet\n",stringFieldtypeType(fieldDecl_getType(myField->fieldDecl)));
487void getField_ToShader(
struct X3D_Node *node,
int toOffset,
union anyVrml *toAny,
int type) {
496 GLuint currentShader = 0;
498 struct CRStruct *CRoutes = getCRoutes();
509 parents = node->_parentVector;
511 while(i < vectorSize(parents)){
515 if( ap->_nodeType == NODE_Proto) ap = vector_get(
struct X3D_Appearance *,ap->_parentVector, 0);
516 if (ap->_nodeType == NODE_Appearance) {
517 for (j=0; j<vectorSize(ap->_parentVector); j++) {
520 if (sh->_nodeType == NODE_Shape) {
522 shaderflags.base = sh->_shaderflags_base;
523 shaderflags.effects = sh->_shaderflags_effects;
524 shaderflags.usershaders = sh->_shaderflags_usershaders;
529 if(ap->_nodeType == NODE_ProgramShader){
531 parents = ap->_parentVector;
537 if(!shaderflags.base && !shaderflags.usershaders){
546 enableGlobalShader(getMyShaders(shaderflags));
561 switch(node->_nodeType){
562 case NODE_ComposedShader:
563 myObj[0] = (
struct Shader_Script *)(X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields);
568 case NODE_PackagedShader:
569 myObj[0] = (
struct Shader_Script *)(X3D_PACKAGEDSHADER(node)->_shaderUserDefinedFields);
571 case NODE_ProgramShader:{
574 for (i=0; i<X3D_PROGRAMSHADER(node)->programs.n; i++) {
575 struct X3D_ShaderProgram *ps = X3D_SHADERPROGRAM(X3D_PROGRAMSHADER(node)->programs.p[i]);
578 myObj[i] = (
struct Shader_Script *)ps->_shaderUserDefinedFields;
583 case NODE_ShaderProgram:
585 myObj[0] = (
struct Shader_Script *)(X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields);
588 ConsoleMessage (
"getField_ToShader, unhandled type??");
604 if (myObj[0] == NULL)
return;
607 for (i=0; i<numObjs; i++) {
608 if (!myObj[i]->loaded) {
615 for (j=0; j<numObjs; j++) {
617 toField = vector_get(
struct ScriptFieldDecl*, myObj[j]->fields, toOffset);
618 fromFieldID = fieldDecl_getshaderVariableID(toField->fieldDecl);
620 for(i=0; i!=vectorSize(myObj[j]->fields); ++i) {
621 GLint shaderVariable;
627 myf = curField->fieldDecl;
628 shaderVariable = fieldDecl_getshaderVariableID(myf);
646 if (fromFieldID == fieldDecl_getShaderScriptIndex(myf)) {
657 sourceData = &toAny->sffloat;
660#define ROUTE_SF_FLOAT_TO_SHADER(ty1) \
661 case FIELDTYPE_SF##ty1: \
662 GLUNIFORM1F(shaderVariable, *((float*)sourceData)); \
665#define ROUTE_SF_DOUBLE_TO_SHADER(ty1) \
666 case FIELDTYPE_SF##ty1: {float val = (float) *((double *)sourceData); \
667 GLUNIFORM1F(shaderVariable, val); \
670#define ROUTE_SF_INTS_TO_SHADER(ty1) \
671 case FIELDTYPE_SF##ty1: \
672 GLUNIFORM1I(shaderVariable, *((int*)sourceData)); \
675#define ROUTE_SF_FLOATS_TO_SHADER(ttt,ty1) \
676 case FIELDTYPE_SF##ty1: \
677 GLUNIFORM##ttt##FV(shaderVariable, 1, (float*)sourceData); \
680#define ROUTE_SF_DOUBLES_TO_SHADER(ttt,ty1) \
681 case FIELDTYPE_SF##ty1: {float val[4]; int i; double *fp = (double*)sourceData; \
682 for (i=0; i<ttt; i++) { val[i] = (float) (*fp); fp++; } \
683 GLUNIFORM##ttt##FV(shaderVariable, 1, val); \
687#define ROUTE_MF_FLOATS_TO_SHADER(ttt,ty1) \
688 case FIELDTYPE_MF##ty1: { struct Multi_##ty1 *sd = (struct Multi_##ty1*) sourceData; \
689 printf ("MF_FLOATS_TO_SHADER, sv %d, sd->n %d\n",shaderVariable,sd->n); \
690 GLUNIFORM##ttt##FV(shaderVariable, sd->n, (const GLfloat *)sd->p); \
693#define ROUTE_MF_INTS_TO_SHADER(ttt,ty1) \
694 case FIELDTYPE_MF##ty1: { struct Multi_##ty1 *sd = (struct Multi_##ty1*) sourceData; \
695 GLUNIFORM##ttt##IV(shaderVariable, sd->n, (const GLint *)sd->p); \
701 switch (JSparamnames[fromFieldID].type) {
702 ROUTE_SF_FLOAT_TO_SHADER(Float)
703 ROUTE_SF_DOUBLE_TO_SHADER(Double)
704 ROUTE_SF_DOUBLE_TO_SHADER(Time)
705 ROUTE_SF_INTS_TO_SHADER(Bool)
706 ROUTE_SF_INTS_TO_SHADER(Int32)
708 ROUTE_SF_FLOATS_TO_SHADER(2,Vec2f)
709 ROUTE_SF_FLOATS_TO_SHADER(3,Vec3f)
710 ROUTE_SF_FLOATS_TO_SHADER(3,Color)
711 ROUTE_SF_FLOATS_TO_SHADER(4,ColorRGBA)
712 ROUTE_SF_FLOATS_TO_SHADER(4,Rotation)
713 ROUTE_SF_FLOATS_TO_SHADER(4,Vec4f)
714 ROUTE_SF_DOUBLES_TO_SHADER(2,Vec2d)
715 ROUTE_SF_DOUBLES_TO_SHADER(3,Vec3d)
716 ROUTE_SF_DOUBLES_TO_SHADER(4,Vec4d)
718 ROUTE_MF_FLOATS_TO_SHADER(1,Float)
719 ROUTE_MF_FLOATS_TO_SHADER(2,Vec2f)
720 ROUTE_MF_FLOATS_TO_SHADER(3,Color)
721 ROUTE_MF_FLOATS_TO_SHADER(3,Vec3f)
722 ROUTE_MF_FLOATS_TO_SHADER(4,ColorRGBA)
723 ROUTE_MF_FLOATS_TO_SHADER(4,Rotation)
725 ROUTE_MF_INTS_TO_SHADER(1,Bool)
726 ROUTE_MF_INTS_TO_SHADER(1,Int32)
730 case FIELDTYPE_SFNode:
731 case FIELDTYPE_MFNode:
732 case FIELDTYPE_MFTime:
733 case FIELDTYPE_SFString:
734 case FIELDTYPE_MFString:
735 case FIELDTYPE_MFImage:
736 case FIELDTYPE_FreeWRLPTR:
737 case FIELDTYPE_MFVec3d:
738 case FIELDTYPE_MFDouble:
739 case FIELDTYPE_SFMatrix3f:
740 case FIELDTYPE_MFMatrix3f:
741 case FIELDTYPE_SFMatrix3d:
742 case FIELDTYPE_MFMatrix3d:
743 case FIELDTYPE_SFMatrix4f:
744 case FIELDTYPE_MFMatrix4f:
745 case FIELDTYPE_SFMatrix4d:
746 case FIELDTYPE_MFMatrix4d:
747 case FIELDTYPE_MFVec2d:
748 case FIELDTYPE_MFVec4d:
749 ConsoleMessage (
"shader field type %s not routable yet",stringFieldtypeType(JSparamnames[fromFieldID].type));
752 ConsoleMessage (
"shader field type %s not routable yet",stringFieldtypeType(JSparamnames[fromFieldID].type));
758 finishedWithGlobalShader();
764static void send_fieldToShader (GLuint myShader,
struct X3D_Node *node) {
770 if (node->_nodeType==NODE_ShaderProgram) me = (
struct Shader_Script *) X3D_SHADERPROGRAM(node)->_shaderUserDefinedFields;
771 else if (node->_nodeType == NODE_ComposedShader) me = (
struct Shader_Script *) X3D_COMPOSEDSHADER(node)->_shaderUserDefinedFields;
772 else if (node->_nodeType == NODE_Effect) me = (
struct Shader_Script *) X3D_EFFECT(node)->_shaderUserDefinedFields;
774 printf (
"send_fieldToShader, expected a ShaderProgram or ComposedShader, got %s\n",
775 stringNodeType(node->_nodeType));
781 printf (
"Shader_Script has node of %p ",me->ShaderScriptNode);
782 printf (
"of type %s ",stringNodeType(me->ShaderScriptNode->_nodeType));
783 printf (
"and has %d as a vector size ",vectorSize(me->fields));
784 if (me->loaded) printf (
"locked and loaded ");
else printf (
"needs loading, I guess ");
791 for (i=0; i<MAX_MULTITEXTURE; i++) {
792 char myShaderTextureName[200];
795 sprintf (myShaderTextureName,
"textureUnit[%d]",(
int) i);
796 myVar = GET_UNIFORM(myShader,myShaderTextureName);
797 if (myVar != INT_ID_UNDEFINED) {
798 printf (
"for texture %s, we got %d\n", myShaderTextureName,myVar);
799 GLUNIFORM1I(myVar,(
int) i);
805 if (me == NULL)
return;
812 for(i=0; i!=vectorSize(me->fields); ++i) {
821 myf = curField->fieldDecl;
822 namePtr = fieldDecl_getShaderScriptName(myf);
827 printf (
"looking for field name %s...\n",namePtr);
828 printf(
"fieldDecl mode %d (%s) type %d (%s) name %d\n",myf->PKWmode,
829 stringPROTOKeywordType(myf->PKWmode), myf->fieldType, stringFieldtypeType(myf->fieldType),myf->lexerNameIndex);
836 myVar = GET_UNIFORM(myShader,namePtr);
838 if (myVar == INT_ID_UNDEFINED) {
839 if (GET_ATTRIB(myShader,fieldDecl_getShaderScriptName(myf)) != INT_ID_UNDEFINED)
840 ConsoleMessage (
"Shader variable :%s: is declared as an attribute; we can not do much with this",fieldDecl_getShaderScriptName(myf));
842 ConsoleMessage (
"Shader variable :%s: is either not declared or not used in the shader program",fieldDecl_getShaderScriptName(myf));
847 shader_checkType(myf,myShader,myVar,namePtr);
852 fieldDecl_setshaderVariableID(myf,myVar);
855 if ((fieldDecl_getAccessType(myf)==PKW_initializeOnly) || (fieldDecl_getAccessType(myf)==PKW_inputOutput)) {
856 sendValueToShader(curField);
894void sendInitialFieldsToShader(
struct X3D_Node * node) {
899 myShader = getAppearanceProperties()->currentShaderProperties->myShaderProgram;
902 switch (node->_nodeType) {
903 case NODE_ProgramShader: {
906 for (i=0; i<X3D_PROGRAMSHADER(node)->programs.n; i++) {
908 printf (
"ProgramShader, activate %d isSelected %d isValid %d TRUE %d FALSE %d\n",
909 X3D_PROGRAMSHADER(node)->activate,X3D_PROGRAMSHADER(node)->isSelected,
910 X3D_PROGRAMSHADER(node)->isValid, TRUE, FALSE);
914 struct X3D_ShaderProgram *part = X3D_SHADERPROGRAM(X3D_PROGRAMSHADER(node)->programs.p[i]);
917 printf (
"sendInitial, have part %p\n",part);
920 send_fieldToShader(myShader, X3D_NODE(part));
922 X3D_PROGRAMSHADER(node)->_initialized = TRUE;
927 case NODE_ComposedShader: {
929 send_fieldToShader(myShader, X3D_NODE(node));
930 X3D_COMPOSEDSHADER(node)->_initialized = TRUE;
945static void tellShapeNodeToRecompile (
struct X3D_Node *node) {
949 if (node->_nodeType == NODE_Shape) {
952 for (i=0; i<vectorSize(node->_parentVector); i++) {
953 struct X3D_Node * parent = vector_get(
struct X3D_Node*, node->_parentVector, i);
955 if (parent == NULL)
return;
956 tellShapeNodeToRecompile(parent);
963 LOADER_INITIAL_STATE=0,
964 LOADER_REQUEST_RESOURCE,
965 LOADER_FETCHING_RESOURCE,
972static void *thread_compile_ComposedShader(
void *args) {
977 GLchar **vertShaderSource;
978 GLchar **fragShaderSource;
983 int haveVertShaderText;
984 int haveFragShaderText;
986 inArgs = (
struct myArgs *) args;
988 node = X3D_COMPOSEDSHADER(inArgs->node);
992 fwl_setCurrentHandle(tg,__FILE__,__LINE__);
995 haveVertShaderText = FALSE;
996 haveFragShaderText = FALSE;
999 ConsoleMessage(
"called compile_ComposedShader(%p)\n",(
void *)node);
1003 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
1005 if (node->_shaderUserNumber < 0) {
1006 ConsoleMessage (
"out of user defined shader slots - can not run");
1011 vertShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->parts.n);
1012 fragShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->parts.n);
1015 node->isValid = TRUE;
1024 for (i=0; i<node->parts.n; i++) {
1027 vertShaderSource[i] = NULL;
1028 fragShaderSource[i] = NULL;
1031 if (prog->_nodeType == NODE_ShaderPart) {
1034 if (!((strcmp (prog->type->strptr,
"VERTEX")) && (strcmp(prog->type->strptr,
"FRAGMENT")))) {
1035 char *myText = NULL;
1038 cptr = prog->url.p[0]->strptr;
1040 ConsoleMessage (
"error reading url for :%s:",stringNodeType(NODE_ShaderPart));
1045 if (!strcmp(prog->type->strptr,
"VERTEX")) {
1046 vertShaderSource[i] = STRDUP(myText);
1047 haveVertShaderText = TRUE;
1049 fragShaderSource[i] = STRDUP(myText);
1050 haveFragShaderText = TRUE;
1056 ConsoleMessage (
"%s, invalid Type, got \"%s\"",stringNodeType(NODE_ShaderPart), prog->type->strptr);
1057 node->isValid = FALSE;
1060 ConsoleMessage (
"Shader, expected \"%s\", got \"%s\"",stringNodeType(NODE_ShaderPart), stringNodeType(prog->_nodeType));
1061 node->isValid = FALSE;
1081 if (node->isValid) {
1083 sendShaderTextToEngine(node->_shaderUserNumber,node->parts.n,vertShaderSource,fragShaderSource);
1085 ConsoleMessage (
"shader node is NOT valid");
1086 FREE_IF_NZ(vertShaderSource);
1087 FREE_IF_NZ(fragShaderSource);
1091 ZERO_THREAD(node->_shaderLoadThread);
1092 node->_retrievedURLData = (haveFragShaderText && haveVertShaderText);
1094 tellShapeNodeToRecompile(X3D_NODE(node));
1102static void *thread_compile_ProgramShader (
void *args){
1107 GLchar **vertShaderSource;
1108 GLchar **fragShaderSource;
1109 int i, node_isValid;
1113 int haveVertShaderText;
1114 int haveFragShaderText;
1116 inArgs = (
struct myArgs *) args;
1117 node = X3D_PROGRAMSHADER(inArgs->node);
1121 fwl_setCurrentHandle(tg,__FILE__,__LINE__);
1123 haveVertShaderText = FALSE;
1124 haveFragShaderText = FALSE;
1127 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeUserDefinedShaderSlot();
1129 if (node->_shaderUserNumber < 0) {
1130 ConsoleMessage (
"out of user defined shader slots - can not run");
1136 vertShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->programs.n);
1137 fragShaderSource = MALLOC(GLchar **,
sizeof(GLchar*) * node->programs.n);
1140 node->isValid = FALSE;
1141 node_isValid = TRUE;
1146 if (strcmp(node->language->strptr,
"GLSL")) {
1147 ConsoleMessage (
"Shaders: support only GLSL shading language, got :%s:, skipping...",node->language->strptr);
1148 node_isValid = FALSE;
1154 LOCATE_SHADER_PARTS(ShaderProgram,programs)
1158 for (i=0; i<node->programs.n; i++) {
1161 vertShaderSource[i] = NULL;
1162 fragShaderSource[i] = NULL;
1165 if (prog->_nodeType == NODE_ShaderProgram) {
1167 if (!((strcmp (prog->type->strptr,
"VERTEX")) && (strcmp(prog->type->strptr,
"FRAGMENT")))) {
1168 char *myText = NULL;
1170 cptr = prog->url.p[0]->strptr;
1172 ConsoleMessage (
"error reading url for :%s:",stringNodeType(NODE_ShaderProgram));
1177 if (!strcmp(prog->type->strptr,
"VERTEX")) {
1178 vertShaderSource[i] = STRDUP(myText);
1179 haveVertShaderText = TRUE;
1181 fragShaderSource[i] = STRDUP(myText);
1182 haveFragShaderText = TRUE;
1188 ConsoleMessage (
"%s, invalid Type, got \"%s\"",stringNodeType(NODE_ShaderProgram), prog->type->strptr);
1189 node_isValid = FALSE;
1192 ConsoleMessage (
"Shader, expected \"%s\", got \"%s\"",stringNodeType(NODE_ShaderProgram), stringNodeType(prog->_nodeType));
1193 node_isValid = FALSE;
1202 sendShaderTextToEngine(node->_shaderUserNumber,node->programs.n,vertShaderSource,fragShaderSource);
1204 FREE_IF_NZ(vertShaderSource);
1205 FREE_IF_NZ(fragShaderSource);
1209 ZERO_THREAD(node->_shaderLoadThread);
1210 node->_retrievedURLData = (haveFragShaderText && haveVertShaderText);
1212 tellShapeNodeToRecompile(X3D_NODE(node));
1213 node->isValid = node_isValid;
1219 node->url.p[0]->strptr = STRDUP(buffer);
1224bool parser_process_res_SHADER(resource_item_t *res)
1233 switch (res->type) {
1239 buffer = res->URLrequest;
1251 of = res->openned_files;
1257 buffer = (
char*)of->fileData;
1263 return shader_initCode(ss, buffer);
1270 resource_item_t *res;
1272 switch (node->__loadstatus) {
1273 case LOADER_INITIAL_STATE:
1275 if (node->url.n == 0) {
1276 node->__loadstatus = LOADER_STABLE;
1279 char * sc = shader_initCodeFromMFUri(&node->url);
1281 node->url.p[0]->strptr = sc;
1283 node->__loadstatus = LOADER_LOADED;
1285 res = resource_create_multi(&(node->url));
1286 res->media_type = resm_fshader;
1287 node->__loadstatus = LOADER_REQUEST_RESOURCE;
1288 node->__loadResource = res;
1293 case LOADER_REQUEST_RESOURCE:
1294 res = node->__loadResource;
1295 resource_identify(node->_parentResource, res);
1298 res->actions = resa_download | resa_load;
1299 resitem_enqueue(ml_new(res));
1301 node->__loadstatus = LOADER_FETCHING_RESOURCE;
1304 case LOADER_FETCHING_RESOURCE:
1305 res = node->__loadResource;
1310 if (res->status == ress_loaded) {
1312 res->whereToPlaceData = X3D_NODE(node);
1313 res->offsetFromWhereToPlaceData = 0;
1314 res->actions = resa_process;
1315 node->__loadstatus = LOADER_PROCESSING;
1316 res->complete = FALSE;
1319 resitem_enqueue(ml_new(res));
1320 }
else if ((res->status == ress_failed) || (res->status == ress_invalid)) {
1322 printf (
"resource failed to load\n");
1323 node->__loadstatus = LOADER_STABLE;
1328 case LOADER_PROCESSING:
1329 res = node->__loadResource;
1334 if (res->status == ress_parsed) {
1335 node->__loadstatus = LOADER_LOADED;
1337 node->__loadstatus = LOADER_STABLE;
1345 case LOADER_COMPILED:
1351 return node->__loadstatus == LOADER_COMPILED;
1354int shaderprograms_loaded_but_not_compiled(
struct Multi_Node *programs){
1355 int i, retval = TRUE;
1356 for(i=0;i<programs->n;i++){
1358 retval = retval && !shaderprogram_compiled(sp) && shaderprogram_loaded(sp);
1363void set_shaderprograms_compiled(
struct Multi_Node *programs){
1365 for(i=0;i<programs->n;i++){
1367 sp->__loadstatus = LOADER_COMPILED;
1372 ttglobal tg = gglobal();
1373 if(shaderprograms_loaded_but_not_compiled(&node->parts)){
1375 args = MALLOC(
struct myArgs *,
sizeof (
struct myArgs));
1376 args->node = X3D_NODE(node);
1382 if (TEST_NULL_THREAD(node->_shaderLoadThread)) {
1383 pthread_create (&(node->_shaderLoadThread), NULL,
1384 &thread_compile_ComposedShader, (
void *)args);
1388 thread_compile_ComposedShader(args);
1390 set_shaderprograms_compiled(&node->parts);
1396 ttglobal tg = gglobal();
1397 if(shaderprograms_loaded_but_not_compiled(&node->programs)){
1398 set_shaderprograms_compiled(&node->programs);
1399 args = MALLOC(
struct myArgs *,
sizeof (
struct myArgs));
1400 args->node = X3D_NODE(node);
1404 if (TEST_NULL_THREAD(node->_shaderLoadThread)) {
1405 pthread_create (&(node->_shaderLoadThread), NULL,
1406 &thread_compile_ProgramShader, (
void *)args);
1410 thread_compile_ProgramShader(args);
1417 ConsoleMessage (
"found PackagedShader, do not support this structure, as we support only GLSL");
1418 node->isValid = FALSE;
1426 if (node->isValid) setUserShaderNode(X3D_NODE(node));
1435 setUserShaderNode(X3D_NODE(node));
1444int getNextFreeEffectSlot() {
1446 ttglobal tg = gglobal();
1447 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)tg->Component_ProgrammableShaders.prv;
1450 if (p->effectCount == MAX_EFFECTS)
return -1;
1452 rv = p->effectCount;
1457void compile_Effect (
struct X3D_Effect *node) {
1461 ttglobal tg = gglobal();
1464 for(i=0;i<node->parts.n;i++){
1465 is_valid = is_valid && shaderprogram_loaded(X3D_SHADERPROGRAM(node->parts.p[i]));
1467 node->isValid = is_valid;
1468 if(node->isValid) MARK_NODE_COMPILED
1470static int effect_stack_count = 0;
1473void popShaderFlags();
1475void sib_prep_Effect (
struct X3D_Node *parent,
struct X3D_Node *sibAffector) {
1479 ttglobal tg = gglobal();
1480 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)tg->Component_ProgrammableShaders.prv;
1487 effect_stack_count++;
1489 if (node->_shaderUserNumber == -1) node->_shaderUserNumber = getNextFreeEffectSlot();
1491 shaderflags = getShaderFlags();
1492 shaderflags.effects |= 1L << node->_shaderUserNumber;
1493 pushShaderFlags(shaderflags);
1494 stack_push(
struct X3D_Node*,p->effect_stack,sibAffector);
1498void sib_fin_Effect (
struct X3D_Node *parent,
struct X3D_Node *sibAffector) {
1500 ttglobal tg = gglobal();
1501 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)tg->Component_ProgrammableShaders.prv;
1505 effect_stack_count--;
1507 stack_pop(
struct X3D_Node*,p->effect_stack);
1512Stack *getEffectStack(){
1513 ttglobal tg = gglobal();
1514 ppComponent_ProgrammableShaders p = (ppComponent_ProgrammableShaders)tg->Component_ProgrammableShaders.prv;
1515 return p->effect_stack;
1517void update_effect_uniforms(){
1518 Stack * effect_stack;
1519 effect_stack = getEffectStack();
1520 if(effect_stack && effect_stack->n){
1522 for(i=0;i<effect_stack->n;i++){
1524 if (effect->isValid) {
1525 if (!effect->_initialized) {
1526 sendInitialFieldsToShader(X3D_NODE(effect));