44 #include <system_threads.h>
49 #include <libFreeWRL.h>
66 char *insertBefore(
char *current,
char *insert,
char* wholeBuffer,
int wholeBuffersize){
68 char *newcurrent, *here;
69 int insertlen, wholelen, need, movesize;
71 wholelen = strlen(current) +1;
72 insertlen = strlen(insert);
73 need = wholelen + insertlen + 1;
76 if(need < wholeBuffersize){
78 newcurrent = current + insertlen;
79 memmove(newcurrent,current,movesize);
80 memcpy(here,insert,insertlen);
82 ConsoleMessage(
"Not enough buffer for compositing shader buffsz=%d need=%d\n",wholeBuffersize,need);
91 void removeAt(
char *here,
int len){
93 int wholelen, movesize;
95 wholelen = strlen(here) + 1;
97 movesize = wholelen - len;
98 memmove(here,source,movesize);
101 void extractPlugCall(
char *start,
char *PlugName,
char *PlugParameters){
103 char *pns, *pne, *pps, *ppe;
105 pns = strstr(start,
"PLUG: ");
106 pns += strlen(
"PLUG: ");
107 pne = strchr(pns,
' ');
109 strncpy(PlugName,pns,len);
110 PlugName[len] =
'\0';
111 pps = strchr(pne,
'(');
112 ppe = strchr(pps,
')') + 1;
114 strncpy(PlugParameters,pps,len);
115 PlugParameters[len] =
'\0';
124 int LookForPlugDeclarations(
char * CodeForPlugDeclarations,
int bsize,
char *PlugName,
char *ProcedureName,
char *ForwardDeclaration) {
133 char MainPlugName[100], MainPlugParams[1000];
135 int AnyOccurrencesHere = FALSE;
138 S = CodeForPlugDeclarations;
143 S = strstr(S,
"/* PLUG: ");
149 char ProcedureCallBuffer[500], *ProcedureCall;
150 extractPlugCall(S,MainPlugName,MainPlugParams);
151 if(!strcmp(MainPlugName,PlugName)){
156 ProcedureCall = ProcedureCallBuffer;
157 sprintf(ProcedureCall,
"%s%s;\n",ProcedureName,MainPlugParams);
158 S = insertBefore(S,ProcedureCall,CodeForPlugDeclarations,bsize);
159 AnyOccurrencesHere = TRUE;
164 S += strlen(
"/* PLUG:") + strlen(MainPlugName) + strlen(MainPlugParams);
171 if(AnyOccurrencesHere){
175 S = CodeForPlugDeclarations;
176 S = strstr(S,
"/* PLUG-DECLARATIONS */");
177 if(!S) S = CodeForPlugDeclarations;
178 S = insertBefore(S,ForwardDeclaration,CodeForPlugDeclarations,bsize);
183 printf(
"didn't find PLUG_%s\n",PlugName);
191 void replaceAll(
char *buffer,
int bsize,
char *oldstr,
char *newstr){
193 while((found = strstr(buffer,oldstr))){
194 removeAt(found,strlen(oldstr));
195 insertBefore(found,newstr,buffer,bsize);
204 void extractPlugName(
char *start,
char *PlugName,
char *PlugDeclaredParameters){
206 char *pns, *pne, *pps, *ppe;
208 pns = strstr(start,
"PLUG_");
209 pns += strlen(
"PLUG_");
211 pne = strpbrk(pns,
" (");
213 strncpy(PlugName,pns,len);
214 PlugName[len] =
'\0';
215 pps = strchr(pne,
'(');
216 ppe = strchr(pps,
')') + 1;
218 strncpy(PlugDeclaredParameters,pps,len);
219 PlugDeclaredParameters[len] =
'\0';
222 #define SBUFSIZE 32767 //must hold final size of composited shader part, could do per-gglobal-instance malloced buffer instead and resize to largest composited shader
223 #define PBUFSIZE 16384 //must hold largets PlugValue
224 int fw_strcpy_s(
char *dest,
int destsize,
const char *source){
227 if(source && strlen(source) < (
unsigned)destsize){
233 int fw_strcat_s(
char *dest,
int destsize,
const char *source){
236 int destlen = strlen(dest);
238 if(strlen(source)+destlen < (
unsigned)destsize){
245 void Plug(
int EffectPartType,
const char *PlugValue,
char **CompleteCode,
int *unique_int)
256 char PlugName[100], PlugDeclaredParameters[1000], PlugForwardDeclaration[1000], ProcedureName[100], PLUG_PlugName[100];
257 char Code[SBUFSIZE], Plug[PBUFSIZE];
258 int HasGeometryMain = FALSE, AnyOccurrences;
268 if(!CompleteCode[EffectPartType])
return;
269 err = fw_strcpy_s(Code,SBUFSIZE, CompleteCode[EffectPartType]);
270 err = fw_strcpy_s(Plug,PBUFSIZE, PlugValue);
275 HasGeometryMain = HasGeometryMain ||
276 ((EffectPartType == SHADERPART_GEOMETRY) && strstr(
"main(",Plug));
282 found = strstr(found,
"void PLUG_");
288 extractPlugName(found,PlugName,PlugDeclaredParameters);
289 found += strlen(
"void PLUG_") + strlen(PlugName) + strlen(PlugDeclaredParameters);
293 sprintf(ProcedureName,
"%s_%d",PlugName,(*unique_int));
298 sprintf(PLUG_PlugName,
"%s%s",
"PLUG_",PlugName);
299 replaceAll(Plug,PBUFSIZE,PLUG_PlugName,ProcedureName);
303 sprintf(PlugForwardDeclaration,
"void %s%s;\n",ProcedureName,PlugDeclaredParameters);
306 AnyOccurrences = LookForPlugDeclarations(Code,SBUFSIZE, PlugName,ProcedureName,PlugForwardDeclaration);
325 ConsoleMessage(
"Plug name %s not declared\n",PlugName);
336 err = fw_strcat_s(Code,SBUFSIZE,Plug);
337 FREE_IF_NZ(CompleteCode[EffectPartType]);
338 CompleteCode[EffectPartType] = strdup(Code);
341 void AddVersion(
int EffectPartType,
int versionNumber,
char **CompleteCode){
343 char Code[SBUFSIZE], line[1000];
349 if (!CompleteCode[EffectPartType])
return;
350 err = fw_strcpy_s(Code, SBUFSIZE, CompleteCode[EffectPartType]);
354 sprintf(line,
"#version %d \n", versionNumber);
355 insertBefore(found, line, Code, SBUFSIZE);
356 FREE_IF_NZ(CompleteCode[EffectPartType]);
357 CompleteCode[EffectPartType] = strdup(Code);
360 void AddDefine0(
int EffectPartType,
const char *defineName,
int defineValue,
char **CompleteCode)
363 char Code[SBUFSIZE], line[1000];
369 if(!CompleteCode[EffectPartType])
return;
370 err = fw_strcpy_s(Code,SBUFSIZE, CompleteCode[EffectPartType]);
372 found = strstr(Code,
"/* DEFINE");
374 sprintf(line,
"#define %s %d \n",defineName,defineValue);
375 insertBefore(found,line,Code,SBUFSIZE);
376 FREE_IF_NZ(CompleteCode[EffectPartType]);
377 CompleteCode[EffectPartType] = strdup(Code);
380 void AddDefine(
int EffectPartType,
const char *defineName,
char **CompleteCode){
383 AddDefine0(EffectPartType,defineName,1,CompleteCode);
396 void EnableEffect(
struct X3D_Node * node,
char **CompletedCode,
int *unique_int){
400 ipart=SHADERPART_VERTEX;
402 for(i=0;i<effect->parts.n;i++){
404 if(part->_nodeType == NODE_EffectPart){
405 if(!strcmp(part->type->strptr,
"FRAGMENT"))
406 ipart = SHADERPART_FRAGMENT;
407 else if(!strcmp(part->type->strptr,
"VERTEX"))
408 ipart = SHADERPART_VERTEX;
409 str = part->url.p[0]->strptr;
410 if(!strncmp(str,
"data:text/plain,",strlen(
"data:text/plain,")))
411 str += strlen(
"data:text/plain,");
412 Plug(ipart,str, CompletedCode, unique_int);
416 Stack *getEffectStack();
417 void EnableEffects(
char **CompletedCode,
int *unique_int){
420 effect_stack = getEffectStack();
421 for(i=0;i<vectorSize(effect_stack);i++){
423 if(node->_nodeType == NODE_Effect){
424 EnableEffect(node,CompletedCode,unique_int);
476 static const GLchar *genericVertexGLES2 =
"\
478 /* Generic GLSL vertex shader, used on OpenGL ES. */ \n\
480 uniform mat4 fw_ModelViewMatrix; \n\
481 uniform mat4 fw_ProjectionMatrix; \n\
482 uniform mat3 fw_NormalMatrix; \n\
484 uniform mat4 fw_ModelViewInverseMatrix; \n\
486 attribute vec4 fw_Vertex; \n\
487 attribute vec3 fw_Normal; \n\
490 uniform mat4 fw_TextureMatrix0; \n\
491 attribute vec4 fw_MultiTexCoord0; \n\
492 //varying vec3 v_texC; \n\
493 varying vec3 fw_TexCoord[4]; \n\
495 uniform int tex3dUseVertex; \n\
498 uniform mat4 fw_TextureMatrix1; \n\
499 uniform mat4 fw_TextureMatrix2; \n\
500 uniform mat4 fw_TextureMatrix3; \n\
501 attribute vec4 fw_MultiTexCoord1; \n\
502 attribute vec4 fw_MultiTexCoord2; \n\
503 attribute vec4 fw_MultiTexCoord3; \n\
506 #define TCGT_CAMERASPACENORMAL 0 \n\
507 #define TCGT_CAMERASPACEPOSITION 1 \n\
508 #define TCGT_CAMERASPACEREFLECTION 2 \n\
509 #define TCGT_COORD 3 \n\
510 #define TCGT_COORD_EYE 4 \n\
511 #define TCGT_NOISE 5 \n\
512 #define TCGT_NOISE_EYE 6 \n\
513 #define TCGT_SPHERE 7 \n\
514 #define TCGT_SPHERE_LOCAL 8 \n\
515 #define TCGT_SPHERE_REFLECT 9 \n\
516 #define TCGT_SPHERE_REFLECT_LOCAL 10 \n\
517 uniform int fw_textureCoordGenType; \n\
521 varying vec2 hatchPosition; \n\
524 /* PLUG-DECLARATIONS */ \n\
526 varying vec4 castle_vertex_eye; \n\
527 varying vec3 castle_normal_eye; \n\
528 varying vec4 castle_Color; //DA diffuse ambient term \n\
530 //uniform float castle_MaterialDiffuseAlpha; \n\
531 //uniform float castle_MaterialShininess; \n\
532 /* Color summed with all the lights. \n\
533 Like gl_Front/BackLightModelProduct.sceneColor: \n\
534 material emissive color + material ambient color * global (light model) ambient. \n\
538 #define MAX_LIGHTS 8 \n\
539 uniform int lightcount; \n\
540 //uniform float lightRadius[MAX_LIGHTS]; \n\
541 uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
542 struct fw_LightSourceParameters { \n\
548 vec4 spotDirection; \n\
549 float spotBeamWidth; \n\
550 float spotCutoff; \n\
551 vec3 Attenuations; \n\
552 float lightRadius; \n\
555 uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
558 //uniform vec3 castle_SceneColor; \n\
559 //uniform vec4 castle_UnlitColor; \n\
561 uniform vec4 fw_UnlitColor; \n\
564 struct fw_MaterialParameters { \n\
571 uniform fw_MaterialParameters fw_FrontMaterial; \n\
572 varying vec3 castle_ColorES; //emissive shininess term \n\
573 vec3 castle_Emissive; \n\
575 uniform fw_MaterialParameters fw_BackMaterial; \n\
582 float visibilityRange; \n\
583 float fogScale; //applied on cpu side to visrange \n\
584 int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL \n\
585 // ifdefed int haveFogCoords; \n\
587 uniform fogParams fw_fogparams; \n\
589 attribute float fw_FogCoords; \n\
592 float castle_MaterialDiffuseAlpha; \n\
593 float castle_MaterialShininess; \n\
594 vec3 castle_SceneColor; \n\
595 vec4 castle_UnlitColor; \n\
596 vec4 castle_Specular; \n\
599 attribute vec4 fw_Color; //castle_ColorPerVertex; \n\
600 varying vec4 cpv_Color; \n\
603 uniform vec3 particlePosition; \n\
604 uniform int fw_ParticleGeomType; \n\
605 #endif //PARTICLE \n\
607 vec3 dehomogenize(in mat4 matrix, in vec4 vector){ \n\
608 vec4 tempv = vector; \n\
609 if(tempv.w == 0.0) tempv.w = 1.0; \n\
610 vec4 temp = matrix * tempv; \n\
611 float winv = 1.0/temp.w; \n\
612 return temp.xyz * winv; \n\
617 castle_MaterialDiffuseAlpha = fw_FrontMaterial.diffuse.a; \n\
620 //to modulate or not to modulate, this is the question \n\
621 //in here, we turn off modulation and use image alpha \n\
622 castle_MaterialDiffuseAlpha = 1.0; \n\
625 castle_MaterialShininess = fw_FrontMaterial.shininess; \n\
626 castle_SceneColor = fw_FrontMaterial.ambient.rgb; \n\
627 castle_Specular = fw_FrontMaterial.specular; \n\
628 castle_Emissive = fw_FrontMaterial.emission.rgb; \n\
630 castle_SceneColor = vec3(0.0,0.0,0.0); //line gets color from castle_Emissive \n\
633 //default unlits in case we dont set them \n\
634 castle_UnlitColor = vec4(1.0,1.0,1.0,1.0); \n\
635 castle_MaterialDiffuseAlpha = 1.0; \n\
639 hatchPosition = fw_Vertex.xy; \n\
642 vec4 vertex_object = fw_Vertex; \n\
644 if(fw_ParticleGeomType != 4){ \n\
645 vertex_object.xyz += particlePosition; \n\
647 #endif //PARTICLE \n\
648 vec3 normal_object = fw_Normal; \n\
649 /* PLUG: vertex_object_space_change (vertex_object, normal_object) */ \n\
650 /* PLUG: vertex_object_space (vertex_object, normal_object) */ \n\
652 #ifdef CASTLE_BUGGY_GLSL_READ_VARYING \n\
653 /* use local variables, instead of reading + writing to varying variables, \n\
654 when VARYING_NOT_READABLE */ \n\
655 vec4 temp_castle_vertex_eye; \n\
656 vec3 temp_castle_normal_eye; \n\
657 vec4 temp_castle_Color; \n\
658 #define castle_vertex_eye temp_castle_vertex_eye \n\
659 #define castle_normal_eye temp_castle_normal_eye \n\
660 #define castle_Color temp_castle_Color \n\
661 #endif //CASTLE_BUGGY_GLSL_READ_VARYING \n\
663 castle_vertex_eye = fw_ModelViewMatrix * vertex_object; \n\
665 //sprite: align to viewer \n\
666 if(fw_ParticleGeomType == 4){ \n\
667 vec4 ppos = vec4(particlePosition,1.0); \n\
668 vec4 particle_eye = fw_ModelViewMatrix * ppos; \n\
670 vec4 particle_eye1 = fw_ModelViewMatrix * ppos; \n\
671 float pscal = length(particle_eye1.xyz - particle_eye.xyz); \n\
672 castle_vertex_eye = particle_eye + pscal*vertex_object; \n\
674 #endif //PARTICLE \n\
675 castle_normal_eye = normalize(fw_NormalMatrix * normal_object); \n\
677 /* PLUG: vertex_eye_space (castle_vertex_eye, castle_normal_eye) */ \n\
680 castle_ColorES = castle_Emissive; \n\
681 castle_Color = vec4(castle_SceneColor, 1.0); \n\
682 /* PLUG: add_light_contribution2 (castle_Color, castle_ColorES, castle_vertex_eye, castle_normal_eye, castle_MaterialShininess) */ \n\
683 /* PLUG: add_light_contribution (castle_Color, castle_vertex_eye, castle_normal_eye, castle_MaterialShininess) */ \n\
684 castle_Color.a = castle_MaterialDiffuseAlpha; \n\
685 /* Clamp sum of lights colors to be <= 1. See template.fs for comments. */ \n\
686 castle_Color.rgb = min(castle_Color.rgb, 1.0); \n\
688 castle_Color.rgb = castle_UnlitColor.rgb; \n\
691 #ifdef CPV //color per vertex \n\
692 cpv_Color = fw_Color; \n\
696 vec4 texcoord = fw_MultiTexCoord0; \n\
698 //to re-use vertex coords as texturecoords3D, we need them in 0-1 range: CPU calc of fw_TextureMatrix0 \n\
699 if(tex3dUseVertex == 1) \n\
700 texcoord = vec4(fw_Vertex.xyz,1.0); \n\
706 vec3 texcoord3 = texcoord.xyz; \n\
707 vertexNorm = normalize(fw_NormalMatrix * fw_Normal); \n\
708 vertexPos = fw_ModelViewMatrix * fw_Vertex; \n\
709 /* sphereEnvironMapping Calculation */ \n\
710 vec3 u=normalize(vec3(vertexPos)); /* u is normalized position, used below more than once */ \n\
711 vec3 r= reflect(u,vertexNorm); \n\
712 if (fw_textureCoordGenType==TCGT_SPHERE) { /* TCGT_SPHERE GL_SPHERE_MAP OpenGL Equiv */ \n\
713 float m=2.0 * sqrt(r.x*r.x + r.y*r.y + (r.z*1.0)*(r.z*1.0)); \n\
714 texcoord3 = vec3(r.x/m+0.5,r.y/m+0.5,0.0); \n\
715 }else if (fw_textureCoordGenType==TCGT_CAMERASPACENORMAL) { \n\
716 /* GL_REFLECTION_MAP used for sampling cubemaps */ \n\
717 float dotResult = 2.0 * dot(u,r); \n\
718 texcoord3 = vec3(u-r)*dotResult; \n\
719 }else if (fw_textureCoordGenType==TCGT_COORD) { \n\
720 /* 3D textures can use coords in 0-1 range */ \n\
721 texcoord3 = fw_Vertex.xyz; //xyz; \n\
722 } else { /* default usage - like default CubeMaps */ \n\
723 vec3 u=normalize(vec3(fw_ProjectionMatrix * fw_Vertex)); /* myEyeVertex */ \n\
724 texcoord3 = reflect(u,vertexNorm); \n\
726 texcoord.xyz = texcoord3; \n\
729 fw_TexCoord[0] = dehomogenize(fw_TextureMatrix0, texcoord); \n\
731 fw_TexCoord[1] = dehomogenize(fw_TextureMatrix1,fw_MultiTexCoord1); \n\
732 fw_TexCoord[2] = dehomogenize(fw_TextureMatrix2,fw_MultiTexCoord2); \n\
733 fw_TexCoord[3] = dehomogenize(fw_TextureMatrix3,fw_MultiTexCoord3); \n\
737 gl_Position = fw_ProjectionMatrix * castle_vertex_eye; \n\
741 vec4 camera = fw_ModelViewInverseMatrix * vec4(0.0,0.0,0.0,1.0); \n\
742 //vec3 u = normalize( vec4(castle_vertex_eye - camera).xyz ); \n\
743 vec3 u = normalize( vec4(vertex_object + camera).xyz ); \n\
744 vec3 v = normalize(fw_Normal); \n\
745 fw_TexCoord[0] = normalize(reflect(u,v)); //computed in object space \n\
746 fw_TexCoord[0].st = -fw_TexCoord[0].st; //helps with renderman cubemap convention \n\
748 #ifdef CASTLE_BUGGY_GLSL_READ_VARYING \n\
749 #undef castle_vertex_eye \n\
750 #undef castle_normal_eye \n\
751 #undef castle_Color \n\
752 castle_vertex_eye = temp_castle_vertex_eye; \n\
753 castle_normal_eye = temp_castle_normal_eye; \n\
754 castle_Color = temp_castle_Color; \n\
755 #endif //CASTLE_BUGGY_GLSL_READ_VARYING \n\
759 castle_vertex_eye.z = fw_FogCoords; \n\
760 #endif //FOGCOORD \n\
763 castle_Color = fw_UnlitColor; \n\
800 static const GLchar *genericFragmentGLES2 =
"\
803 //precision highp float; \n\
804 precision mediump float; \n\
806 /* Generic GLSL fragment shader, used on OpenGL ES. */ \n\
808 varying vec4 castle_Color; \n\
811 #define MAX_LIGHTS 8 \n\
812 uniform int lightcount; \n\
813 //uniform float lightRadius[MAX_LIGHTS]; \n\
814 uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
815 struct fw_LightSourceParameters { \n\
821 vec4 spotDirection; \n\
822 float spotBeamWidth; \n\
823 float spotCutoff; \n\
824 vec3 Attenuations; \n\
825 float lightRadius; \n\
828 uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
832 varying vec4 cpv_Color; \n\
837 uniform samplerCube fw_Texture_unit0; \n\
839 uniform sampler2D fw_Texture_unit0; \n\
841 varying vec3 fw_TexCoord[4]; \n\
843 uniform int tex3dTiles[3]; \n\
844 uniform int repeatSTR[3]; \n\
845 uniform int magFilter; \n\
848 uniform sampler2D fw_Texture_unit1; \n\
849 uniform sampler2D fw_Texture_unit2; \n\
850 uniform sampler2D fw_Texture_unit3; \n\
851 uniform int textureCount; \n\
852 #endif //TEX3DLAY \n\
854 uniform sampler2D fw_Texture_unit1; \n\
855 uniform sampler2D fw_Texture_unit2; \n\
856 uniform sampler2D fw_Texture_unit3; \n\
857 uniform ivec2 fw_Texture_mode0; \n\
858 uniform ivec2 fw_Texture_mode1; \n\
859 uniform ivec2 fw_Texture_mode2; \n\
860 uniform ivec2 fw_Texture_mode3; \n\
861 uniform ivec2 fw_Texture_source0; \n\
862 uniform ivec2 fw_Texture_source1; \n\
863 uniform ivec2 fw_Texture_source2; \n\
864 uniform ivec2 fw_Texture_source3; \n\
865 uniform int fw_Texture_function0; \n\
866 uniform int fw_Texture_function1; \n\
867 uniform int fw_Texture_function2; \n\
868 uniform int fw_Texture_function3; \n\
869 uniform int textureCount; \n\
870 uniform vec4 mt_Color; \n\
871 #define MTMODE_ADD 1\n \
872 #define MTMODE_ADDSIGNED 2\n \
873 #define MTMODE_ADDSIGNED2X 3\n \
874 #define MTMODE_ADDSMOOTH 4\n \
875 #define MTMODE_BLENDCURRENTALPHA 5\n \
876 #define MTMODE_BLENDDIFFUSEALPHA 6\n \
877 #define MTMODE_BLENDFACTORALPHA 7\n \
878 #define MTMODE_BLENDTEXTUREALPHA 8\n \
879 #define MTMODE_DOTPRODUCT3 9\n \
880 #define MTMODE_MODULATE 10\n \
881 #define MTMODE_MODULATE2X 11\n \
882 #define MTMODE_MODULATE4X 12\n \
883 #define MTMODE_MODULATEALPHA_ADDCOLOR 13\n \
884 #define MTMODE_MODULATEINVALPHA_ADDCOLOR 14\n \
885 #define MTMODE_MODULATEINVCOLOR_ADDALPHA 15\n \
886 #define MTMODE_OFF 16\n \
887 #define MTMODE_REPLACE 17\n \
888 #define MTMODE_SELECTARG1 18\n \
889 #define MTMODE_SELECTARG2 19\n \
890 #define MTMODE_SUBTRACT 20\n \
891 #define MTSRC_DIFFUSE 1 \n\
892 #define MTSRC_FACTOR 2 \n\
893 #define MTSRC_SPECULAR 3 \n\
894 #define MTFN_ALPHAREPLICATE 0 \n\
895 #define MTFN_COMPLEMENT 1 \n\
896 #define MT_DEFAULT -1 \n\
898 void finalColCalc(inout vec4 prevColour, in int mode, in int modea, in int func, in sampler2D tex, in vec2 texcoord) { \n\
899 vec4 texel = texture2D(tex,texcoord); \n\
900 vec4 rv = vec4(1.,0.,1.,1.); \n\
901 if (mode==MTMODE_OFF) { \n\
902 rv = vec4(prevColour); \n\
903 } else if (mode==MTMODE_REPLACE) { \n\
904 rv = vec4(texture2D(tex, texcoord)); \n\
905 }else if (mode==MTMODE_MODULATE) { \n\
908 cf = prevColour.rgb; \n\
909 af = prevColour.a; \n\
912 rv = vec4(ct*cf, at*af); \n\
913 } else if (mode==MTMODE_MODULATE2X) { \n\
916 cf = prevColour.rgb; \n\
917 af = prevColour.a; \n\
920 rv = vec4(vec4(ct*cf, at*af)*vec4(2.,2.,2.,2.)); \n\
921 }else if (mode==MTMODE_MODULATE4X) { \n\
924 cf = prevColour.rgb; \n\
925 af = prevColour.a; \n\
928 rv = vec4(vec4(ct*cf, at*af)*vec4(4.,4.,4.,4.)); \n\
929 }else if (mode== MTMODE_ADDSIGNED) { \n\
930 rv = vec4 (prevColour + texel - vec4 (0.5, 0.5, 0.5, -.5)); \n\
931 } else if (mode== MTMODE_ADDSIGNED2X) { \n\
932 rv = vec4 ((prevColour + texel - vec4 (0.5, 0.5, 0.5, -.5))*vec4(2.,2.,2.,2.)); \n\
933 } else if (mode== MTMODE_ADD) { \n\
934 rv= vec4 (prevColour + texel); \n\
935 } else if (mode== MTMODE_SUBTRACT) { \n\
936 rv = vec4 (texel - prevColour); //jas had prev - tex \n\
937 } else if (mode==MTMODE_ADDSMOOTH) { \n\
938 rv = vec4 (prevColour + (prevColour - vec4 (1.,1.,1.,1.)) * texel); \n\
939 } else if (mode==MTMODE_BLENDDIFFUSEALPHA) { \n\
940 rv = vec4 (mix(prevColour,texel,castle_Color.a)); \n\
941 } else if (mode==MTMODE_BLENDTEXTUREALPHA) { \n\
942 rv = vec4 (mix(prevColour,texel,texel.a)); \n\
943 } else if (mode==MTMODE_BLENDFACTORALPHA) { \n\
944 rv = vec4 (mix(prevColour,texel,mt_Color.a)); \n\
945 } else if (mode==MTMODE_BLENDCURRENTALPHA) { \n\
946 rv = vec4 (mix(prevColour,texel,prevColour.a)); \n\
947 } else if (mode==MTMODE_SELECTARG1) { \n\
949 } else if (mode==MTMODE_SELECTARG2) { \n\
953 if (modea==MTMODE_OFF) { \n\
954 rv.a = prevColour.a; \n\
955 } else if (modea==MTMODE_REPLACE) { \n\
957 }else if (modea==MTMODE_MODULATE) { \n\
959 af = prevColour.a; \n\
962 } else if (modea==MTMODE_MODULATE2X) { \n\
964 af = prevColour.a; \n\
966 rv.a = at*af*2.0; \n\
967 }else if (modea==MTMODE_MODULATE4X) { \n\
969 af = prevColour.a; \n\
971 rv.a = at*af*4.0; \n\
972 }else if (modea== MTMODE_ADDSIGNED) { \n\
973 rv.a = (prevColour.a + texel.a + .5); \n\
974 } else if (modea== MTMODE_ADDSIGNED2X) { \n\
975 rv.a = ((prevColour.a + texel.a + .5))*2.0; \n\
976 } else if (modea== MTMODE_ADD) { \n\
977 rv.a = prevColour.a + texel.a; \n\
978 } else if (modea== MTMODE_SUBTRACT) { \n\
979 rv.a = texel.a - prevColour.a; //jas had prev - texel \n\
980 } else if (modea==MTMODE_ADDSMOOTH) { \n\
981 rv.a = (prevColour.a + (prevColour.a - 1.)) * texel.a; \n\
982 } else if (modea==MTMODE_BLENDDIFFUSEALPHA) { \n\
983 rv.a = mix(prevColour.a,texel.a,castle_Color.a); \n\
984 } else if (modea==MTMODE_BLENDTEXTUREALPHA) { \n\
985 rv.a = mix(prevColour.a,texel.a,texel.a); \n\
986 } else if (modea==MTMODE_BLENDFACTORALPHA) { \n\
987 rv.a = mix(prevColour.a,texel.a,mt_Color.a); \n\
988 } else if (modea==MTMODE_BLENDCURRENTALPHA) { \n\
989 rv.a = mix(prevColour.a,texel.a,prevColour.a); \n\
990 } else if (modea==MTMODE_SELECTARG1) { \n\
992 } else if (modea==MTMODE_SELECTARG2) { \n\
993 rv.a = prevColour.a; \n\
996 if(func == MTFN_COMPLEMENT){ \n\
997 //rv = vec4(1.0,1.0,1.0,1.0) - rv; \n\
998 rv = vec4( vec3(1.0,1.0,1.0) - rv.rgb, rv.a); \n\
999 }else if(func == MTFN_ALPHAREPLICATE){ \n\
1000 rv = vec4(rv.a,rv.a,rv.a,rv.a); \n\
1002 prevColour = rv; \n\
1007 uniform vec4 HatchColour; \n\
1008 uniform bool hatched; uniform bool filled;\n\
1009 uniform vec2 HatchScale; \n\
1010 uniform vec2 HatchPct; \n\
1011 uniform int algorithm; \n\
1012 varying vec2 hatchPosition; \n\
1013 void fillPropCalc(inout vec4 prevColour, vec2 MCposition, int algorithm) { \n\
1015 vec2 position, useBrick; \n\
1017 position = MCposition / HatchScale; \n\
1019 if (algorithm == 0) {/* bricking */ \n\
1020 if (fract(position.y * 0.5) > 0.5) \n\
1021 position.x += 0.5; \n\
1024 /* algorithm 1, 2 = no futzing required here */ \n\
1025 if (algorithm == 3) { /* positive diagonals */ \n\
1026 vec2 curpos = position; \n\
1027 position.x -= curpos.y; \n\
1030 if (algorithm == 4) { /* negative diagonals */ \n\
1031 vec2 curpos = position; \n\
1032 position.x += curpos.y; \n\
1035 if (algorithm == 6) { /* diagonal crosshatch */ \n\
1036 vec2 curpos = position; \n\
1037 if (fract(position.y) > 0.5) { \n\
1038 if (fract(position.x) < 0.5) position.x += curpos.y; \n\
1039 else position.x -= curpos.y; \n\
1041 if (fract(position.x) > 0.5) position.x += curpos.y; \n\
1042 else position.x -= curpos.y; \n\
1046 position = fract(position); \n\
1048 useBrick = step(position, HatchPct); \n\
1050 if (filled) {colour = prevColour;} else { colour=vec4(0.,0.,0.,0); }\n\
1052 colour = mix(HatchColour, colour, useBrick.x * useBrick.y); \n\
1054 prevColour = colour; \n\
1058 struct fogParams \n\
1061 float visibilityRange; \n\
1063 int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL \n\
1064 // ifdefed int haveFogCoords; \n\
1066 uniform fogParams fw_fogparams; \n\
1069 /* PLUG-DECLARATIONS */ \n\
1071 #ifdef HAS_GEOMETRY_SHADER \n\
1072 #define castle_vertex_eye castle_vertex_eye_geoshader \n\
1073 #define castle_normal_eye castle_normal_eye_geoshader \n\
1076 varying vec4 castle_vertex_eye; \n\
1077 varying vec3 castle_normal_eye; \n\
1080 //per-fragment lighting ie phong \n\
1081 struct fw_MaterialParameters { \n\
1086 float shininess; \n\
1088 uniform fw_MaterialParameters fw_FrontMaterial; \n\
1090 uniform fw_MaterialParameters fw_BackMaterial; \n\
1092 vec3 castle_ColorES; \n\
1094 //per-vertex lighting - interpolated Emissive-specular \n\
1095 varying vec3 castle_ColorES; //emissive shininess term \n\
1099 /* Wrapper for calling PLUG texture_coord_shift */ \n\
1100 vec2 texture_coord_shifted(in vec2 tex_coord) \n\
1102 /* PLUG: texture_coord_shift (tex_coord) */ \n\
1103 return tex_coord; \n\
1106 vec4 matdiff_color; \n\
1109 vec4 fragment_color = vec4(1.0,1.0,1.0,1.0); \n\
1110 matdiff_color = castle_Color; \n\
1111 float castle_MaterialDiffuseAlpha = castle_Color.a; \n\
1114 //per-fragment lighting aka PHONG \n\
1115 //start over with the color, since we have material and lighting in here \n\
1116 castle_MaterialDiffuseAlpha = fw_FrontMaterial.diffuse.a; \n\
1117 matdiff_color = vec4(0,0,0,1.0); \n\
1118 castle_ColorES = fw_FrontMaterial.emission.rgb; \n\
1119 /* PLUG: add_light_contribution2 (matdiff_color, castle_ColorES, castle_vertex_eye, castle_normal_eye, fw_FrontMaterial.shininess) */ \n\
1124 fragment_color.rgb = matdiff_color.rgb; \n\
1128 fragment_color = castle_Color; \n\
1133 fragment_color = cpv_Color; //CPV replaces mat.diffuse prior \n\
1134 fragment_color.a *= castle_MaterialDiffuseAlpha; \n\
1136 fragment_color *= cpv_Color; //CPV modulates prior \n\
1142 fragment_color = vec4(1.0,1.0,1.0,1.0); //texture replaces prior \n\
1146 /* Fragment shader on mobile doesn't get a normal vector now, for speed. */ \n\
1147 //#define normal_eye_fragment castle_normal_eye //vec3(0.0) \n\
1148 #define normal_eye_fragment vec3(0.0) \n\
1151 fillPropCalc(matdiff_color, hatchPosition, algorithm); \n\
1156 //modulate texture with mat.diffuse \n\
1157 fragment_color.rgb *= matdiff_color.rgb; \n\
1158 fragment_color.a *= castle_MaterialDiffuseAlpha; \n\
1160 fragment_color.rgb = clamp(fragment_color.rgb + castle_ColorES, 0.0, 1.0); \n\
1163 /* PLUG: texture_apply (fragment_color, normal_eye_fragment) */ \n\
1164 /* PLUG: steep_parallax_shadow_apply (fragment_color) */ \n\
1165 /* PLUG: fog_apply (fragment_color, normal_eye_fragment) */ \n\
1167 #undef normal_eye_fragment \n\
1169 gl_FragColor = fragment_color; \n\
1171 /* PLUG: fragment_end (gl_FragColor) */ \n\
1176 const char *getGenericVertex(
void){
1177 return genericVertexGLES2;
1179 const char *getGenericFragment(){
1180 return genericFragmentGLES2;
1182 #include "../scenegraph/Component_Shape.h"
1184 static const GLchar *plug_fragment_end_anaglyph =
"\
1185 void PLUG_fragment_end (inout vec4 finalFrag){ \n\
1186 float gray = dot(finalFrag.rgb, vec3(0.299, 0.587, 0.114)); \n\
1187 finalFrag = vec4(gray,gray,gray, finalFrag.a); \n\
1229 static const GLchar *plug_fragment_texture3D_apply_volume =
"\n\
1230 vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, in int magfilter){ \n\
1231 vec4 sample = vec4(0.0); \n\
1233 //TILED method (vs Y strip method) \n\
1234 vec3 texcoord = texcoord3; \n\
1235 //texcoord.z = 1.0 - texcoord.z; //flip z from RHS to LHS\n\
1236 float depth = max(1.0,float(tex3dTiles[2])); \n\
1237 if(repeatSTR[0] == 0) texcoord.x = clamp(texcoord.x,0.0001,.9999); \n\
1238 else texcoord.x = mod(texcoord.x,1.0); \n\
1239 if(repeatSTR[1] == 0) texcoord.y = clamp(texcoord.y,0.0001,.9999); \n\
1240 else texcoord.y = mod(texcoord.y,1.0); \n\
1241 if(repeatSTR[2] == 0) texcoord.z = clamp(texcoord.z,0.0001,.9999); \n\
1242 else texcoord.z = mod(texcoord.z,1.0); \n\
1244 int izf = int(floor(texcoord.z*depth)); //floor z \n\
1245 int izc = int(ceil(texcoord.z*depth)); //ceiling z \n\
1246 izc = izc == tex3dTiles[2] ? izc - 1 : izc; //clamp int z \n\
1247 vec4 ftexel, ctexel; \n\
1249 int nx = tex3dTiles[0]; //0-11 \n\
1250 int ny = tex3dTiles[1]; \n\
1251 float fnx = 1.0/float(nx); //.1\n\
1252 float fny = 1.0/float(ny); \n\
1253 int ix = izc / ny; //60/11=5\n\
1254 int ixny = ix * ny; //5*11=55\n\
1255 int iy = izc - ixny; //60-55=5 modulus remainder \n\
1256 float cix = float(ix); //5 \n\
1257 float ciy = float(iy); \n\
1258 float xxc = (cix + texcoord.s)*fnx; //(5 + .5)*.1 = .55\n\
1259 float yyc = (ciy + texcoord.t)*fny; \n\
1262 iy = izf - ixny; //modulus remainder \n\
1263 float fix = float(ix); \n\
1264 float fiy = float(iy); \n\
1265 float xxf = (fix + texcoord.s)*fnx; \n\
1266 float yyf = (fiy + texcoord.t)*fny; \n\
1268 vec2 ftexcoord, ctexcoord; //texcoord is 3D, ftexcoord and ctexcoord are 2D coords\n\
1269 ftexcoord.s = xxf; \n\
1270 ftexcoord.t = yyf; \n\
1271 ctexcoord.s = xxc; \n\
1272 ctexcoord.t = yyc; \n\
1273 ftexel = texture2D(sampler,ftexcoord.st); \n\
1274 ctexel = texture2D(sampler,ctexcoord.st); \n\
1275 float fraction = mod(texcoord.z*depth,1.0); \n\
1276 if(magfilter == 1) \n\
1277 texel = mix(ctexel,ftexel,1.0-fraction); //lerp GL_LINEAR \n\
1279 texel = ftexel; //fraction > .5 ? ctexel : ftexel; //GL_NEAREST \n\
1284 vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3){ \n\
1285 //use uniform magfilter \n\
1286 return texture3Demu0( sampler, texcoord3, magFilter); \n\
1288 void PLUG_texture3D( inout vec4 sample, in vec3 texcoord3 ){ \n\
1289 sample = texture3Demu(fw_Texture_unit0,texcoord3); \n\
1291 void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1294 sample = texture3Demu(fw_Texture_unit0,fw_TexCoord[0]); \n\
1295 finalFrag *= sample; \n\
1301 static const GLchar *plug_fragment_texture3Dlayer_apply =
"\
1302 void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1305 vec3 texcoord = fw_TexCoord[0]; \n\
1306 texcoord.z = 1.0 - texcoord.z; //flip z from RHS to LHS\n\
1307 float depth = max(1.0,float(textureCount-1)); \n\
1308 float delta = 1.0/depth; \n\
1309 if(repeatSTR[0] == 0) texcoord.x = clamp(texcoord.x,0.0001,.9999); \n\
1310 else texcoord.x = mod(texcoord.x,1.0); \n\
1311 if(repeatSTR[1] == 0) texcoord.y = clamp(texcoord.y,0.0001,.9999); \n\
1312 else texcoord.y = mod(texcoord.y,1.0); \n\
1313 if(repeatSTR[2] == 0) texcoord.z = clamp(texcoord.z,0.0001,.9999); \n\
1314 else texcoord.z = mod(texcoord.z,1.0); \n\
1315 int flay = int(floor(texcoord.z*depth)); \n\
1316 int clay = int(ceil(texcoord.z*depth)); \n\
1317 vec4 ftexel, ctexel; \n\
1320 if(flay == 0) ftexel = texture2D(fw_Texture_unit0,texcoord.st); \n\
1321 if(clay == 0) ctexel = texture2D(fw_Texture_unit0,texcoord.st); \n\
1322 if(flay == 1) ftexel = texture2D(fw_Texture_unit1,texcoord.st); \n\
1323 if(clay == 1) ctexel = texture2D(fw_Texture_unit1,texcoord.st); \n\
1324 if(flay == 2) ftexel = texture2D(fw_Texture_unit2,texcoord.st); \n\
1325 if(clay == 2) ctexel = texture2D(fw_Texture_unit2,texcoord.st); \n\
1326 if(flay == 3) ftexel = texture2D(fw_Texture_unit3,texcoord.st); \n\
1327 if(clay == 3) ctexel = texture2D(fw_Texture_unit3,texcoord.st); \n\
1328 float fraction = mod(texcoord.z*depth,1.0); \n\
1330 if(magFilter == 1) \n\
1331 texel = mix(ctexel,ftexel,(1.0-fraction)); //lerp GL_LINEAR \n\
1333 texel = fraction > .5 ? ctexel : ftexel; //GL_NEAREST \n\
1334 finalFrag *= texel; \n\
1335 #endif //TEX3DLAY \n\
1342 static const GLchar *plug_fragment_texture_apply =
"\
1343 void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1347 int isource,iasource, mode; \n\
1348 //finalFrag = texture2D(fw_Texture_unit0, fw_TexCoord[0].st) * finalFrag; \n\
1349 if(textureCount>0){ \n\
1350 if(fw_Texture_mode0[0] != MTMODE_OFF) { \n\
1351 isource = fw_Texture_source0[0]; //castle-style dual sources \n\
1352 iasource = fw_Texture_source0[1]; \n\
1353 if(isource == MT_DEFAULT) source = finalFrag; \n\
1354 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1355 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1356 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1357 if(iasource != 0){ \n\
1358 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1359 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1360 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1361 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1363 finalColCalc(source,fw_Texture_mode0[0],fw_Texture_mode0[1],fw_Texture_function0, fw_Texture_unit0,fw_TexCoord[0].st); \n\
1364 finalFrag = source; \n\
1367 if(textureCount>1){ \n\
1368 if(fw_Texture_mode1[0] != MTMODE_OFF) { \n\
1369 isource = fw_Texture_source1[0]; //castle-style dual sources \n\
1370 iasource = fw_Texture_source1[1]; \n\
1371 if(isource == MT_DEFAULT) source = finalFrag; \n\
1372 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1373 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1374 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1375 if(iasource != 0){ \n\
1376 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1377 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1378 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1379 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1381 finalColCalc(source,fw_Texture_mode1[0],fw_Texture_mode1[1],fw_Texture_function1, fw_Texture_unit1,fw_TexCoord[1].st); \n\
1382 finalFrag = source; \n\
1385 if(textureCount>2){ \n\
1386 if(fw_Texture_mode2[0] != MTMODE_OFF) { \n\
1387 isource = fw_Texture_source2[0]; //castle-style dual sources \n\
1388 iasource = fw_Texture_source2[1]; \n\
1389 if(isource == MT_DEFAULT) source = finalFrag; \n\
1390 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1391 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1392 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1393 if(iasource != 0){ \n\
1394 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1395 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1396 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1397 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1399 finalColCalc(source,fw_Texture_mode2[0],fw_Texture_mode2[1],fw_Texture_function2,fw_Texture_unit2,fw_TexCoord[2].st); \n\
1400 finalFrag = source; \n\
1403 if(textureCount>3){ \n\
1404 if(fw_Texture_mode3[0] != MTMODE_OFF) { \n\
1405 isource = fw_Texture_source3[0]; //castle-style dual sources \n\
1406 iasource = fw_Texture_source3[1]; \n\
1407 if(isource == MT_DEFAULT) source = finalFrag; \n\
1408 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1409 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1410 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1411 if(iasource != 0){ \n\
1412 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1413 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1414 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1415 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1417 finalColCalc(source,fw_Texture_mode3[0],fw_Texture_mode3[1],fw_Texture_function3,fw_Texture_unit3,fw_TexCoord[3].st); \n\
1418 finalFrag = source; \n\
1422 /* ONE TEXTURE */ \n\
1424 finalFrag = textureCube(fw_Texture_unit0, fw_TexCoord[0]) * finalFrag; \n\
1426 finalFrag = texture2D(fw_Texture_unit0, fw_TexCoord[0].st) * finalFrag; \n\
1443 static const GLchar *plug_vertex_lighting_matemissive =
"\n\
1444 void PLUG_add_light_contribution (inout vec4 vertexcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ) {\n\
1445 vertexcolor.rgb += fw_FrontMaterial.emissive.rgb; \n\
1449 static const GLchar *plug_vertex_lighting_ADSLightModel =
"\n\
1450 /* use ADSLightModel here the ADS colour is returned from the function. */ \n\
1451 void PLUG_add_light_contribution2 (inout vec4 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ) { \n\
1452 //working in eye space: eye is at 0,0,0 looking generally in direction 0,0,-1 \n\
1453 //myPosition, myNormal - of surface vertex, in eyespace \n\
1454 //vertexcolor - diffuse+ambient -will be replaced or modulated by texture color \n\
1455 //specularcolor - specular+emissive or non-diffuse (emissive added outside this function) \n\
1456 //algo: uses Blinn-Phong specular reflection: half-vector pow(N*H,shininess) \n\
1458 vec4 diffuse = vec4(0., 0., 0., 0.); \n\
1459 vec4 ambient = vec4(0., 0., 0., 0.); \n\
1460 vec4 specular = vec4(0., 0., 0., 1.); \n\
1461 vec3 N = normalize (myNormal); \n\
1463 vec3 E = -normalize(myPosition.xyz); \n \
1464 vec4 matdiffuse = vec4(1.0,1.0,1.0,1.0); \n\
1465 float myAlph = 0.0;\n\
1467 fw_MaterialParameters myMat = fw_FrontMaterial; \n\
1469 /* back Facing materials - flip the normal and grab back materials */ \n\
1470 bool backFacing = (dot(N,E) < 0.0); \n\
1471 if (backFacing) { \n\
1474 myMat = fw_BackMaterial; \n\
1478 myAlph = myMat.diffuse.a; \n\
1479 //if(useMatDiffuse) \n\
1480 matdiffuse = myMat.diffuse; \n\
1482 /* apply the lights to this material */ \n\
1483 /* weird but ANGLE needs constant loop */ \n\
1484 for (i=0; i<MAX_LIGHTS; i++) {\n\
1485 if(i < lightcount) { \n\
1486 vec4 myLightDiffuse = fw_LightSource[i].diffuse; \n\
1487 vec4 myLightAmbient = fw_LightSource[i].ambient; \n\
1488 vec4 myLightSpecular = fw_LightSource[i].specular; \n\
1489 vec4 myLightPosition = fw_LightSource[i].position; \n\
1490 int myLightType = lightType[i]; \n\
1491 vec3 myLightDir = fw_LightSource[i].spotDirection.xyz; \n\
1492 vec3 VP; /* vector of light direction and distance */ \n\
1493 VP = myLightPosition.xyz - myPosition.xyz; \n\
1494 vec3 L = myLightDir; /*directional light*/ \n\
1495 if(myLightType < 2) /*point and spot*/ \n\
1496 L = normalize(VP); \n\
1497 float NdotL = max(dot(N, L), 0.0); //Lambertian diffuse term \n\
1498 /*specular reflection models, phong or blinn-phong*/ \n\
1499 //#define PHONG 1 \n\
1502 vec3 R = normalize(-reflect(L,N)); \n\
1503 float RdotE = max(dot(R,E),0.0); \n\
1504 float specbase = RdotE; \n\
1505 float specpow = .3 * myMat.shininess; //assume shini tuned to blinn, adjust for phong \n\
1508 vec3 H = normalize(L + E); //halfvector\n\
1509 float NdotH = max(dot(N,H),0.0); \n\
1510 float specbase = NdotH; \n\
1511 float specpow = myMat.shininess; \n\
1513 float powerFactor = 0.0; /* for light dropoff */ \n\
1514 if (specbase > 0.0) { \n\
1515 powerFactor = pow(specbase,specpow); \n\
1516 /* tone down the power factor if myMat.shininess borders 0 */ \n\
1517 if (myMat.shininess < 1.0) { \n\
1518 powerFactor *= myMat.shininess; \n\
1522 if (myLightType==1) { \n\
1524 float spotDot, multiplier; \n\
1525 float spotAttenuation = 0.0; \n\
1526 float attenuation; /* computed attenuation factor */ \n\
1527 float D; /* distance to vertex */ \n\
1529 attenuation = 1.0/(fw_LightSource[i].Attenuations.x + (fw_LightSource[i].Attenuations.y * D) + (fw_LightSource[i].Attenuations.z *D*D)); \n\
1530 multiplier = 0.0; \n\
1531 spotDot = dot (-L,myLightDir); \n\
1532 /* check against spotCosCutoff */ \n\
1533 if (spotDot > fw_LightSource[i].spotCutoff) { \n\
1534 //?? what was this: spotAttenuation = pow(spotDot,fw_LightSource[i].spotExponent); \n\
1535 if(spotDot > fw_LightSource[i].spotBeamWidth) { \n\
1536 multiplier = 1.0; \n\
1538 multiplier = (spotDot - fw_LightSource[i].spotCutoff)/(fw_LightSource[i].spotBeamWidth - fw_LightSource[i].spotCutoff); \n\
1541 //attenuation *= spotAttenuation; \n\
1542 attenuation *= multiplier; \n\
1543 /* diffuse light computation */ \n\
1544 diffuse += NdotL* matdiffuse*myLightDiffuse * attenuation; \n\
1545 /* ambient light computation */ \n\
1546 ambient += myMat.ambient*myLightAmbient; \n\
1547 /* specular light computation */ \n\
1548 specular += myLightSpecular * powerFactor * attenuation; \n\
1550 } else if (myLightType == 2) { \n\
1551 /* DirectionalLight */ \n\
1552 /* Specular light computation */ \n\
1553 specular += myMat.specular *myLightSpecular*powerFactor; \n\
1554 /* diffuse light computation */ \n\
1555 diffuse += NdotL*matdiffuse*myLightDiffuse; \n\
1556 /* ambient light computation */ \n\
1557 ambient += myMat.ambient*myLightAmbient; \n\
1559 /* PointLight */ \n\
1560 float attenuation = 0.0; /* computed attenuation factor */ \n\
1561 float D = length(VP); /* distance to vertex */ \n\
1562 /* are we within range? */ \n\
1563 if (D <= fw_LightSource[i].lightRadius) { \n\
1564 /* this is actually the SFVec3f attenuation field */ \n\
1565 attenuation = 1.0/(fw_LightSource[i].Attenuations.x + (fw_LightSource[i].Attenuations.y * D) + (fw_LightSource[i].Attenuations.z *D*D)); \n\
1566 /* diffuse light computation */ \n\
1567 diffuse += NdotL* matdiffuse*myLightDiffuse * attenuation; \n\
1568 /* ambient light computation */ \n\
1569 ambient += myMat.ambient*myLightAmbient; \n\
1570 /* specular light computation */ \n\
1571 attenuation *= (myMat.shininess/128.0); \n\
1572 specular += myLightSpecular * powerFactor * attenuation; \n\
1577 vertexcolor = clamp(vec4(vec3(ambient + diffuse ) + vertexcolor.rgb ,myAlph), 0.0, 1.0); \n\
1578 specularcolor = clamp(specular.rgb + specularcolor, 0.0, 1.0); \n\
1584 static const GLchar *plug_fog_apply =
"\
1585 void PLUG_fog_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1587 float depth = abs(castle_vertex_eye.z/castle_vertex_eye.w); \n\
1588 if(fw_fogparams.fogType > 0){ \n\
1590 if(fw_fogparams.fogType == 1){ //FOGTYPE_LINEAR \n\
1591 if(depth < fw_fogparams.visibilityRange) \n\
1592 ff = (fw_fogparams.visibilityRange-depth)/fw_fogparams.visibilityRange; \n\
1593 } else { //FOGTYPE_EXPONENTIAL \n\
1594 if(depth < fw_fogparams.visibilityRange){ \n\
1595 ff = exp(-depth/(fw_fogparams.visibilityRange -depth) ); \n\
1596 ff = clamp(ff, 0.0, 1.0); \n\
1599 finalFrag = mix(finalFrag,fw_fogparams.fogColor,1.0 - ff); \n\
1604 static const GLchar *vertex_plug_clip_apply =
"\
1606 #define FW_MAXCLIPPLANES 4 \n\
1607 uniform int fw_nclipplanes; \n\
1608 uniform vec4 fw_clipplanes[FW_MAXCLIPPLANES]; \n\
1609 varying float fw_ClipDistance[FW_MAXCLIPPLANES]; \n\
1611 void PLUG_vertex_object_space (in vec4 vertex_object, in vec3 normal_object){ \n\
1612 for ( int i=0; i<fw_nclipplanes; i++ ) \n\
1613 fw_ClipDistance[i] = dot( fw_clipplanes[i], vertex_object); \n\
1618 static const GLchar *frag_plug_clip_apply =
"\
1620 #define FW_MAXCLIPPLANES 4 \n\
1621 uniform int fw_nclipplanes; \n\
1622 varying float fw_ClipDistance[FW_MAXCLIPPLANES]; \n\
1623 void PLUG_fog_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1624 for(int i=0;i<fw_nclipplanes;i++) { \n\
1625 //if(normal_eye_fragment.z > fw_ClipDistance[i]) discard; \n\
1626 if(fw_ClipDistance[i] < 0.0) discard; \n\
1632 #if defined(GL_ES_VERSION_2_0)
1633 static int isMobile = TRUE;
1635 static int isMobile = FALSE;
1638 #define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
1639 int getSpecificShaderSourceCastlePlugs (
const GLchar **vertexSource,
const GLchar **fragmentSource,
shaderflagsstruct whichOne)
1645 int retval, unique_int;
1646 char *CompleteCode[3];
1649 if(whichOne.usershaders )
1654 vs = strdup(getGenericVertex());
1655 fs = strdup(getGenericFragment());
1657 CompleteCode[SHADERPART_VERTEX] = vs;
1658 CompleteCode[SHADERPART_GEOMETRY] = NULL;
1659 CompleteCode[SHADERPART_FRAGMENT] = fs;
1667 AddVersion(SHADERPART_VERTEX, 100, CompleteCode);
1668 AddVersion(SHADERPART_FRAGMENT, 100, CompleteCode);
1669 AddDefine(SHADERPART_FRAGMENT,
"MOBILE",CompleteCode);
1672 AddVersion(SHADERPART_VERTEX, 110, CompleteCode);
1673 AddVersion(SHADERPART_FRAGMENT, 110, CompleteCode);
1681 if(DESIRE(whichOne.base,WANT_ANAGLYPH))
1682 Plug(SHADERPART_FRAGMENT,plug_fragment_end_anaglyph,CompleteCode,&unique_int);
1684 if DESIRE(whichOne.base,COLOUR_MATERIAL_SHADER) {
1685 AddDefine(SHADERPART_VERTEX,
"CPV",CompleteCode);
1686 AddDefine(SHADERPART_FRAGMENT,
"CPV",CompleteCode);
1687 if(DESIRE(whichOne.base,CPV_REPLACE_PRIOR)){
1688 AddDefine(SHADERPART_VERTEX,
"CPVREP",CompleteCode);
1689 AddDefine(SHADERPART_FRAGMENT,
"CPVREP",CompleteCode);
1695 if(DESIRE(whichOne.base,MATERIAL_APPEARANCE_SHADER) || DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER)){
1697 if(DESIRE(whichOne.base,MAT_FIRST)){
1699 AddDefine(SHADERPART_VERTEX,
"MATFIR",CompleteCode);
1700 AddDefine(SHADERPART_FRAGMENT,
"MATFIR",CompleteCode);
1702 if(DESIRE(whichOne.base,SHADINGSTYLE_PHONG) && !DESIRE(whichOne.base,HAVE_LINEPOINTS_COLOR)){
1704 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
1705 AddDefine(SHADERPART_FRAGMENT,
"LITE",CompleteCode);
1706 Plug(SHADERPART_FRAGMENT,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
1708 if(DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER))
1709 AddDefine(SHADERPART_FRAGMENT,
"TWO",CompleteCode);
1713 AddDefine(SHADERPART_FRAGMENT,
"PHONG",CompleteCode);
1715 AddDefine(SHADERPART_VERTEX,
"LIT",CompleteCode);
1716 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
1718 if( DESIRE(whichOne.base,HAVE_LINEPOINTS_COLOR) ) {
1719 AddDefine(SHADERPART_VERTEX,
"LINE",CompleteCode);
1721 AddDefine(SHADERPART_VERTEX,
"LITE",CompleteCode);
1722 Plug(SHADERPART_VERTEX,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
1723 if(DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER))
1724 AddDefine(SHADERPART_VERTEX,
"TWO",CompleteCode);
1746 if(DESIRE(whichOne.base,HAVE_UNLIT_COLOR)){
1747 AddDefine(SHADERPART_VERTEX,
"UNLIT",CompleteCode);
1748 AddDefine(SHADERPART_FRAGMENT,
"UNLIT",CompleteCode);
1750 if (DESIRE(whichOne.base,ONE_TEX_APPEARANCE_SHADER) ||
1751 DESIRE(whichOne.base,HAVE_TEXTURECOORDINATEGENERATOR) ||
1752 DESIRE(whichOne.base,HAVE_CUBEMAP_TEXTURE) ||
1753 DESIRE(whichOne.base,MULTI_TEX_APPEARANCE_SHADER)) {
1754 AddDefine(SHADERPART_VERTEX,
"TEX",CompleteCode);
1755 AddDefine(SHADERPART_FRAGMENT,
"TEX",CompleteCode);
1756 if(DESIRE(whichOne.base,HAVE_TEXTURECOORDINATEGENERATOR) )
1757 AddDefine(SHADERPART_VERTEX,
"TGEN",CompleteCode);
1758 if(DESIRE(whichOne.base,TEX3D_SHADER)){
1765 AddDefine(SHADERPART_VERTEX,
"TEX3D",CompleteCode);
1766 AddDefine(SHADERPART_FRAGMENT,
"TEX3D",CompleteCode);
1768 if(DESIRE(whichOne.base,TEX3D_LAYER_SHADER)){
1770 AddDefine(SHADERPART_FRAGMENT,
"TEX3DLAY",CompleteCode);
1771 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3Dlayer_apply,CompleteCode,&unique_int);
1775 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3D_apply_volume,CompleteCode,&unique_int);
1778 if(DESIRE(whichOne.base,HAVE_CUBEMAP_TEXTURE)){
1779 AddDefine(SHADERPART_VERTEX,
"CUB",CompleteCode);
1780 AddDefine(SHADERPART_FRAGMENT,
"CUB",CompleteCode);
1781 }
else if(DESIRE(whichOne.base,MULTI_TEX_APPEARANCE_SHADER)){
1782 AddDefine(SHADERPART_VERTEX,
"MTEX",CompleteCode);
1783 AddDefine(SHADERPART_FRAGMENT,
"MTEX",CompleteCode);
1785 if(DESIRE(whichOne.base,TEXTURE_REPLACE_PRIOR) )
1786 AddDefine(SHADERPART_FRAGMENT,
"TEXREP",CompleteCode);
1787 if(DESIRE(whichOne.base,TEXALPHA_REPLACE_PRIOR))
1788 AddDefine(SHADERPART_VERTEX,
"TAREP",CompleteCode);
1790 Plug(SHADERPART_FRAGMENT,plug_fragment_texture_apply,CompleteCode,&unique_int);
1800 if(DESIRE(whichOne.base,FILL_PROPERTIES_SHADER)) {
1801 AddDefine(SHADERPART_VERTEX,
"FILL",CompleteCode);
1802 AddDefine(SHADERPART_FRAGMENT,
"FILL",CompleteCode);
1805 if(DESIRE(whichOne.base,FOG_APPEARANCE_SHADER)){
1806 AddDefine(SHADERPART_VERTEX,
"FOG",CompleteCode);
1807 AddDefine(SHADERPART_FRAGMENT,
"FOG",CompleteCode);
1808 if(DESIRE(whichOne.base,HAVE_FOG_COORDS))
1809 AddDefine(SHADERPART_VERTEX,
"FOGCOORD",CompleteCode);
1810 Plug(SHADERPART_FRAGMENT,plug_fog_apply,CompleteCode,&unique_int);
1814 if(DESIRE(whichOne.base,CLIPPLANE_SHADER)){
1815 AddDefine(SHADERPART_VERTEX,
"CLIP",CompleteCode);
1816 Plug(SHADERPART_VERTEX,vertex_plug_clip_apply,CompleteCode,&unique_int);
1817 AddDefine(SHADERPART_FRAGMENT,
"CLIP",CompleteCode);
1818 Plug(SHADERPART_FRAGMENT,frag_plug_clip_apply,CompleteCode,&unique_int);
1820 if(DESIRE(whichOne.base,PARTICLE_SHADER)){
1821 AddDefine(SHADERPART_VERTEX,
"PARTICLE",CompleteCode);
1824 EnableEffects(CompleteCode,&unique_int);
1830 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
1831 *vertexSource = CompleteCode[SHADERPART_VERTEX];
1838 static const GLchar *volumeVertexGLES2 =
" \n\
1839 uniform mat4 fw_ModelViewMatrix; \n\
1840 uniform mat4 fw_ProjectionMatrix; \n\
1841 attribute vec4 fw_Vertex; \n\
1843 /* PLUG-DECLARATIONS */ \n\
1845 varying vec4 castle_vertex_eye; \n\
1846 varying vec4 castle_Color; \n\
1850 vec4 vertex_object = fw_Vertex; \n\
1851 vec3 normal_object = vec3(0.0); \n\
1852 /* PLUG: vertex_object_space (vertex_object, normal_object) */ \n\
1853 castle_vertex_eye = fw_ModelViewMatrix * vertex_object; \n\
1855 castle_Color = vec4(1.0,.5,.5,1.0); \n\
1857 gl_Position = fw_ProjectionMatrix * castle_vertex_eye; \n\
1869 static const GLchar *volumeFragmentGLES2 =
" \n\
1872 //precision highp float; \n\
1873 precision mediump float; \n\
1876 vec4 HeatMapColor(float value, float minValue, float maxValue) \n\
1878 //used for debugging. If min=0,max=1 then magenta is 0, blue,green,yellow, red is 1 \n\
1880 int HEATMAP_COLORS_COUNT; \n\
1882 HEATMAP_COLORS_COUNT = 6; \n\
1883 colors[0] = vec4(0.32, 0.00, 0.32, 1.0); \n\
1884 colors[1] = vec4( 0.00, 0.00, 1.00, 1.00); \n\
1885 colors[2] = vec4(0.00, 1.00, 0.00, 1.00); \n\
1886 colors[3] = vec4(1.00, 1.00, 0.00, 1.00); \n\
1887 colors[4] = vec4(1.00, 0.60, 0.00, 1.00); \n\
1888 colors[5] = vec4(1.00, 0.00, 0.00, 1.00); \n\
1889 float ratio=(float(HEATMAP_COLORS_COUNT)-1.0)*clamp((value-minValue)/(maxValue-minValue),0.0,1.0); \n\
1890 int indexMin=int(floor(ratio)); \n\
1891 int indexMax= indexMin+1 < HEATMAP_COLORS_COUNT-1 ? indexMin+1 : HEATMAP_COLORS_COUNT-1; \n\
1892 ret = mix(colors[indexMin], colors[indexMax], ratio-float(indexMin)); \n\
1893 if(value < minValue) ret = vec4(0.0,0.0,0.0,1.0); \n\
1894 if(value > maxValue) ret = vec4(1.0,1.0,1.0,1.0); \n\
1897 vec4 debug_color; \n\
1898 float hash( float n ) \n\
1900 return fract(sin(n)*43758.5453); \n\
1902 float noise( vec3 xyz ) \n\
1904 // The noise function returns a value in the range -1.0f -> 1.0f \n\
1905 vec3 p = floor(xyz); \n\
1906 vec3 f = fract(xyz); \n\
1908 f = f*f*(3.0-2.0*f); \n\
1909 float n = p.x + p.y*57.0 + 113.0*p.z; \n\
1911 return mix(mix(mix( hash(n+0.0), hash(n+1.0),f.x), \n\
1912 mix( hash(n+57.0), hash(n+58.0),f.x),f.y), \n\
1913 mix(mix( hash(n+113.0), hash(n+114.0),f.x), \n\
1914 mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z); \n\
1916 vec3 noise3( in vec3 xyz, in float range ){ \n\
1917 vec3 rxyz = vec3(xyz); \n\
1918 rxyz.x += noise(xyz)*range; \n\
1919 rxyz.y += noise(xyz)*range; \n\
1920 rxyz.z += noise(xyz)*range; \n\
1924 varying vec4 castle_vertex_eye; \n\
1925 varying vec4 castle_Color; \n\
1926 uniform mat4 fw_ModelViewProjInverse; \n\
1927 //uniform float fw_FocalLength; \n\
1928 uniform vec4 fw_viewport; \n\
1929 uniform vec3 fw_dimensions; \n\
1930 //uniform vec3 fw_RayOrigin; \n\
1931 uniform sampler2D fw_Texture_unit0; \n\
1932 uniform sampler2D fw_Texture_unit1; \n\
1933 uniform sampler2D fw_Texture_unit2; \n\
1934 uniform sampler2D fw_Texture_unit3; \n\
1936 uniform int tex3dTiles[3]; \n\
1937 uniform int repeatSTR[3]; \n\
1938 uniform int magFilter; \n\
1941 uniform int fw_nIDs; \n\
1942 uniform int fw_enableIDs[10]; \n\
1943 uniform int fw_surfaceStyles[2]; \n\
1944 uniform int fw_nStyles; \n\
1945 vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3); \n\
1946 vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, int magfilter); \n\
1947 bool inEnabledSegment(in vec3 texcoords, inout int jstyle){ \n\
1948 bool inside = true; \n\
1949 jstyle = 1; //DEFAULT \n\
1950 vec4 segel = texture3Demu0(fw_Texture_unit1,texcoords,0); \n\
1951 //convert from GL_FLOAT 0-1 to int 0-255 \n\
1952 //Q. is there a way to do int images in GLES2? \n\
1953 int ID = int(floor(segel.a * 255.0 + .1)); \n\
1954 //debug_color = HeatMapColor(float(ID),0.0,5.0); \n\
1955 //debug_color.a = .2; \n\
1956 if(ID < fw_nIDs){ \n\
1957 //specs: The indices of this array corresponds to the segment identifier. \n\
1958 inside = fw_enableIDs[ID] == 0 ? false : true; \n\
1961 int kstyle = fw_nStyles-1; \n\
1962 kstyle = ID < fw_nStyles ? ID : kstyle; \n\
1963 jstyle = fw_surfaceStyles[kstyle]; \n\
1964 jstyle = jstyle == 1 ? 0 : jstyle; \n\
1968 #endif //SEGMENT \n\
1970 uniform float fw_stepSize; \n\
1971 uniform float fw_tolerance; \n\
1972 uniform float fw_surfaceVals[]; \n\
1973 uniform int fw_nVals; \n\
1974 uniform int fw_surfaceStyles[]; \n\
1975 uniform int fw_nStyles; \n\
1986 bool IntersectBox(Ray r, AABB aabb, out float t0, out float t1) \n\
1988 vec3 invR = 1.0 / r.Dir; \n\
1989 vec3 tbot = invR * (aabb.Min-r.Origin); \n\
1990 vec3 ttop = invR * (aabb.Max-r.Origin); \n\
1991 vec3 tmin = min(ttop, tbot); \n\
1992 vec3 tmax = max(ttop, tbot); \n\
1993 vec2 t = max(tmin.xx, tmin.yz); \n\
1994 t0 = max(t.x, t.y); \n\
1995 t = min(tmax.xx, tmax.yz); \n\
1996 t1 = min(t.x, t.y); \n\
1997 return t0 <= t1; \n\
1999 /* PLUG-DECLARATIONS */ \n\
2001 vec3 fw_TexCoord[1]; \n\
2003 #define FW_MAXCLIPPLANES 4 \n\
2004 uniform int fw_nclipplanes; \n\
2005 uniform vec4 fw_clipplanes[FW_MAXCLIPPLANES]; \n\
2006 bool clip (in vec3 vertex_object){ \n\
2007 bool iclip = false; \n\
2008 for ( int i=0; i<fw_nclipplanes; i++ ) { \n\
2009 if( dot( fw_clipplanes[i], vec4(vertex_object,1.0)) < 0.0) \n\
2015 vec3 vertex_eye; \n\
2016 vec3 normal_eye; \n\
2020 debug_color = vec4(0.0); \n\
2021 float maxDist = length(fw_dimensions); //1.414214; //sqrt(2.0); \n\
2022 int numSamples = 128; \n\
2023 float fnumSamples = float(numSamples); \n\
2024 float stepSize = maxDist/fnumSamples; \n\
2025 float densityFactor = 5.0/fnumSamples; //.88; // 1.0=normal H3D, .5 see deeper \n\
2027 vec4 fragment_color; \n\
2029 vec3 rayDirection; \n\
2030 //convert window to frustum \n\
2031 rayDirection.xy = 2.0 * (gl_FragCoord.xy - fw_viewport.xy) / fw_viewport.zw - vec2(1.0); \n\
2032 rayDirection.z = 0.0; \n\
2033 vec3 rayOrigin; // = fw_RayOrigin; \n\
2034 //the equivalent of gluUnproject \n\
2035 //by unprojecting 2 points on ray here, this should also work with ortho viewpoint \n\
2036 vec4 ray4 = vec4(rayDirection,1.0); \n\
2037 vec4 org4 = ray4; \n\
2038 //if I back up the ray origin by -1.0 the front plane clipping works properly \n\
2039 ray4.z = 0.0; //1.0; \n\
2040 org4.z = -1.0; //0.0; \n\
2041 ray4 = fw_ModelViewProjInverse * ray4; \n\
2042 org4 = fw_ModelViewProjInverse * org4; \n\
2045 rayDirection = normalize(ray4.xyz - org4.xyz); \n\
2046 rayOrigin = org4.xyz; \n\
2048 Ray eye = Ray( rayOrigin, rayDirection); \n\
2049 vec3 half_dimensions = fw_dimensions * .5; \n\
2050 vec3 minus_half_dimensions = half_dimensions * -1.0; \n\
2051 AABB aabb = AABB(minus_half_dimensions,half_dimensions); \n\
2053 float tnear, tfar; \n\
2054 IntersectBox(eye, aabb, tnear, tfar); \n\
2055 if (tnear < 0.0) tnear = 0.0; \n\
2056 vec3 rayStart = eye.Origin + eye.Dir * tnear; \n\
2057 vec3 rayStop = eye.Origin + eye.Dir * tfar; \n\
2058 // Perform the ray marching: \n\
2059 vec3 pos = rayStart; \n\
2060 vec3 step = normalize(rayStop-rayStart) * stepSize; \n\
2061 float totaltravel = distance(rayStop, rayStart); \n\
2062 float travel = totaltravel; \n\
2064 vec3 Lo = vec3(0.0); \n\
2065 normal_eye = rayDirection; \n\
2066 vec3 pos2 = pos; \n\
2067 // Transform from object space to texture coordinate space: \n\
2068 pos2 = (pos2+half_dimensions)/fw_dimensions; \n\
2069 pos2 = clamp(pos2,0.001,.999); \n\
2070 raysum = vec4(0.0); \n\
2071 float depth = 0.0; \n\
2072 float lastdensity; \n\
2073 float lastdensity_iso; \n\
2075 for (int i=0; i < numSamples; ++i) { \n\
2076 //raysum = HeatMapColor(travel,0.0,2.0); \n\
2078 // ...lighting and absorption stuff here... \n\
2080 vertex_eye = pos2; \n\
2081 // Transform from object space to texture coordinate space: \n\
2082 pos2 = (pos2+half_dimensions)/fw_dimensions; \n\
2083 //pos2.z = 1.0 - pos2.z; //RHS to LHS \n\
2084 pos2 = clamp(pos2,0.001,.999); \n\
2085 vec3 texcoord3 = pos2; \n\
2086 bool iclip = false; \n\
2088 iclip = clip(vertex_eye); //clip(totaltravel - travel); \n\
2091 fragment_color = vec4(1.0,0.0,1.0,1.0); //do I need a default? seems not \n\
2092 /* PLUG: texture3D ( fragment_color, texcoord3) */ \n\
2095 if(inEnabledSegment(texcoord3,jstyle)){ \n\
2096 #endif //SEGMENT \n\
2097 //assuming we had a scalar input image and put L into .a, \n\
2098 // and computed gradient and put in .rgb : \n\
2099 float density = fragment_color.a; //recover the scalar value \n\
2100 vec3 gradient = fragment_color.rgb - vec3(.5,.5,.5); //we added 127 to (-127 to 127) in CPU gradient computation\n\
2101 //vec4 voxel = vec4(density,density,density,density); //this is where the black visual voxels come from\n\
2102 vec4 voxel = vec4(density,density,density,density); //this is where the black visual voxels come from\n\
2106 lastdensity = density; \n\
2107 lastdensity_iso = 0.0; \n\
2109 int MODE = fw_nVals == 1 ? 1 : 3; \n\
2110 MODE = fw_stepSize != 0.0 && MODE == 1 ? 2 : 1; \n\
2111 #ifdef ISO_MODE3 \n\
2113 for(int i=0;i<fw_nVals;i++){ \n\
2114 float iso = fw_surfaceVals[i]; \n\
2115 if( sign( density - iso) != sign( lastdensity - iso) && length(gradient) > fw_tolerance ){ \n\
2117 int jstyle = min(i,fw_nStyles-1); \n\
2118 jstyle = fw_surfaceStyles[jstyle]; \n\
2119 if(jstyle == 1){ \n\
2120 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2121 } else if(jstyle == 2) { \n\
2122 /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ \n\
2123 } else if(jstyle == 3) { \n\
2124 /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ \n\
2125 } else if(jstyle == 4) { \n\
2126 /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ \n\
2127 } else if(jstyle == 5) { \n\
2128 /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ \n\
2129 } else if(jstyle == 6) { \n\
2130 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2131 } else if(jstyle == 7) { \n\
2132 /* PLUG: voxel_apply_EDGE (voxel, gradient) */ \n\
2133 } else if(jstyle == 8) { \n\
2134 /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ \n\
2135 } else if(jstyle == 9) { \n\
2136 /* PLUG: voxel_apply_SHADED (voxel, gradient) */ \n\
2137 } else if(jstyle == 10) { \n\
2138 /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ \n\
2139 } else if(jstyle == 11) { \n\
2140 /* PLUG: voxel_apply_TONE (voxel, gradient) */ \n\
2143 voxel = vec4(0.0); //similar to discard \n\
2146 lastdensity = density; \n\
2148 #else //ISO_MODE3 \n\
2150 float iso = fw_surfaceVals[0]; \n\
2151 if( sign( density - iso) != sign( lastdensity - iso) && length(gradient) > fw_tolerance ){ \n\
2152 //debug_color = HeatMapColor(iso,0.0,.3); \n\
2154 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2156 voxel = vec4(0.0); //similar to discard \n\
2158 lastdensity = density; \n\
2159 } else if(MODE == 2){ \n\
2160 float iso = fw_surfaceVals[0]; \n\
2161 float density_iso = density / fw_stepSize; \n\
2162 if( sign( density_iso - iso) != sign( lastdensity_iso - iso) && length(gradient) > fw_tolerance ){ \n\
2164 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2166 voxel = vec4(0.0); //similar to discard \n\
2168 lastdensity = density; \n\
2169 lastdensity_iso = density_iso; \n\
2171 #endif //ISO_MODE3 \n\
2174 //debug_color = HeatMapColor(float(jstyle),1.0,12.0); \n\
2175 //debug_color.a = .2; \n\
2176 if(jstyle == 1){ \n\
2177 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2178 } else if(jstyle == 2) { \n\
2179 /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ \n\
2180 } else if(jstyle == 3) { \n\
2181 /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ \n\
2182 } else if(jstyle == 4) { \n\
2183 /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ \n\
2184 } else if(jstyle == 5) { \n\
2185 /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ \n\
2186 } else if(jstyle == 6) { \n\
2187 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2188 } else if(jstyle == 7) { \n\
2189 /* PLUG: voxel_apply_EDGE (voxel, gradient) */ \n\
2190 } else if(jstyle == 8) { \n\
2191 /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ \n\
2192 } else if(jstyle == 9) { \n\
2193 /* PLUG: voxel_apply_SHADED (voxel, gradient) */ \n\
2194 } else if(jstyle == 10) { \n\
2195 /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ \n\
2196 } else if(jstyle == 11) { \n\
2197 /* PLUG: voxel_apply_TONE (voxel, gradient) */ \n\
2200 //non-iso rendering styles \n\
2201 //void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) \n\
2202 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2203 #endif //SEGMENT \n\
2205 density = voxel.a; \n\
2206 //debug_color = HeatMapColor(densityFactor,0.134,.135); \n\
2207 T = (1.0 - raysum.a); \n\
2208 raysum.a += density * T; \n\
2209 raysum.rgb += voxel.rgb * T * density; \n\
2210 if(raysum.a > .99) { \n\
2214 } //if inEnabledSegment \n\
2215 #endif //SEGMENT \n\
2217 travel -= stepSize; \n\
2218 depth += stepSize; \n\
2219 if(travel <= 0.0) break; \n\
2223 //void PLUG_ray_apply (inout vec4 raysum) \n\
2224 /* PLUG: ray_apply (raysum) */ \n\
2225 if(true) gl_FragColor = raysum; \n\
2226 else gl_FragColor = debug_color; \n\
2236 static const GLchar *plug_voxel_DEFAULT =
"\
2237 void voxel_apply_DEFAULT (inout vec4 voxel, inout vec3 gradient) { \n\
2238 float alpha = voxel.a; \n\
2239 //voxel.a = voxel.r; \n\
2240 //voxel.rgb = vec3(alpha); \n\
2242 void PLUG_voxel_apply_DEFAULT (inout vec4 voxel, inout vec3 gradient) { \n\
2243 voxel_apply_DEFAULT(voxel,gradient); \n\
2245 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2246 voxel_apply_DEFAULT(voxel,gradient); \n\
2251 static const GLchar *plug_voxel_OPACITY =
"\
2252 uniform int fw_opacTexture; \n\
2253 //uniform sampler2D fw_Texture_unit3; \n\
2254 void voxel_apply_OPACITY (inout vec4 voxel, inout vec3 gradient) { \n\
2255 if(fw_opacTexture == 1){ \n\
2256 vec4 lookup_color; \n\
2257 float lum = voxel.r; \n\
2258 vec2 texcoord = vec2(lum,0.0); \n\
2259 //this is too simple for the lookups in the specs \n\
2260 //http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/volume.html#t-transferFunctionTextureCoordinateMapping \n\
2261 lookup_color = texture2D(fw_Texture_unit3,texcoord); \n\
2262 voxel.rgb = lookup_color.rgb; \n\
2266 float alpha = voxel.a; \n\
2267 voxel.a = voxel.r; \n\
2268 voxel.rgb = vec3(alpha); \n\
2271 void PLUG_voxel_apply_OPACITY (inout vec4 voxel, inout vec3 gradient) { \n\
2272 voxel_apply_OPACITY(voxel, gradient); \n\
2274 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2275 voxel_apply_OPACITY(voxel, gradient); \n\
2280 static const GLchar *plug_voxel_BLENDED =
"\
2281 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2286 static const GLchar *plug_voxel_BOUNDARY =
"\n\
2287 uniform float fw_boundaryOpacity; \n\
2288 uniform float fw_retainedOpacity; \n\
2289 uniform float fw_opacityFactor; \n\
2290 void voxel_apply_BOUNDARY (inout vec4 voxel, inout vec3 gradient) { \n\
2291 float magnitude = length(gradient); \n\
2292 float factor = (fw_retainedOpacity + fw_boundaryOpacity*pow(magnitude,fw_opacityFactor) ); \n\
2293 voxel.a = voxel.a * factor; \n\
2294 //debug_color = HeatMapColor(factor,0.0,1.0); \n\
2296 void PLUG_voxel_apply_BOUNDARY (inout vec4 voxel, inout vec3 gradient) { \n\
2297 voxel_apply_BOUNDARY(voxel, gradient); \n\
2299 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2300 voxel_apply_BOUNDARY(voxel, gradient); \n\
2305 static const GLchar *plug_voxel_CARTOON =
"\n\
2306 uniform int fw_colorSteps; \n\
2307 uniform vec4 fw_orthoColor; \n\
2308 uniform vec4 fw_paraColor; \n\
2309 void voxel_apply_CARTOON (inout vec4 voxel, inout vec3 gradient) { \n\
2310 float len = length(gradient); \n\
2311 if(len > 0.01) { \n\
2312 vec3 ng = normalize(gradient); \n\
2313 float ndotv = dot(normal_eye,ng); \n\
2314 if(ndotv > 0.01 && voxel.a > 0.0) { \n\
2315 ndotv = floor(ndotv/float(fw_colorSteps))*float(fw_colorSteps); \n\
2316 vec4 color = mix(fw_orthoColor,fw_paraColor,ndotv); \n\
2317 //voxel.rgb = color.rgb*voxel.a; \n\
2318 voxel.rgb = color.rgb; \n\
2320 voxel = vec4(0.0); //similar to discard \n\
2323 voxel = vec4(0.0); //similar to discard \n\
2326 void PLUG_voxel_apply_CARTOON (inout vec4 voxel, inout vec3 gradient) { \n\
2327 voxel_apply_CARTOON(voxel, gradient); \n\
2329 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2330 voxel_apply_CARTOON(voxel, gradient); \n\
2335 static const GLchar *plug_voxel_COMPOSED =
"\
2336 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2341 static const GLchar *plug_voxel_EDGE =
"\
2342 uniform float fw_cosGradientThreshold; \n\
2343 uniform vec4 fw_edgeColor; \n\
2344 void voxel_apply_EDGE (inout vec4 voxel, inout vec3 gradient) { \n\
2345 float len = length(gradient); \n\
2346 if(len > 0.01) { \n\
2347 vec3 ng = normalize(gradient); \n\
2348 float ndotv = abs(dot(normal_eye,ng)); \n\
2349 if( ndotv < fw_cosGradientThreshold ) { \n\
2350 voxel = mix(voxel,fw_edgeColor,1.0 -ndotv); \n\
2354 void PLUG_voxel_apply_EDGE (inout vec4 voxel, inout vec3 gradient) { \n\
2355 voxel_apply_EDGE(voxel, gradient); \n\
2357 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2358 voxel_apply_EDGE(voxel, gradient); \n\
2363 static const GLchar *plug_voxel_PROJECTION =
"\n\
2364 uniform float fw_intensityThreshold; \n\
2365 uniform int fw_projType; \n\
2366 float MAXPROJ = 0.0; \n\
2367 float MINPROJ = 1.0; \n\
2368 float AVEPROJ = 0.0; \n\
2369 float LMIP = 0.0; \n\
2371 int PROJCOUNT = 0; \n\
2372 void voxel_apply_PROJECTION (inout vec4 voxel, inout vec3 gradient) { \n\
2374 float cval = length(voxel.rgb); \n\
2375 if(fw_projType == 1){ \n\
2377 if(cval < MINPROJ){ \n\
2379 RGBAPROJ = voxel; \n\
2381 }else if(fw_projType == 2){ \n\
2383 if(fw_intensityThreshold > 0.0){ \n\
2385 if(LMIP == 0.0) { \n\
2387 RGBAPROJ = voxel; \n\
2391 if(cval > MAXPROJ){ \n\
2393 RGBAPROJ = voxel; \n\
2396 }else if(fw_projType==3){ \n\
2398 AVEPROJ += cval; \n\
2399 RGBAPROJ += voxel; \n\
2402 void PLUG_voxel_apply_PROJECTION (inout vec4 voxel, inout vec3 gradient) { \n\
2403 voxel_apply_PROJECTION(voxel, gradient); \n\
2405 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2406 voxel_apply_PROJECTION(voxel, gradient); \n\
2408 void PLUG_ray_apply (inout vec4 raysum) { \n\
2409 float value = 0.0; \n\
2410 vec4 color = vec4(1.0); \n\
2411 if(fw_projType == 1){ \n\
2413 value = MINPROJ; \n\
2414 color = RGBAPROJ; \n\
2415 }else if(fw_projType == 2){ \n\
2417 if(fw_intensityThreshold > 0.0){ \n\
2420 color = RGBAPROJ; \n\
2423 value = MAXPROJ; \n\
2424 color = RGBAPROJ; \n\
2426 }else if(fw_projType==3){ \n\
2428 value = AVEPROJ / float(PROJCOUNT); \n\
2429 color = RGBAPROJ / float(PROJCOUNT); \n\
2431 //raysum.rgb = color.rgb * color.a; \n\
2432 //raysum.a = color.a; \n\
2434 raysum.rgb = vec3(value,value,value); \n\
2435 // raysum.a = 1.0 - value; \n\
2436 //raysum.a = value;\n\
2437 //raysum.a = color.a; \n\
2438 //raysum = color; \n\
2443 static const GLchar *plug_voxel_SHADED =
"\
2445 #define MAX_LIGHTS 8 \n\
2446 uniform int lightcount; \n\
2447 //uniform float lightRadius[MAX_LIGHTS]; \n\
2448 uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
2449 struct fw_LightSourceParameters { \n\
2454 vec4 halfVector; \n\
2455 vec4 spotDirection; \n\
2456 float spotBeamWidth; \n\
2457 float spotCutoff; \n\
2458 vec3 Attenuations; \n\
2459 float lightRadius; \n\
2462 uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
2466 struct fogParams \n\
2469 float visibilityRange; \n\
2471 int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL \n\
2472 // ifdefed int haveFogCoords; \n\
2474 uniform fogParams fw_fogparams; \n\
2478 //per-fragment lighting ie phong \n\
2479 struct fw_MaterialParameters { \n\
2484 float shininess; \n\
2486 uniform fw_MaterialParameters fw_FrontMaterial; \n\
2488 uniform fw_MaterialParameters fw_BackMaterial; \n\
2490 vec3 castle_ColorES; \n\
2492 //per-vertex lighting - interpolated Emissive-specular \n\
2493 varying vec3 castle_ColorES; //emissive shininess term \n\
2496 uniform int fw_phase; \n\
2497 uniform int fw_lighting; \n\
2498 uniform int fw_shadows; \n\
2499 void voxel_apply_SHADED (inout vec4 voxel, inout vec3 gradient) { \n\
2500 float len = length(gradient); \n\
2501 vec3 ng = vec3(0.0); \n\
2503 ng = normalize(gradient); \n\
2504 vec4 color = vec4(1.0); \n\
2506 vec3 castle_ColorES = fw_FrontMaterial.specular.rgb; \n\
2507 color.rgb = fw_FrontMaterial.diffuse.rgb; \n\
2509 color.rgb = vec3(0,0,0.0,0.0); \n\
2510 vec3 castle_ColorES = vec3(0.0,0.0,0.0); \n\
2512 // void add_light_contribution2(inout vec4 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ); \n\
2513 vec4 vertex_eye4 = vec4(vertex_eye,1.0); \n\
2514 /* PLUG: add_light_contribution2 (color, castle_ColorES, vertex_eye4, ng, fw_FrontMaterial.shininess) */ \n\
2515 // voxel.rgb = color.rgb; \n\
2516 color.rgb = mix(color.rgb,castle_ColorES,dot(ng,normal_eye)); \n\
2517 voxel.rgb = color.rgb; \n\
2518 //voxel.rgb = voxel.rgb * color.rgb; \n\
2520 void PLUG_voxel_apply_SHADED (inout vec4 voxel, inout vec3 gradient) { \n\
2521 voxel_apply_SHADED(voxel, gradient); \n\
2523 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2524 voxel_apply_SHADED(voxel, gradient); \n\
2529 static const GLchar *plug_voxel_SILHOUETTE =
"\n\
2530 uniform float fw_BoundaryOpacity; \n\
2531 uniform float fw_RetainedOpacity; \n\
2532 uniform float fw_Sharpness; \n\
2533 void voxel_apply_SILHOUETTE (inout vec4 voxel, inout vec3 gradient) { \n\
2534 float len = length(gradient); \n\
2535 if(len > 0.01) { \n\
2536 vec3 ng = normalize(gradient); \n\
2537 float ndotv = abs(dot(ng,normal_eye)); \n\
2538 float factor = (fw_RetainedOpacity + fw_BoundaryOpacity*pow(1.0 - ndotv,fw_Sharpness)); \n\
2539 //float factor = (fw_RetainedOpacity + pow(fw_BoundaryOpacity*(1.0 - ndotv),fw_Sharpness)); \n\
2540 //debug_color = HeatMapColor(factor,0.0,1.0); \n\
2541 voxel.a = voxel.a * factor; \n\
2544 void PLUG_voxel_apply_SILHOUETTE (inout vec4 voxel, inout vec3 gradient) { \n\
2545 voxel_apply_SILHOUETTE(voxel, gradient); \n\
2547 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2548 voxel_apply_SILHOUETTE(voxel, gradient); \n\
2553 static const GLchar *plug_voxel_TONE =
"\
2554 uniform vec4 fw_coolColor; \n\
2555 uniform vec4 fw_warmColor; \n\
2556 void voxel_apply_TONE (inout vec4 voxel, inout vec3 gradient) { \n\
2557 float len = length(gradient); \n\
2560 vec3 ng = normalize(gradient); \n\
2561 //vec3 L = normalize(vec3(-.707,-.707,.707)); \n\
2562 float cc = (1.0 + dot(normal_eye,ng))*.5; \n\
2563 //float cc = (1.0 + dot(L,ng))*.5; \n\
2564 //debug_color = HeatMapColor(cc,0.0,1.0); \n\
2565 color = mix(fw_coolColor.rgb,fw_warmColor.rgb,cc); \n\
2566 voxel = vec4(color,voxel.a); \n\
2569 //debug_color = vec4(0.0); \n\
2572 void PLUG_voxel_apply_TONE (inout vec4 voxel, inout vec3 gradient) { \n\
2573 voxel_apply_TONE(voxel, gradient); \n\
2575 void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2576 voxel_apply_TONE(voxel, gradient); \n\
2587 static const GLchar *volumeBlendedFragmentGLES2 =
" \n\
2590 //precision highp float; \n\
2591 precision mediump float; \n\
2593 vec4 HeatMapColor(float value, float minValue, float maxValue) \n\
2595 //used for debugging. If min=0,max=1 then magenta is 0, blue,green,yellow, red is 1 \n\
2597 int HEATMAP_COLORS_COUNT; \n\
2599 HEATMAP_COLORS_COUNT = 6; \n\
2600 colors[0] = vec4(0.32, 0.00, 0.32, 1.0); \n\
2601 colors[1] = vec4( 0.00, 0.00, 1.00, 1.00); \n\
2602 colors[2] = vec4(0.00, 1.00, 0.00, 1.00); \n\
2603 colors[3] = vec4(1.00, 1.00, 0.00, 1.00); \n\
2604 colors[4] = vec4(1.00, 0.60, 0.00, 1.00); \n\
2605 colors[5] = vec4(1.00, 0.00, 0.00, 1.00); \n\
2606 float ratio=(float(HEATMAP_COLORS_COUNT)-1.0)*clamp((value-minValue)/(maxValue-minValue),0.0,1.0); \n\
2607 int indexMin=int(floor(ratio)); \n\
2608 int indexMax= indexMin+1 < HEATMAP_COLORS_COUNT-1 ? indexMin+1 : HEATMAP_COLORS_COUNT-1; \n\
2609 ret = mix(colors[indexMin], colors[indexMax], ratio-float(indexMin)); \n\
2610 if(value < minValue) ret = vec4(0.0,0.0,0.0,1.0); \n\
2611 if(value > maxValue) ret = vec4(1.0,1.0,1.0,1.0); \n\
2614 vec4 debug_color; \n\
2616 uniform vec4 fw_viewport; \n\
2617 uniform sampler2D fw_Texture_unit0; \n\
2618 uniform sampler2D fw_Texture_unit1; \n\
2619 uniform sampler2D fw_Texture_unit2; \n\
2620 uniform sampler2D fw_Texture_unit3; \n\
2621 uniform float fw_iwtc1; \n\
2622 uniform float fw_iwtc2; \n\
2623 uniform int fw_iwtf1; \n\
2624 uniform int fw_iwtf2; \n\
2625 uniform int fw_haveTransfers; \n\
2626 vec3 weightcolor( in vec3 color, in int func, in float wt, in float ov, in float oblend, in sampler2D table){ \n\
2629 ret = color * wt; \n\
2630 }else if(func == 2){ \n\
2631 ret = color * ov; \n\
2632 }else if(func == 3){ \n\
2633 ret = color * oblend; \n\
2634 }else if(func == 4){ \n\
2635 ret = color * (1.0 - oblend); \n\
2636 }else if(func == 5){ \n\
2637 vec2 texcoord = color.rg;\n\
2638 ret = color * texture2D(table,texcoord).r; \n\
2642 float weightalpha( in float alpha, in int func, in float wt, in float ov, in float oblend, in sampler2D table){ \n\
2645 ret = alpha * wt; \n\
2646 }else if(func == 2){ \n\
2647 ret = alpha * ov; \n\
2648 }else if(func == 3){ \n\
2649 ret = alpha * oblend; \n\
2650 }else if(func == 4){ \n\
2651 ret = alpha * (1.0 - oblend); \n\
2652 }else if(func == 5){ \n\
2653 vec2 texcoord = vec2(alpha,0);\n\
2654 ret = alpha * texture2D(table,texcoord).r; \n\
2660 vec2 fc = (gl_FragCoord.xy - fw_viewport.xy) / fw_viewport.zw; \n\
2661 vec4 frag0 = texture2D(fw_Texture_unit0,fc); \n\
2662 vec4 frag1 = texture2D(fw_Texture_unit1,fc); \n\
2663 vec3 cv = frag0.rgb; \n\
2664 float ov = frag0.a; \n\
2665 vec3 cblend = frag1.rgb; \n\
2666 float oblend = frag1.a; \n\
2669 cvw = weightcolor(cv,fw_iwtf1,fw_iwtc1,ov,oblend,fw_Texture_unit2); \n\
2670 ovw = weightalpha(ov,fw_iwtf1,fw_iwtc1,ov,oblend,fw_Texture_unit2); \n\
2671 cbw = weightcolor(cblend,fw_iwtf2,fw_iwtc2,ov,oblend,fw_Texture_unit3); \n\
2672 obw = weightalpha(oblend,fw_iwtf2,fw_iwtc2,ov,oblend,fw_Texture_unit3); \n\
2673 vec3 cg = clamp( cvw + cbw, 0.0, 1.0); \n\
2674 float og = clamp(ovw + obw, 0.0, 1.0); \n\
2676 gl_FragColor = vec4(cg,og); \n\
2681 const char *getVolumeVertex(
void){
2682 return volumeVertexGLES2;
2684 const char *getVolumeFragment(){
2685 return volumeFragmentGLES2;
2687 int getSpecificShaderSourceVolume (
const GLchar **vertexSource,
const GLchar **fragmentSource,
shaderflagsstruct whichOne)
2693 int retval, unique_int;
2694 unsigned int volflags;
2695 unsigned char volflag[7];
2697 char *CompleteCode[3];
2700 if(whichOne.usershaders )
2705 vs = strdup(getVolumeVertex());
2706 fs = strdup(getVolumeFragment());
2708 CompleteCode[SHADERPART_VERTEX] = vs;
2709 CompleteCode[SHADERPART_GEOMETRY] = NULL;
2710 if(whichOne.volume == SHADERFLAGS_VOLUME_STYLE_BLENDED << 4){
2711 CompleteCode[SHADERPART_FRAGMENT] = STRDUP(volumeBlendedFragmentGLES2);
2714 CompleteCode[SHADERPART_FRAGMENT] = fs;
2723 AddVersion(SHADERPART_VERTEX, 100, CompleteCode);
2724 AddVersion(SHADERPART_FRAGMENT, 100, CompleteCode);
2725 AddDefine(SHADERPART_FRAGMENT,
"MOBILE",CompleteCode);
2728 AddVersion(SHADERPART_VERTEX, 110, CompleteCode);
2729 AddVersion(SHADERPART_FRAGMENT, 110, CompleteCode);
2732 if(whichOne.volume == SHADERFLAGS_VOLUME_STYLE_BLENDED << 4){
2733 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
2734 *vertexSource = CompleteCode[SHADERPART_VERTEX];
2741 AddDefine(SHADERPART_FRAGMENT,
"TEX3D",CompleteCode);
2742 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3D_apply_volume,CompleteCode,&unique_int);
2745 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_BASIC)){
2746 AddDefine(SHADERPART_FRAGMENT,
"BASIC",CompleteCode);
2748 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_ISO)){
2749 AddDefine(SHADERPART_FRAGMENT,
"ISO",CompleteCode);
2750 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_ISO_MODE3)){
2751 AddDefine(SHADERPART_FRAGMENT,
"ISO_MODE3",CompleteCode);
2754 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_SEGMENT)){
2755 AddDefine(SHADERPART_FRAGMENT,
"SEGMENT",CompleteCode);
2757 if(DESIRE(whichOne.base,CLIPPLANE_SHADER)){
2758 AddDefine(SHADERPART_FRAGMENT,
"CLIP",CompleteCode);
2764 volflags = whichOne.volume;
2768 int iflag = (volflags >> (7-i)*4) & 0xF;
2770 volflag[kflags] = iflag;
2775 for(k=0;k<kflags;k++){
2777 case SHADERFLAGS_VOLUME_STYLE_DEFAULT:
2778 AddDefine(SHADERPART_FRAGMENT,
"DEFAULT",CompleteCode);
2779 Plug(SHADERPART_FRAGMENT,plug_voxel_DEFAULT,CompleteCode,&unique_int);
2781 case SHADERFLAGS_VOLUME_STYLE_OPACITY:
2782 AddDefine(SHADERPART_FRAGMENT,
"OPACITY",CompleteCode);
2783 Plug(SHADERPART_FRAGMENT,plug_voxel_OPACITY,CompleteCode,&unique_int);
2785 case SHADERFLAGS_VOLUME_STYLE_BLENDED:
2786 AddDefine(SHADERPART_FRAGMENT,
"BLENDED",CompleteCode);
2787 Plug(SHADERPART_FRAGMENT,plug_voxel_BLENDED,CompleteCode,&unique_int);
2789 case SHADERFLAGS_VOLUME_STYLE_BOUNDARY:
2790 AddDefine(SHADERPART_FRAGMENT,
"BOUNDARY",CompleteCode);
2791 Plug(SHADERPART_FRAGMENT,plug_voxel_BOUNDARY,CompleteCode,&unique_int);
2793 case SHADERFLAGS_VOLUME_STYLE_CARTOON:
2794 AddDefine(SHADERPART_FRAGMENT,
"CARTOON",CompleteCode);
2795 Plug(SHADERPART_FRAGMENT,plug_voxel_CARTOON,CompleteCode,&unique_int);
2797 case SHADERFLAGS_VOLUME_STYLE_COMPOSED:
2798 AddDefine(SHADERPART_FRAGMENT,
"COMPOSED",CompleteCode);
2799 Plug(SHADERPART_FRAGMENT,plug_voxel_COMPOSED,CompleteCode,&unique_int);
2801 case SHADERFLAGS_VOLUME_STYLE_EDGE:
2802 AddDefine(SHADERPART_FRAGMENT,
"EDGE",CompleteCode);
2803 Plug(SHADERPART_FRAGMENT,plug_voxel_EDGE,CompleteCode,&unique_int);
2805 case SHADERFLAGS_VOLUME_STYLE_PROJECTION:
2806 AddDefine(SHADERPART_FRAGMENT,
"PROJECTION",CompleteCode);
2807 Plug(SHADERPART_FRAGMENT,plug_voxel_PROJECTION,CompleteCode,&unique_int);
2809 case SHADERFLAGS_VOLUME_STYLE_SHADED:
2810 AddDefine(SHADERPART_FRAGMENT,
"SHADED",CompleteCode);
2811 Plug(SHADERPART_FRAGMENT,plug_voxel_SHADED,CompleteCode,&unique_int);
2814 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
2815 AddDefine(SHADERPART_FRAGMENT,
"LITE",CompleteCode);
2816 Plug(SHADERPART_FRAGMENT,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
2818 case SHADERFLAGS_VOLUME_STYLE_SILHOUETTE:
2819 AddDefine(SHADERPART_FRAGMENT,
"SILHOUETTE",CompleteCode);
2820 Plug(SHADERPART_FRAGMENT,plug_voxel_SILHOUETTE,CompleteCode,&unique_int);
2822 case SHADERFLAGS_VOLUME_STYLE_TONE:
2823 AddDefine(SHADERPART_FRAGMENT,
"TONE",CompleteCode);
2824 Plug(SHADERPART_FRAGMENT,plug_voxel_TONE,CompleteCode,&unique_int);
2836 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
2837 *vertexSource = CompleteCode[SHADERPART_VERTEX];