44#include <system_threads.h>
49#include <libFreeWRL.h>
66char *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);
91void removeAt(
char *here,
int len){
93 int wholelen, movesize;
95 wholelen = strlen(here) + 1;
97 movesize = wholelen - len;
98 memmove(here,source,movesize);
101void 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';
124int 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);
191void 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);
204void 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
223#define PBUFSIZE 16384
224int fw_strcpy_s(
char *dest,
int destsize,
const char *source){
227 if(source && strlen(source) < (
unsigned)destsize){
233int fw_strcat_s(
char *dest,
int destsize,
const char *source){
236 int destlen = strlen(dest);
238 if(strlen(source)+destlen < (
unsigned)destsize){
245void 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);
341void 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);
360void 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);
380void AddDefine(
int EffectPartType,
const char *defineName,
char **CompleteCode){
383 AddDefine0(EffectPartType,defineName,1,CompleteCode);
396void 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);
416Stack *getEffectStack();
417void 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);
476static const GLchar *genericVertexGLES2 =
"\
478/* Generic GLSL vertex shader, used on OpenGL ES. */ \n\
480uniform mat4 fw_ModelViewMatrix; \n\
481uniform mat4 fw_ProjectionMatrix; \n\
482uniform mat3 fw_NormalMatrix; \n\
484uniform mat4 fw_ModelViewInverseMatrix; \n\
486attribute vec4 fw_Vertex; \n\
487attribute vec3 fw_Normal; \n\
490uniform mat4 fw_TextureMatrix0; \n\
491attribute vec4 fw_MultiTexCoord0; \n\
492//varying vec3 v_texC; \n\
493varying vec3 fw_TexCoord[4]; \n\
495uniform int tex3dUseVertex; \n\
498uniform mat4 fw_TextureMatrix1; \n\
499uniform mat4 fw_TextureMatrix2; \n\
500uniform mat4 fw_TextureMatrix3; \n\
501attribute vec4 fw_MultiTexCoord1; \n\
502attribute vec4 fw_MultiTexCoord2; \n\
503attribute 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\
521varying vec2 hatchPosition; \n\
524/* PLUG-DECLARATIONS */ \n\
526varying vec4 castle_vertex_eye; \n\
527varying vec3 castle_normal_eye; \n\
528varying 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\
539uniform int lightcount; \n\
540//uniform float lightRadius[MAX_LIGHTS]; \n\
541uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
542struct fw_LightSourceParameters { \n\
548 vec4 spotDirection; \n\
549 float spotBeamWidth; \n\
550 float spotCutoff; \n\
551 vec3 Attenuations; \n\
552 float lightRadius; \n\
555uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
558//uniform vec3 castle_SceneColor; \n\
559//uniform vec4 castle_UnlitColor; \n\
561uniform vec4 fw_UnlitColor; \n\
564struct fw_MaterialParameters { \n\
571uniform fw_MaterialParameters fw_FrontMaterial; \n\
572varying vec3 castle_ColorES; //emissive shininess term \n\
573vec3 castle_Emissive; \n\
575uniform 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\
587uniform fogParams fw_fogparams; \n\
589attribute float fw_FogCoords; \n\
592float castle_MaterialDiffuseAlpha; \n\
593float castle_MaterialShininess; \n\
594vec3 castle_SceneColor; \n\
595vec4 castle_UnlitColor; \n\
596vec4 castle_Specular; \n\
599attribute vec4 fw_Color; //castle_ColorPerVertex; \n\
600varying vec4 cpv_Color; \n\
603uniform vec3 particlePosition; \n\
604uniform int fw_ParticleGeomType; \n\
607uniform mat4 projTexGenMatCam[8]; \n\
608uniform int pCount; \n\
609varying vec4 projTexCoord[8]; \n\
610varying vec4 projTexNorm[8]; \n\
611void vertProjCalTexCoord(void) { \n\
612 for(int i=0;i<pCount;i++){ \n\
613 projTexCoord[i] = projTexGenMatCam[i] * castle_vertex_eye; \n\
614 projTexNorm[i] = projTexGenMatCam[i] * vec4((castle_vertex_eye.xyz + castle_normal_eye.xyz),1.0); \n\
619 vec3 dehomogenize(in mat4 matrix, in vec4 vector){ \n\
620 vec4 tempv = vector; \n\
621 if(tempv.w == 0.0) tempv.w = 1.0; \n\
622 vec4 temp = matrix * tempv; \n\
623 float winv = 1.0/temp.w; \n\
624 return temp.xyz * winv; \n\
629 castle_MaterialDiffuseAlpha = fw_FrontMaterial.diffuse.a; \n\
632 //to modulate or not to modulate, this is the question \n\
633 //in here, we turn off modulation and use image alpha \n\
634 castle_MaterialDiffuseAlpha = 1.0; \n\
637 castle_MaterialShininess = fw_FrontMaterial.shininess; \n\
638 castle_SceneColor = fw_FrontMaterial.ambient.rgb; \n\
639 castle_Specular = fw_FrontMaterial.specular; \n\
640 castle_Emissive = fw_FrontMaterial.emission.rgb; \n\
642 castle_SceneColor = vec3(0.0,0.0,0.0); //line gets color from castle_Emissive \n\
645 //default unlits in case we dont set them \n\
646 castle_UnlitColor = vec4(1.0,1.0,1.0,1.0); \n\
647 castle_MaterialDiffuseAlpha = 1.0; \n\
651 hatchPosition = fw_Vertex.xy; \n\
654 vec4 vertex_object = fw_Vertex; \n\
656 if(fw_ParticleGeomType != 4){ \n\
657 vertex_object.xyz += particlePosition; \n\
659 #endif //PARTICLE \n\
660 vec3 normal_object = fw_Normal; \n\
661 /* PLUG: vertex_object_space_change (vertex_object, normal_object) */ \n\
662 /* PLUG: vertex_object_space (vertex_object, normal_object) */ \n\
664 #ifdef CASTLE_BUGGY_GLSL_READ_VARYING \n\
665 /* use local variables, instead of reading + writing to varying variables, \n\
666 when VARYING_NOT_READABLE */ \n\
667 vec4 temp_castle_vertex_eye; \n\
668 vec3 temp_castle_normal_eye; \n\
669 vec4 temp_castle_Color; \n\
670 #define castle_vertex_eye temp_castle_vertex_eye \n\
671 #define castle_normal_eye temp_castle_normal_eye \n\
672 #define castle_Color temp_castle_Color \n\
673 #endif //CASTLE_BUGGY_GLSL_READ_VARYING \n\
675 castle_vertex_eye = fw_ModelViewMatrix * vertex_object; \n\
677 //sprite: align to viewer \n\
678 if(fw_ParticleGeomType == 4){ \n\
679 vec4 ppos = vec4(particlePosition,1.0); \n\
680 vec4 particle_eye = fw_ModelViewMatrix * ppos; \n\
682 vec4 particle_eye1 = fw_ModelViewMatrix * ppos; \n\
683 float pscal = length(particle_eye1.xyz - particle_eye.xyz); \n\
684 castle_vertex_eye = particle_eye + pscal*vertex_object; \n\
686 #endif //PARTICLE \n\
687 castle_normal_eye = normalize(fw_NormalMatrix * normal_object); \n\
689 vertProjCalTexCoord(); \n\
690 #endif //PROJETEX \n\
692 /* PLUG: vertex_eye_space (castle_vertex_eye, castle_normal_eye) */ \n\
695 castle_ColorES = castle_Emissive; \n\
696 castle_Color = vec4(castle_SceneColor, 1.0); \n\
697 /* PLUG: add_light_contribution2 (castle_Color, castle_ColorES, castle_vertex_eye, castle_normal_eye, castle_MaterialShininess) */ \n\
698 /* PLUG: add_light_contribution (castle_Color, castle_vertex_eye, castle_normal_eye, castle_MaterialShininess) */ \n\
699 castle_Color.a = castle_MaterialDiffuseAlpha; \n\
700 /* Clamp sum of lights colors to be <= 1. See template.fs for comments. */ \n\
701 castle_Color.rgb = min(castle_Color.rgb, 1.0); \n\
703 castle_Color.rgb = castle_UnlitColor.rgb; \n\
706 #ifdef CPV //color per vertex \n\
707 cpv_Color = fw_Color; \n\
711 vec4 texcoord = fw_MultiTexCoord0; \n\
713 //to re-use vertex coords as texturecoords3D, we need them in 0-1 range: CPU calc of fw_TextureMatrix0 \n\
714 if(tex3dUseVertex == 1) \n\
715 texcoord = vec4(fw_Vertex.xyz,1.0); \n\
721 vec3 texcoord3 = texcoord.xyz; \n\
722 vertexNorm = normalize(fw_NormalMatrix * fw_Normal); \n\
723 vertexPos = fw_ModelViewMatrix * fw_Vertex; \n\
724 /* sphereEnvironMapping Calculation */ \n\
725 vec3 u=normalize(vec3(vertexPos)); /* u is normalized position, used below more than once */ \n\
726 vec3 r= reflect(u,vertexNorm); \n\
727 if (fw_textureCoordGenType==TCGT_SPHERE) { /* TCGT_SPHERE GL_SPHERE_MAP OpenGL Equiv */ \n\
728 float m=2.0 * sqrt(r.x*r.x + r.y*r.y + (r.z*1.0)*(r.z*1.0)); \n\
729 texcoord3 = vec3(r.x/m+0.5,r.y/m+0.5,0.0); \n\
730 }else if (fw_textureCoordGenType==TCGT_CAMERASPACENORMAL) { \n\
731 /* GL_REFLECTION_MAP used for sampling cubemaps */ \n\
732 float dotResult = 2.0 * dot(u,r); \n\
733 texcoord3 = vec3(u-r)*dotResult; \n\
734 }else if (fw_textureCoordGenType==TCGT_COORD) { \n\
735 /* 3D textures can use coords in 0-1 range */ \n\
736 texcoord3 = fw_Vertex.xyz; //xyz; \n\
737 } else { /* default usage - like default CubeMaps */ \n\
738 vec3 u=normalize(vec3(fw_ProjectionMatrix * fw_Vertex)); /* myEyeVertex */ \n\
739 texcoord3 = reflect(u,vertexNorm); \n\
741 texcoord.xyz = texcoord3; \n\
744 fw_TexCoord[0] = dehomogenize(fw_TextureMatrix0, texcoord); \n\
746 fw_TexCoord[1] = dehomogenize(fw_TextureMatrix1,fw_MultiTexCoord1); \n\
747 fw_TexCoord[2] = dehomogenize(fw_TextureMatrix2,fw_MultiTexCoord2); \n\
748 fw_TexCoord[3] = dehomogenize(fw_TextureMatrix3,fw_MultiTexCoord3); \n\
752 gl_Position = fw_ProjectionMatrix * castle_vertex_eye; \n\
756 vec4 camera = fw_ModelViewInverseMatrix * vec4(0.0,0.0,0.0,1.0); \n\
757 //vec3 u = normalize( vec4(castle_vertex_eye - camera).xyz ); \n\
758 vec3 u = normalize( vec4(vertex_object + camera).xyz ); \n\
759 vec3 v = normalize(fw_Normal); \n\
760 fw_TexCoord[0] = normalize(reflect(u,v)); //computed in object space \n\
761 fw_TexCoord[0].st = -fw_TexCoord[0].st; //helps with renderman cubemap convention \n\
763 #ifdef CASTLE_BUGGY_GLSL_READ_VARYING \n\
764 #undef castle_vertex_eye \n\
765 #undef castle_normal_eye \n\
766 #undef castle_Color \n\
767 castle_vertex_eye = temp_castle_vertex_eye; \n\
768 castle_normal_eye = temp_castle_normal_eye; \n\
769 castle_Color = temp_castle_Color; \n\
770 #endif //CASTLE_BUGGY_GLSL_READ_VARYING \n\
774 castle_vertex_eye.z = fw_FogCoords; \n\
775 #endif //FOGCOORD \n\
778 castle_Color = fw_UnlitColor; \n\
815static const GLchar *genericFragmentGLES2 =
"\
818//precision highp float; \n\
819precision mediump float; \n\
821/* Generic GLSL fragment shader, used on OpenGL ES. */ \n\
823varying vec4 castle_Color; \n\
826#define MAX_LIGHTS 8 \n\
827uniform int lightcount; \n\
828//uniform float lightRadius[MAX_LIGHTS]; \n\
829uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
830struct fw_LightSourceParameters { \n\
836 vec4 spotDirection; \n\
837 float spotBeamWidth; \n\
838 float spotCutoff; \n\
839 vec3 Attenuations; \n\
840 float lightRadius; \n\
843uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
847varying vec4 cpv_Color; \n\
852uniform samplerCube fw_Texture_unit0; \n\
854uniform sampler2D fw_Texture_unit0; \n\
856varying vec3 fw_TexCoord[4]; \n\
858uniform int tex3dTiles[3]; \n\
859uniform int repeatSTR[3]; \n\
860uniform int magFilter; \n\
863uniform sampler2D fw_Texture_unit1; \n\
864uniform sampler2D fw_Texture_unit2; \n\
865uniform sampler2D fw_Texture_unit3; \n\
866uniform int textureCount; \n\
868#if defined(MTEX) || defined(PROJTEX) \n\
869uniform sampler2D fw_Texture_unit1; \n\
870uniform sampler2D fw_Texture_unit2; \n\
871uniform sampler2D fw_Texture_unit3; \n\
872uniform ivec2 fw_Texture_mode0; \n\
873uniform ivec2 fw_Texture_mode1; \n\
874uniform ivec2 fw_Texture_mode2; \n\
875uniform ivec2 fw_Texture_mode3; \n\
876uniform ivec2 fw_Texture_source0; \n\
877uniform ivec2 fw_Texture_source1; \n\
878uniform ivec2 fw_Texture_source2; \n\
879uniform ivec2 fw_Texture_source3; \n\
880uniform int fw_Texture_function0; \n\
881uniform int fw_Texture_function1; \n\
882uniform int fw_Texture_function2; \n\
883uniform int fw_Texture_function3; \n\
884uniform int textureCount; \n\
885uniform vec4 mt_Color; \n\
886#define MTMODE_ADD 1\n \
887#define MTMODE_ADDSIGNED 2\n \
888#define MTMODE_ADDSIGNED2X 3\n \
889#define MTMODE_ADDSMOOTH 4\n \
890#define MTMODE_BLENDCURRENTALPHA 5\n \
891#define MTMODE_BLENDDIFFUSEALPHA 6\n \
892#define MTMODE_BLENDFACTORALPHA 7\n \
893#define MTMODE_BLENDTEXTUREALPHA 8\n \
894#define MTMODE_DOTPRODUCT3 9\n \
895#define MTMODE_MODULATE 10\n \
896#define MTMODE_MODULATE2X 11\n \
897#define MTMODE_MODULATE4X 12\n \
898#define MTMODE_MODULATEALPHA_ADDCOLOR 13\n \
899#define MTMODE_MODULATEINVALPHA_ADDCOLOR 14\n \
900#define MTMODE_MODULATEINVCOLOR_ADDALPHA 15\n \
901#define MTMODE_OFF 16\n \
902#define MTMODE_REPLACE 17\n \
903#define MTMODE_SELECTARG1 18\n \
904#define MTMODE_SELECTARG2 19\n \
905#define MTMODE_SUBTRACT 20\n \
906#define MTSRC_DIFFUSE 1 \n\
907#define MTSRC_FACTOR 2 \n\
908#define MTSRC_SPECULAR 3 \n\
909#define MTFN_ALPHAREPLICATE 0 \n\
910#define MTFN_COMPLEMENT 1 \n\
911#define MT_DEFAULT -1 \n\
913void finalColCalc(inout vec4 prevColour, in int mode, in int modea, in int func, in sampler2D tex, in vec2 texcoord) { \n\
914 vec4 texel = texture2D(tex,texcoord); \n\
915 vec4 rv = vec4(1.,0.,1.,1.); \n\
916 if (mode==MTMODE_OFF) { \n\
917 rv = vec4(prevColour); \n\
918 } else if (mode==MTMODE_REPLACE) { \n\
919 rv = vec4(texture2D(tex, texcoord)); \n\
920 }else if (mode==MTMODE_MODULATE) { \n\
923 cf = prevColour.rgb; \n\
924 af = prevColour.a; \n\
927 rv = vec4(ct*cf, at*af); \n\
928 } else if (mode==MTMODE_MODULATE2X) { \n\
931 cf = prevColour.rgb; \n\
932 af = prevColour.a; \n\
935 rv = vec4(vec4(ct*cf, at*af)*vec4(2.,2.,2.,2.)); \n\
936 }else if (mode==MTMODE_MODULATE4X) { \n\
939 cf = prevColour.rgb; \n\
940 af = prevColour.a; \n\
943 rv = vec4(vec4(ct*cf, at*af)*vec4(4.,4.,4.,4.)); \n\
944 }else if (mode== MTMODE_ADDSIGNED) { \n\
945 rv = vec4 (prevColour + texel - vec4 (0.5, 0.5, 0.5, -.5)); \n\
946 } else if (mode== MTMODE_ADDSIGNED2X) { \n\
947 rv = vec4 ((prevColour + texel - vec4 (0.5, 0.5, 0.5, -.5))*vec4(2.,2.,2.,2.)); \n\
948 } else if (mode== MTMODE_ADD) { \n\
949 rv= vec4 (prevColour + texel); \n\
950 } else if (mode== MTMODE_SUBTRACT) { \n\
951 rv = vec4 (texel - prevColour); //jas had prev - tex \n\
952 } else if (mode==MTMODE_ADDSMOOTH) { \n\
953 rv = vec4 (prevColour + (prevColour - vec4 (1.,1.,1.,1.)) * texel); \n\
954 } else if (mode==MTMODE_BLENDDIFFUSEALPHA) { \n\
955 rv = vec4 (mix(prevColour,texel,castle_Color.a)); \n\
956 } else if (mode==MTMODE_BLENDTEXTUREALPHA) { \n\
957 rv = vec4 (mix(prevColour,texel,texel.a)); \n\
958 } else if (mode==MTMODE_BLENDFACTORALPHA) { \n\
959 rv = vec4 (mix(prevColour,texel,mt_Color.a)); \n\
960 } else if (mode==MTMODE_BLENDCURRENTALPHA) { \n\
961 rv = vec4 (mix(prevColour,texel,prevColour.a)); \n\
962 } else if (mode==MTMODE_SELECTARG1) { \n\
964 } else if (mode==MTMODE_SELECTARG2) { \n\
968 if (modea==MTMODE_OFF) { \n\
969 rv.a = prevColour.a; \n\
970 } else if (modea==MTMODE_REPLACE) { \n\
972 }else if (modea==MTMODE_MODULATE) { \n\
974 af = prevColour.a; \n\
977 } else if (modea==MTMODE_MODULATE2X) { \n\
979 af = prevColour.a; \n\
981 rv.a = at*af*2.0; \n\
982 }else if (modea==MTMODE_MODULATE4X) { \n\
984 af = prevColour.a; \n\
986 rv.a = at*af*4.0; \n\
987 }else if (modea== MTMODE_ADDSIGNED) { \n\
988 rv.a = (prevColour.a + texel.a + .5); \n\
989 } else if (modea== MTMODE_ADDSIGNED2X) { \n\
990 rv.a = ((prevColour.a + texel.a + .5))*2.0; \n\
991 } else if (modea== MTMODE_ADD) { \n\
992 rv.a = prevColour.a + texel.a; \n\
993 } else if (modea== MTMODE_SUBTRACT) { \n\
994 rv.a = texel.a - prevColour.a; //jas had prev - texel \n\
995 } else if (modea==MTMODE_ADDSMOOTH) { \n\
996 rv.a = (prevColour.a + (prevColour.a - 1.)) * texel.a; \n\
997 } else if (modea==MTMODE_BLENDDIFFUSEALPHA) { \n\
998 rv.a = mix(prevColour.a,texel.a,castle_Color.a); \n\
999 } else if (modea==MTMODE_BLENDTEXTUREALPHA) { \n\
1000 rv.a = mix(prevColour.a,texel.a,texel.a); \n\
1001 } else if (modea==MTMODE_BLENDFACTORALPHA) { \n\
1002 rv.a = mix(prevColour.a,texel.a,mt_Color.a); \n\
1003 } else if (modea==MTMODE_BLENDCURRENTALPHA) { \n\
1004 rv.a = mix(prevColour.a,texel.a,prevColour.a); \n\
1005 } else if (modea==MTMODE_SELECTARG1) { \n\
1007 } else if (modea==MTMODE_SELECTARG2) { \n\
1008 rv.a = prevColour.a; \n\
1011 if(func == MTFN_COMPLEMENT){ \n\
1012 //rv = vec4(1.0,1.0,1.0,1.0) - rv; \n\
1013 rv = vec4( vec3(1.0,1.0,1.0) - rv.rgb, rv.a); \n\
1014 }else if(func == MTFN_ALPHAREPLICATE){ \n\
1015 rv = vec4(rv.a,rv.a,rv.a,rv.a); \n\
1017 prevColour = rv; \n\
1022uniform vec4 HatchColour; \n\
1023uniform bool hatched; uniform bool filled;\n\
1024uniform vec2 HatchScale; \n\
1025uniform vec2 HatchPct; \n\
1026uniform int algorithm; \n\
1027varying vec2 hatchPosition; \n\
1028void fillPropCalc(inout vec4 prevColour, vec2 MCposition, int algorithm) { \n\
1030 vec2 position, useBrick; \n\
1032 position = MCposition / HatchScale; \n\
1034 if (algorithm == 0) {/* bricking */ \n\
1035 if (fract(position.y * 0.5) > 0.5) \n\
1036 position.x += 0.5; \n\
1039 /* algorithm 1, 2 = no futzing required here */ \n\
1040 if (algorithm == 3) { /* positive diagonals */ \n\
1041 vec2 curpos = position; \n\
1042 position.x -= curpos.y; \n\
1045 if (algorithm == 4) { /* negative diagonals */ \n\
1046 vec2 curpos = position; \n\
1047 position.x += curpos.y; \n\
1050 if (algorithm == 6) { /* diagonal crosshatch */ \n\
1051 vec2 curpos = position; \n\
1052 if (fract(position.y) > 0.5) { \n\
1053 if (fract(position.x) < 0.5) position.x += curpos.y; \n\
1054 else position.x -= curpos.y; \n\
1056 if (fract(position.x) > 0.5) position.x += curpos.y; \n\
1057 else position.x -= curpos.y; \n\
1061 position = fract(position); \n\
1063 useBrick = step(position, HatchPct); \n\
1065 if (filled) {colour = prevColour;} else { colour=vec4(0.,0.,0.,0); }\n\
1067 colour = mix(HatchColour, colour, useBrick.x * useBrick.y); \n\
1069 prevColour = colour; \n\
1076 float visibilityRange; \n\
1078 int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL \n\
1079 // ifdefed int haveFogCoords; \n\
1081uniform fogParams fw_fogparams; \n\
1084/* PLUG-DECLARATIONS */ \n\
1086#ifdef HAS_GEOMETRY_SHADER \n\
1087#define castle_vertex_eye castle_vertex_eye_geoshader \n\
1088#define castle_normal_eye castle_normal_eye_geoshader \n\
1091varying vec4 castle_vertex_eye; \n\
1092varying vec3 castle_normal_eye; \n\
1095//per-fragment lighting ie phong \n\
1096struct fw_MaterialParameters { \n\
1101 float shininess; \n\
1103uniform fw_MaterialParameters fw_FrontMaterial; \n\
1105uniform fw_MaterialParameters fw_BackMaterial; \n\
1107vec3 castle_ColorES; \n\
1109//per-vertex lighting - interpolated Emissive-specular \n\
1110varying vec3 castle_ColorES; //emissive shininess term \n\
1115uniform sampler2D textureUnit[4]; \n\
1117uniform int pbackCull[8]; \n\
1118uniform int ntdesc[8]; \n\
1119uniform int pCount; \n\
1120varying vec4 projTexCoord[8]; \n\
1121varying vec4 projTexNorm[8]; \n\
1122//per texture descriptor (projector 1:m texdescriptor m:1 sampler): \n\
1123uniform int tunits[16]; \n\
1124uniform int modes[16]; \n\
1125uniform int sources[16]; \n\
1126uniform int funcs[16]; \n\
1127vec4 fragProjCalTexCoord(in vec4 frag_color) { \n\
1129 for(int i=0;i<pCount;i++) { \n\
1130 if( projTexCoord[i].q > 0.0 ){ \n\
1131 vec4 pp = projTexCoord[i]; \n\
1132 bool inside = (-pp.w < pp.x) && (pp.x < pp.w); \n\
1133 inside = inside && (-pp.w < pp.y) && (pp.y < pp.w); \n\
1134 inside = inside && (-pp.w < pp.z) && (pp.z < pp.w); \n\
1136 bool facingProjector = true; \n\
1137 vec3 pptex = pp.xyz/pp.w; \n\
1138 if(pbackCull[i] == 1){ \n\
1139 vec3 pn = projTexNorm[i].xyz/projTexNorm[i].w; \n\
1140 vec3 nvec = normalize(pptex.xyz-pn); \n\
1141 vec3 peye = vec3(0.0,0.0,1.0); //normalize(pc); \n\
1142 float dotval = dot(nvec,peye); \n\
1143 facingProjector = (dotval > 0.0); \n\
1145 if(facingProjector){ \n\
1146 //parallel/ortho \n\
1147 vec2 ptex = pptex.xy; \n\
1148 ptex.x = (ptex.x * .5) + .5; \n\
1149 ptex.y = (ptex.y * .5) + .5; \n\
1150 int ndesc = ntdesc[i]; \n\
1151 vec4 prev = frag_color; \n\
1152 for(int j=0;j<ndesc;j++,k++){ \n\
1153 int kk = tunits[k]; \n\
1154 int modea = int(modes[k] / 100); \n\
1155 int mode = modes[k] - 100*modea; \n\
1156 finalColCalc(prev, mode, modea, funcs[k], textureUnit[kk], ptex); \n\
1157 //vec4 pcolor = texture2D(textureUnit[i], ptex.xy); \n\
1158 //frag_color = (vec4(.5, .5, .5, .5) + frag_color)*pcolor; //modulate + add \n\
1160 frag_color = prev;\n\
1165 return frag_color; \n\
1168/* Wrapper for calling PLUG texture_coord_shift */ \n\
1169vec2 texture_coord_shifted(in vec2 tex_coord) \n\
1171 /* PLUG: texture_coord_shift (tex_coord) */ \n\
1172 return tex_coord; \n\
1175vec4 matdiff_color; \n\
1178 vec4 fragment_color = vec4(1.0,1.0,1.0,1.0); \n\
1179 matdiff_color = castle_Color; \n\
1180 float castle_MaterialDiffuseAlpha = castle_Color.a; \n\
1183 //per-fragment lighting aka PHONG \n\
1184 //start over with the color, since we have material and lighting in here \n\
1185 castle_MaterialDiffuseAlpha = fw_FrontMaterial.diffuse.a; \n\
1186 matdiff_color = vec4(0,0,0,1.0); \n\
1187 castle_ColorES = fw_FrontMaterial.emission.rgb; \n\
1188 /* PLUG: add_light_contribution2 (matdiff_color, castle_ColorES, castle_vertex_eye, castle_normal_eye, fw_FrontMaterial.shininess) */ \n\
1193 fragment_color.rgb = matdiff_color.rgb; \n\
1197 fragment_color = castle_Color; \n\
1202 fragment_color = cpv_Color; //CPV replaces mat.diffuse prior \n\
1203 fragment_color.a *= castle_MaterialDiffuseAlpha; \n\
1205 fragment_color *= cpv_Color; //CPV modulates prior \n\
1211 fragment_color = vec4(1.0,1.0,1.0,1.0); //texture replaces prior \n\
1215 /* Fragment shader on mobile doesn't get a normal vector now, for speed. */ \n\
1216 //#define normal_eye_fragment castle_normal_eye //vec3(0.0) \n\
1217 #define normal_eye_fragment vec3(0.0) \n\
1220 fillPropCalc(matdiff_color, hatchPosition, algorithm); \n\
1225 //modulate texture with mat.diffuse \n\
1226 fragment_color.rgb *= matdiff_color.rgb; \n\
1227 fragment_color.a *= castle_MaterialDiffuseAlpha; \n\
1229 fragment_color.rgb = clamp(fragment_color.rgb + castle_ColorES, 0.0, 1.0); \n\
1232 /* PLUG: texture_apply (fragment_color, normal_eye_fragment) */ \n\
1233 /* PLUG: steep_parallax_shadow_apply (fragment_color) */ \n\
1234 /* PLUG: fog_apply (fragment_color, normal_eye_fragment) */ \n\
1236 fragment_color = fragProjCalTexCoord(fragment_color); \n\
1237 #endif //PROJTEX \n\
1239 #undef normal_eye_fragment \n\
1241 gl_FragColor = fragment_color; \n\
1243 /* PLUG: fragment_end (gl_FragColor) */ \n\
1248const char *getGenericVertex(
void){
1249 return genericVertexGLES2;
1251const char *getGenericFragment(){
1252 return genericFragmentGLES2;
1254#include "../scenegraph/Component_Shape.h"
1256static const GLchar *plug_fragment_end_anaglyph =
"\
1257void PLUG_fragment_end (inout vec4 finalFrag){ \n\
1258 float gray = dot(finalFrag.rgb, vec3(0.299, 0.587, 0.114)); \n\
1259 finalFrag = vec4(gray,gray,gray, finalFrag.a); \n\
1301static const GLchar *plug_fragment_texture3D_apply_volume =
"\n\
1302vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, in int magfilter){ \n\
1303 vec4 sample = vec4(0.0); \n\
1305 //TILED method (vs Y strip method) \n\
1306 vec3 texcoord = texcoord3; \n\
1307 //texcoord.z = 1.0 - texcoord.z; //flip z from RHS to LHS\n\
1308 float depth = max(1.0,float(tex3dTiles[2])); \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\
1316 int izf = int(floor(texcoord.z*depth)); //floor z \n\
1317 int izc = int(ceil(texcoord.z*depth)); //ceiling z \n\
1318 izc = izc == tex3dTiles[2] ? izc - 1 : izc; //clamp int z \n\
1319 vec4 ftexel, ctexel; \n\
1321 int nx = tex3dTiles[0]; //0-11 \n\
1322 int ny = tex3dTiles[1]; \n\
1323 float fnx = 1.0/float(nx); //.1\n\
1324 float fny = 1.0/float(ny); \n\
1325 int ix = izc / ny; //60/11=5\n\
1326 int ixny = ix * ny; //5*11=55\n\
1327 int iy = izc - ixny; //60-55=5 modulus remainder \n\
1328 float cix = float(ix); //5 \n\
1329 float ciy = float(iy); \n\
1330 float xxc = (cix + texcoord.s)*fnx; //(5 + .5)*.1 = .55\n\
1331 float yyc = (ciy + texcoord.t)*fny; \n\
1334 iy = izf - ixny; //modulus remainder \n\
1335 float fix = float(ix); \n\
1336 float fiy = float(iy); \n\
1337 float xxf = (fix + texcoord.s)*fnx; \n\
1338 float yyf = (fiy + texcoord.t)*fny; \n\
1340 vec2 ftexcoord, ctexcoord; //texcoord is 3D, ftexcoord and ctexcoord are 2D coords\n\
1341 ftexcoord.s = xxf; \n\
1342 ftexcoord.t = yyf; \n\
1343 ctexcoord.s = xxc; \n\
1344 ctexcoord.t = yyc; \n\
1345 ftexel = texture2D(sampler,ftexcoord.st); \n\
1346 ctexel = texture2D(sampler,ctexcoord.st); \n\
1347 float fraction = mod(texcoord.z*depth,1.0); \n\
1348 if(magfilter == 1) \n\
1349 texel = mix(ctexel,ftexel,1.0-fraction); //lerp GL_LINEAR \n\
1351 texel = ftexel; //fraction > .5 ? ctexel : ftexel; //GL_NEAREST \n\
1356vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3){ \n\
1357 //use uniform magfilter \n\
1358 return texture3Demu0( sampler, texcoord3, magFilter); \n\
1360void PLUG_texture3D( inout vec4 sample, in vec3 texcoord3 ){ \n\
1361 sample = texture3Demu(fw_Texture_unit0,texcoord3); \n\
1363void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1366 sample = texture3Demu(fw_Texture_unit0,fw_TexCoord[0]); \n\
1367 finalFrag *= sample; \n\
1373static const GLchar *plug_fragment_texture3Dlayer_apply =
"\
1374void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1377 vec3 texcoord = fw_TexCoord[0]; \n\
1378 texcoord.z = 1.0 - texcoord.z; //flip z from RHS to LHS\n\
1379 float depth = max(1.0,float(textureCount-1)); \n\
1380 float delta = 1.0/depth; \n\
1381 if(repeatSTR[0] == 0) texcoord.x = clamp(texcoord.x,0.0001,.9999); \n\
1382 else texcoord.x = mod(texcoord.x,1.0); \n\
1383 if(repeatSTR[1] == 0) texcoord.y = clamp(texcoord.y,0.0001,.9999); \n\
1384 else texcoord.y = mod(texcoord.y,1.0); \n\
1385 if(repeatSTR[2] == 0) texcoord.z = clamp(texcoord.z,0.0001,.9999); \n\
1386 else texcoord.z = mod(texcoord.z,1.0); \n\
1387 int flay = int(floor(texcoord.z*depth)); \n\
1388 int clay = int(ceil(texcoord.z*depth)); \n\
1389 vec4 ftexel, ctexel; \n\
1392 if(flay == 0) ftexel = texture2D(fw_Texture_unit0,texcoord.st); \n\
1393 if(clay == 0) ctexel = texture2D(fw_Texture_unit0,texcoord.st); \n\
1394 if(flay == 1) ftexel = texture2D(fw_Texture_unit1,texcoord.st); \n\
1395 if(clay == 1) ctexel = texture2D(fw_Texture_unit1,texcoord.st); \n\
1396 if(flay == 2) ftexel = texture2D(fw_Texture_unit2,texcoord.st); \n\
1397 if(clay == 2) ctexel = texture2D(fw_Texture_unit2,texcoord.st); \n\
1398 if(flay == 3) ftexel = texture2D(fw_Texture_unit3,texcoord.st); \n\
1399 if(clay == 3) ctexel = texture2D(fw_Texture_unit3,texcoord.st); \n\
1400 float fraction = mod(texcoord.z*depth,1.0); \n\
1402 if(magFilter == 1) \n\
1403 texel = mix(ctexel,ftexel,(1.0-fraction)); //lerp GL_LINEAR \n\
1405 texel = fraction > .5 ? ctexel : ftexel; //GL_NEAREST \n\
1406 finalFrag *= texel; \n\
1407 #endif //TEX3DLAY \n\
1414static const GLchar *plug_fragment_texture_apply =
"\
1415void PLUG_texture_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1419 int isource,iasource, mode; \n\
1420 //finalFrag = texture2D(fw_Texture_unit0, fw_TexCoord[0].st) * finalFrag; \n\
1421 if(textureCount>0){ \n\
1422 if(fw_Texture_mode0[0] != MTMODE_OFF) { \n\
1423 isource = fw_Texture_source0[0]; //castle-style dual sources \n\
1424 iasource = fw_Texture_source0[1]; \n\
1425 if(isource == MT_DEFAULT) source = finalFrag; \n\
1426 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1427 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1428 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1429 if(iasource != 0){ \n\
1430 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1431 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1432 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1433 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1435 finalColCalc(source,fw_Texture_mode0[0],fw_Texture_mode0[1],fw_Texture_function0, fw_Texture_unit0,fw_TexCoord[0].st); \n\
1436 finalFrag = source; \n\
1439 if(textureCount>1){ \n\
1440 if(fw_Texture_mode1[0] != MTMODE_OFF) { \n\
1441 isource = fw_Texture_source1[0]; //castle-style dual sources \n\
1442 iasource = fw_Texture_source1[1]; \n\
1443 if(isource == MT_DEFAULT) source = finalFrag; \n\
1444 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1445 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1446 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1447 if(iasource != 0){ \n\
1448 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1449 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1450 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1451 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1453 finalColCalc(source,fw_Texture_mode1[0],fw_Texture_mode1[1],fw_Texture_function1, fw_Texture_unit1,fw_TexCoord[1].st); \n\
1454 finalFrag = source; \n\
1457 if(textureCount>2){ \n\
1458 if(fw_Texture_mode2[0] != MTMODE_OFF) { \n\
1459 isource = fw_Texture_source2[0]; //castle-style dual sources \n\
1460 iasource = fw_Texture_source2[1]; \n\
1461 if(isource == MT_DEFAULT) source = finalFrag; \n\
1462 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1463 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1464 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1465 if(iasource != 0){ \n\
1466 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1467 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1468 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1469 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1471 finalColCalc(source,fw_Texture_mode2[0],fw_Texture_mode2[1],fw_Texture_function2,fw_Texture_unit2,fw_TexCoord[2].st); \n\
1472 finalFrag = source; \n\
1475 if(textureCount>3){ \n\
1476 if(fw_Texture_mode3[0] != MTMODE_OFF) { \n\
1477 isource = fw_Texture_source3[0]; //castle-style dual sources \n\
1478 iasource = fw_Texture_source3[1]; \n\
1479 if(isource == MT_DEFAULT) source = finalFrag; \n\
1480 else if(isource == MTSRC_DIFFUSE) source = matdiff_color; \n\
1481 else if(isource == MTSRC_SPECULAR) source = vec4(castle_ColorES.rgb,1.0); \n\
1482 else if(isource == MTSRC_FACTOR) source = mt_Color; \n\
1483 if(iasource != 0){ \n\
1484 if(iasource == MT_DEFAULT) source.a = finalFrag.a; \n\
1485 else if(iasource == MTSRC_DIFFUSE) source.a = matdiff_color.a; \n\
1486 else if(iasource == MTSRC_SPECULAR) source.a = 1.0; \n\
1487 else if(iasource == MTSRC_FACTOR) source.a = mt_Color.a; \n\
1489 finalColCalc(source,fw_Texture_mode3[0],fw_Texture_mode3[1],fw_Texture_function3,fw_Texture_unit3,fw_TexCoord[3].st); \n\
1490 finalFrag = source; \n\
1494 /* ONE TEXTURE */ \n\
1496 finalFrag = textureCube(fw_Texture_unit0, fw_TexCoord[0]) * finalFrag; \n\
1498 finalFrag = texture2D(fw_Texture_unit0, fw_TexCoord[0].st) * finalFrag; \n\
1515static const GLchar *plug_vertex_lighting_matemissive =
"\n\
1516void PLUG_add_light_contribution (inout vec4 vertexcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ) {\n\
1517 vertexcolor.rgb += fw_FrontMaterial.emissive.rgb; \n\
1521static const GLchar *plug_vertex_lighting_ADSLightModel =
"\n\
1522/* use ADSLightModel here the ADS colour is returned from the function. */ \n\
1523void PLUG_add_light_contribution2 (inout vec4 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ) { \n\
1524 //working in eye space: eye is at 0,0,0 looking generally in direction 0,0,-1 \n\
1525 //myPosition, myNormal - of surface vertex, in eyespace \n\
1526 //vertexcolor - diffuse+ambient -will be replaced or modulated by texture color \n\
1527 //specularcolor - specular+emissive or non-diffuse (emissive added outside this function) \n\
1528 //algo: uses Blinn-Phong specular reflection: half-vector pow(N*H,shininess) \n\
1530 vec4 diffuse = vec4(0., 0., 0., 0.); \n\
1531 vec4 ambient = vec4(0., 0., 0., 0.); \n\
1532 vec4 specular = vec4(0., 0., 0., 1.); \n\
1533 vec3 N = normalize (myNormal); \n\
1535 vec3 E = -normalize(myPosition.xyz); \n \
1536 vec4 matdiffuse = vec4(1.0,1.0,1.0,1.0); \n\
1537 float myAlph = 0.0;\n\
1539 fw_MaterialParameters myMat = fw_FrontMaterial; \n\
1541 /* back Facing materials - flip the normal and grab back materials */ \n\
1542 bool backFacing = (dot(N,E) < 0.0); \n\
1543 if (backFacing) { \n\
1546 myMat = fw_BackMaterial; \n\
1550 myAlph = myMat.diffuse.a; \n\
1551 //if(useMatDiffuse) \n\
1552 matdiffuse = myMat.diffuse; \n\
1554 /* apply the lights to this material */ \n\
1555 /* weird but ANGLE needs constant loop */ \n\
1556 for (i=0; i<MAX_LIGHTS; i++) {\n\
1557 if(i < lightcount) { \n\
1558 vec4 myLightDiffuse = fw_LightSource[i].diffuse; \n\
1559 vec4 myLightAmbient = fw_LightSource[i].ambient; \n\
1560 vec4 myLightSpecular = fw_LightSource[i].specular; \n\
1561 vec4 myLightPosition = fw_LightSource[i].position; \n\
1562 int myLightType = lightType[i]; \n\
1563 vec3 myLightDir = fw_LightSource[i].spotDirection.xyz; \n\
1564 vec3 VP; /* vector of light direction and distance */ \n\
1565 VP = myLightPosition.xyz - myPosition.xyz; \n\
1566 vec3 L = myLightDir; /*directional light*/ \n\
1567 if(myLightType < 2) /*point and spot*/ \n\
1568 L = normalize(VP); \n\
1569 float NdotL = max(dot(N, L), 0.0); //Lambertian diffuse term \n\
1570 /*specular reflection models, phong or blinn-phong*/ \n\
1571 //#define PHONG 1 \n\
1574 vec3 R = normalize(-reflect(L,N)); \n\
1575 float RdotE = max(dot(R,E),0.0); \n\
1576 float specbase = RdotE; \n\
1577 float specpow = .3 * myMat.shininess; //assume shini tuned to blinn, adjust for phong \n\
1580 vec3 H = normalize(L + E); //halfvector\n\
1581 float NdotH = max(dot(N,H),0.0); \n\
1582 float specbase = NdotH; \n\
1583 float specpow = myMat.shininess; \n\
1585 float powerFactor = 0.0; /* for light dropoff */ \n\
1586 if (specbase > 0.0) { \n\
1587 powerFactor = pow(specbase,specpow); \n\
1588 /* tone down the power factor if myMat.shininess borders 0 */ \n\
1589 if (myMat.shininess < 1.0) { \n\
1590 powerFactor *= myMat.shininess; \n\
1594 if (myLightType==1) { \n\
1596 float spotDot, multiplier; \n\
1597 float spotAttenuation = 0.0; \n\
1598 float attenuation; /* computed attenuation factor */ \n\
1599 float D; /* distance to vertex */ \n\
1601 attenuation = 1.0/(fw_LightSource[i].Attenuations.x + (fw_LightSource[i].Attenuations.y * D) + (fw_LightSource[i].Attenuations.z *D*D)); \n\
1602 multiplier = 0.0; \n\
1603 spotDot = dot (-L,myLightDir); \n\
1604 /* check against spotCosCutoff */ \n\
1605 if (spotDot > fw_LightSource[i].spotCutoff) { \n\
1606 //?? what was this: spotAttenuation = pow(spotDot,fw_LightSource[i].spotExponent); \n\
1607 if(spotDot > fw_LightSource[i].spotBeamWidth) { \n\
1608 multiplier = 1.0; \n\
1610 multiplier = (spotDot - fw_LightSource[i].spotCutoff)/(fw_LightSource[i].spotBeamWidth - fw_LightSource[i].spotCutoff); \n\
1613 //attenuation *= spotAttenuation; \n\
1614 attenuation *= multiplier; \n\
1615 /* diffuse light computation */ \n\
1616 diffuse += NdotL* matdiffuse*myLightDiffuse * attenuation; \n\
1617 /* ambient light computation */ \n\
1618 ambient += myMat.ambient*myLightAmbient; \n\
1619 /* specular light computation */ \n\
1620 specular += myLightSpecular * powerFactor * attenuation; \n\
1622 } else if (myLightType == 2) { \n\
1623 /* DirectionalLight */ \n\
1624 /* Specular light computation */ \n\
1625 specular += myMat.specular *myLightSpecular*powerFactor; \n\
1626 /* diffuse light computation */ \n\
1627 diffuse += NdotL*matdiffuse*myLightDiffuse; \n\
1628 /* ambient light computation */ \n\
1629 ambient += myMat.ambient*myLightAmbient; \n\
1631 /* PointLight */ \n\
1632 float attenuation = 0.0; /* computed attenuation factor */ \n\
1633 float D = length(VP); /* distance to vertex */ \n\
1634 /* are we within range? */ \n\
1635 if (D <= fw_LightSource[i].lightRadius) { \n\
1636 /* this is actually the SFVec3f attenuation field */ \n\
1637 attenuation = 1.0/(fw_LightSource[i].Attenuations.x + (fw_LightSource[i].Attenuations.y * D) + (fw_LightSource[i].Attenuations.z *D*D)); \n\
1638 /* diffuse light computation */ \n\
1639 diffuse += NdotL* matdiffuse*myLightDiffuse * attenuation; \n\
1640 /* ambient light computation */ \n\
1641 ambient += myMat.ambient*myLightAmbient; \n\
1642 /* specular light computation */ \n\
1643 attenuation *= (myMat.shininess/128.0); \n\
1644 specular += myLightSpecular * powerFactor * attenuation; \n\
1649 vertexcolor = clamp(vec4(vec3(ambient + diffuse ) + vertexcolor.rgb ,myAlph), 0.0, 1.0); \n\
1650 specularcolor = clamp(specular.rgb + specularcolor, 0.0, 1.0); \n\
1656static const GLchar *plug_fog_apply =
"\
1657void PLUG_fog_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1659 float depth = abs(castle_vertex_eye.z/castle_vertex_eye.w); \n\
1660 if(fw_fogparams.fogType > 0){ \n\
1662 if(fw_fogparams.fogType == 1){ //FOGTYPE_LINEAR \n\
1663 if(depth < fw_fogparams.visibilityRange) \n\
1664 ff = (fw_fogparams.visibilityRange-depth)/fw_fogparams.visibilityRange; \n\
1665 } else { //FOGTYPE_EXPONENTIAL \n\
1666 if(depth < fw_fogparams.visibilityRange){ \n\
1667 ff = exp(-depth/(fw_fogparams.visibilityRange -depth) ); \n\
1668 ff = clamp(ff, 0.0, 1.0); \n\
1671 finalFrag = mix(finalFrag,fw_fogparams.fogColor,1.0 - ff); \n\
1676static const GLchar *vertex_plug_clip_apply =
"\
1678#define FW_MAXCLIPPLANES 4 \n\
1679uniform int fw_nclipplanes; \n\
1680uniform vec4 fw_clipplanes[FW_MAXCLIPPLANES]; \n\
1681varying float fw_ClipDistance[FW_MAXCLIPPLANES]; \n\
1683void PLUG_vertex_object_space (in vec4 vertex_object, in vec3 normal_object){ \n\
1684 for ( int i=0; i<fw_nclipplanes; i++ ) \n\
1685 fw_ClipDistance[i] = dot( fw_clipplanes[i], vertex_object); \n\
1690static const GLchar *frag_plug_clip_apply =
"\
1692#define FW_MAXCLIPPLANES 4 \n\
1693uniform int fw_nclipplanes; \n\
1694varying float fw_ClipDistance[FW_MAXCLIPPLANES]; \n\
1695void PLUG_fog_apply (inout vec4 finalFrag, in vec3 normal_eye_fragment ){ \n\
1696 for(int i=0;i<fw_nclipplanes;i++) { \n\
1697 //if(normal_eye_fragment.z > fw_ClipDistance[i]) discard; \n\
1698 if(fw_ClipDistance[i] < 0.0) discard; \n\
1704#if defined(GL_ES_VERSION_2_0)
1705static int isMobile = TRUE;
1707static int isMobile = FALSE;
1710#define DESIRE(whichOne,zzz) ((whichOne & zzz)==zzz)
1711int getSpecificShaderSourceCastlePlugs (
const GLchar **vertexSource,
const GLchar **fragmentSource,
shaderflagsstruct whichOne)
1717 int retval, unique_int;
1718 char *CompleteCode[3];
1721 if(whichOne.usershaders )
1726 vs = strdup(getGenericVertex());
1727 fs = strdup(getGenericFragment());
1729 CompleteCode[SHADERPART_VERTEX] = vs;
1730 CompleteCode[SHADERPART_GEOMETRY] = NULL;
1731 CompleteCode[SHADERPART_FRAGMENT] = fs;
1739 AddVersion(SHADERPART_VERTEX, 100, CompleteCode);
1740 AddVersion(SHADERPART_FRAGMENT, 100, CompleteCode);
1741 AddDefine(SHADERPART_FRAGMENT,
"MOBILE",CompleteCode);
1744 AddVersion(SHADERPART_VERTEX, 110, CompleteCode);
1745 AddVersion(SHADERPART_FRAGMENT, 110, CompleteCode);
1753 if(DESIRE(whichOne.base,WANT_ANAGLYPH))
1754 Plug(SHADERPART_FRAGMENT,plug_fragment_end_anaglyph,CompleteCode,&unique_int);
1756 if DESIRE(whichOne.base,COLOUR_MATERIAL_SHADER) {
1757 AddDefine(SHADERPART_VERTEX,
"CPV",CompleteCode);
1758 AddDefine(SHADERPART_FRAGMENT,
"CPV",CompleteCode);
1759 if(DESIRE(whichOne.base,CPV_REPLACE_PRIOR)){
1760 AddDefine(SHADERPART_VERTEX,
"CPVREP",CompleteCode);
1761 AddDefine(SHADERPART_FRAGMENT,
"CPVREP",CompleteCode);
1767 if(DESIRE(whichOne.base,MATERIAL_APPEARANCE_SHADER) || DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER)){
1769 if(DESIRE(whichOne.base,MAT_FIRST)){
1771 AddDefine(SHADERPART_VERTEX,
"MATFIR",CompleteCode);
1772 AddDefine(SHADERPART_FRAGMENT,
"MATFIR",CompleteCode);
1774 if(DESIRE(whichOne.base,SHADINGSTYLE_PHONG) && !DESIRE(whichOne.base,HAVE_LINEPOINTS_COLOR)){
1776 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
1777 AddDefine(SHADERPART_FRAGMENT,
"LITE",CompleteCode);
1778 Plug(SHADERPART_FRAGMENT,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
1780 if(DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER))
1781 AddDefine(SHADERPART_FRAGMENT,
"TWO",CompleteCode);
1785 AddDefine(SHADERPART_FRAGMENT,
"PHONG",CompleteCode);
1787 AddDefine(SHADERPART_VERTEX,
"LIT",CompleteCode);
1788 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
1790 if( DESIRE(whichOne.base,HAVE_LINEPOINTS_COLOR) ) {
1791 AddDefine(SHADERPART_VERTEX,
"LINE",CompleteCode);
1793 AddDefine(SHADERPART_VERTEX,
"LITE",CompleteCode);
1794 Plug(SHADERPART_VERTEX,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
1795 if(DESIRE(whichOne.base,TWO_MATERIAL_APPEARANCE_SHADER))
1796 AddDefine(SHADERPART_VERTEX,
"TWO",CompleteCode);
1818 if(DESIRE(whichOne.base,HAVE_UNLIT_COLOR)){
1819 AddDefine(SHADERPART_VERTEX,
"UNLIT",CompleteCode);
1820 AddDefine(SHADERPART_FRAGMENT,
"UNLIT",CompleteCode);
1822 if(DESIRE(whichOne.base,HAVE_PROJECTIVETEXTURE)){
1823 AddDefine(SHADERPART_VERTEX,
"PROJTEX",CompleteCode);
1824 AddDefine(SHADERPART_FRAGMENT,
"PROJTEX",CompleteCode);
1825 AddDefine(SHADERPART_FRAGMENT,
"TEX",CompleteCode);
1827 if (DESIRE(whichOne.base,ONE_TEX_APPEARANCE_SHADER) ||
1828 DESIRE(whichOne.base,HAVE_TEXTURECOORDINATEGENERATOR) ||
1829 DESIRE(whichOne.base,HAVE_CUBEMAP_TEXTURE) ||
1830 DESIRE(whichOne.base,MULTI_TEX_APPEARANCE_SHADER)) {
1831 AddDefine(SHADERPART_VERTEX,
"TEX",CompleteCode);
1832 AddDefine(SHADERPART_FRAGMENT,
"TEX",CompleteCode);
1833 if(DESIRE(whichOne.base,HAVE_TEXTURECOORDINATEGENERATOR) )
1834 AddDefine(SHADERPART_VERTEX,
"TGEN",CompleteCode);
1835 if(DESIRE(whichOne.base,TEX3D_SHADER)){
1842 AddDefine(SHADERPART_VERTEX,
"TEX3D",CompleteCode);
1843 AddDefine(SHADERPART_FRAGMENT,
"TEX3D",CompleteCode);
1845 if(DESIRE(whichOne.base,TEX3D_LAYER_SHADER)){
1847 AddDefine(SHADERPART_FRAGMENT,
"TEX3DLAY",CompleteCode);
1848 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3Dlayer_apply,CompleteCode,&unique_int);
1852 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3D_apply_volume,CompleteCode,&unique_int);
1855 if(DESIRE(whichOne.base,HAVE_CUBEMAP_TEXTURE)){
1856 AddDefine(SHADERPART_VERTEX,
"CUB",CompleteCode);
1857 AddDefine(SHADERPART_FRAGMENT,
"CUB",CompleteCode);
1858 }
else if(DESIRE(whichOne.base,MULTI_TEX_APPEARANCE_SHADER)){
1859 AddDefine(SHADERPART_VERTEX,
"MTEX",CompleteCode);
1860 AddDefine(SHADERPART_FRAGMENT,
"MTEX",CompleteCode);
1862 if(DESIRE(whichOne.base,TEXTURE_REPLACE_PRIOR) )
1863 AddDefine(SHADERPART_FRAGMENT,
"TEXREP",CompleteCode);
1864 if(DESIRE(whichOne.base,TEXALPHA_REPLACE_PRIOR))
1865 AddDefine(SHADERPART_VERTEX,
"TAREP",CompleteCode);
1867 Plug(SHADERPART_FRAGMENT,plug_fragment_texture_apply,CompleteCode,&unique_int);
1877 if(DESIRE(whichOne.base,FILL_PROPERTIES_SHADER)) {
1878 AddDefine(SHADERPART_VERTEX,
"FILL",CompleteCode);
1879 AddDefine(SHADERPART_FRAGMENT,
"FILL",CompleteCode);
1882 if(DESIRE(whichOne.base,FOG_APPEARANCE_SHADER)){
1883 AddDefine(SHADERPART_VERTEX,
"FOG",CompleteCode);
1884 AddDefine(SHADERPART_FRAGMENT,
"FOG",CompleteCode);
1885 if(DESIRE(whichOne.base,HAVE_FOG_COORDS))
1886 AddDefine(SHADERPART_VERTEX,
"FOGCOORD",CompleteCode);
1887 Plug(SHADERPART_FRAGMENT,plug_fog_apply,CompleteCode,&unique_int);
1891 if(DESIRE(whichOne.base,CLIPPLANE_SHADER)){
1892 AddDefine(SHADERPART_VERTEX,
"CLIP",CompleteCode);
1893 Plug(SHADERPART_VERTEX,vertex_plug_clip_apply,CompleteCode,&unique_int);
1894 AddDefine(SHADERPART_FRAGMENT,
"CLIP",CompleteCode);
1895 Plug(SHADERPART_FRAGMENT,frag_plug_clip_apply,CompleteCode,&unique_int);
1897 if(DESIRE(whichOne.base,PARTICLE_SHADER)){
1898 AddDefine(SHADERPART_VERTEX,
"PARTICLE",CompleteCode);
1901 EnableEffects(CompleteCode,&unique_int);
1908 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
1909 *vertexSource = CompleteCode[SHADERPART_VERTEX];
1916 FILE *fp = fopen(
"C:/tmp/composed_shader.vert",
"w+");
1917 fwrite(*vertexSource,strlen(*vertexSource),1,fp);
1919 fp = fopen(
"C:/tmp/composed_shader.frag",
"w+");
1920 fwrite(*fragmentSource,strlen(*fragmentSource),1,fp);
1932static const GLchar *volumeVertexGLES2 =
" \n\
1933uniform mat4 fw_ModelViewMatrix; \n\
1934uniform mat4 fw_ProjectionMatrix; \n\
1935attribute vec4 fw_Vertex; \n\
1937/* PLUG-DECLARATIONS */ \n\
1939varying vec4 castle_vertex_eye; \n\
1940varying vec4 castle_Color; \n\
1944 vec4 vertex_object = fw_Vertex; \n\
1945 vec3 normal_object = vec3(0.0); \n\
1946 /* PLUG: vertex_object_space (vertex_object, normal_object) */ \n\
1947 castle_vertex_eye = fw_ModelViewMatrix * vertex_object; \n\
1949 castle_Color = vec4(1.0,.5,.5,1.0); \n\
1951 gl_Position = fw_ProjectionMatrix * castle_vertex_eye; \n\
1963static const GLchar *volumeFragmentGLES2 =
" \n\
1966//precision highp float; \n\
1967precision mediump float; \n\
1970 vec4 HeatMapColor(float value, float minValue, float maxValue) \n\
1972 //used for debugging. If min=0,max=1 then magenta is 0, blue,green,yellow, red is 1 \n\
1974 int HEATMAP_COLORS_COUNT; \n\
1976 HEATMAP_COLORS_COUNT = 6; \n\
1977 colors[0] = vec4(0.32, 0.00, 0.32, 1.0); \n\
1978 colors[1] = vec4( 0.00, 0.00, 1.00, 1.00); \n\
1979 colors[2] = vec4(0.00, 1.00, 0.00, 1.00); \n\
1980 colors[3] = vec4(1.00, 1.00, 0.00, 1.00); \n\
1981 colors[4] = vec4(1.00, 0.60, 0.00, 1.00); \n\
1982 colors[5] = vec4(1.00, 0.00, 0.00, 1.00); \n\
1983 float ratio=(float(HEATMAP_COLORS_COUNT)-1.0)*clamp((value-minValue)/(maxValue-minValue),0.0,1.0); \n\
1984 int indexMin=int(floor(ratio)); \n\
1985 int indexMax= indexMin+1 < HEATMAP_COLORS_COUNT-1 ? indexMin+1 : HEATMAP_COLORS_COUNT-1; \n\
1986 ret = mix(colors[indexMin], colors[indexMax], ratio-float(indexMin)); \n\
1987 if(value < minValue) ret = vec4(0.0,0.0,0.0,1.0); \n\
1988 if(value > maxValue) ret = vec4(1.0,1.0,1.0,1.0); \n\
1991vec4 debug_color; \n\
1992float hash( float n ) \n\
1994 return fract(sin(n)*43758.5453); \n\
1996float noise( vec3 xyz ) \n\
1998 // The noise function returns a value in the range -1.0f -> 1.0f \n\
1999 vec3 p = floor(xyz); \n\
2000 vec3 f = fract(xyz); \n\
2002 f = f*f*(3.0-2.0*f); \n\
2003 float n = p.x + p.y*57.0 + 113.0*p.z; \n\
2005 return mix(mix(mix( hash(n+0.0), hash(n+1.0),f.x), \n\
2006 mix( hash(n+57.0), hash(n+58.0),f.x),f.y), \n\
2007 mix(mix( hash(n+113.0), hash(n+114.0),f.x), \n\
2008 mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z); \n\
2010vec3 noise3( in vec3 xyz, in float range ){ \n\
2011 vec3 rxyz = vec3(xyz); \n\
2012 rxyz.x += noise(xyz)*range; \n\
2013 rxyz.y += noise(xyz)*range; \n\
2014 rxyz.z += noise(xyz)*range; \n\
2018varying vec4 castle_vertex_eye; \n\
2019varying vec4 castle_Color; \n\
2020uniform mat4 fw_ModelViewProjInverse; \n\
2021//uniform float fw_FocalLength; \n\
2022uniform vec4 fw_viewport; \n\
2023uniform vec3 fw_dimensions; \n\
2024//uniform vec3 fw_RayOrigin; \n\
2025uniform sampler2D fw_Texture_unit0; \n\
2026uniform sampler2D fw_Texture_unit1; \n\
2027uniform sampler2D fw_Texture_unit2; \n\
2028uniform sampler2D fw_Texture_unit3; \n\
2030uniform int tex3dTiles[3]; \n\
2031uniform int repeatSTR[3]; \n\
2032uniform int magFilter; \n\
2035uniform int fw_nIDs; \n\
2036uniform int fw_enableIDs[10]; \n\
2037uniform int fw_surfaceStyles[2]; \n\
2038uniform int fw_nStyles; \n\
2039vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3); \n\
2040vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, int magfilter); \n\
2041bool inEnabledSegment(in vec3 texcoords, inout int jstyle){ \n\
2042 bool inside = true; \n\
2043 jstyle = 1; //DEFAULT \n\
2044 vec4 segel = texture3Demu0(fw_Texture_unit1,texcoords,0); \n\
2045 //convert from GL_FLOAT 0-1 to int 0-255 \n\
2046 //Q. is there a way to do int images in GLES2? \n\
2047 int ID = int(floor(segel.a * 255.0 + .1)); \n\
2048 //debug_color = HeatMapColor(float(ID),0.0,5.0); \n\
2049 //debug_color.a = .2; \n\
2050 if(ID < fw_nIDs){ \n\
2051 //specs: The indices of this array corresponds to the segment identifier. \n\
2052 inside = fw_enableIDs[ID] == 0 ? false : true; \n\
2055 int kstyle = fw_nStyles-1; \n\
2056 kstyle = ID < fw_nStyles ? ID : kstyle; \n\
2057 jstyle = fw_surfaceStyles[kstyle]; \n\
2058 jstyle = jstyle == 1 ? 0 : jstyle; \n\
2064uniform float fw_stepSize; \n\
2065uniform float fw_tolerance; \n\
2066uniform float fw_surfaceVals[]; \n\
2067uniform int fw_nVals; \n\
2068uniform int fw_surfaceStyles[]; \n\
2069uniform int fw_nStyles; \n\
2080bool IntersectBox(Ray r, AABB aabb, out float t0, out float t1) \n\
2082 vec3 invR = 1.0 / r.Dir; \n\
2083 vec3 tbot = invR * (aabb.Min-r.Origin); \n\
2084 vec3 ttop = invR * (aabb.Max-r.Origin); \n\
2085 vec3 tmin = min(ttop, tbot); \n\
2086 vec3 tmax = max(ttop, tbot); \n\
2087 vec2 t = max(tmin.xx, tmin.yz); \n\
2088 t0 = max(t.x, t.y); \n\
2089 t = min(tmax.xx, tmax.yz); \n\
2090 t1 = min(t.x, t.y); \n\
2091 return t0 <= t1; \n\
2093/* PLUG-DECLARATIONS */ \n\
2095vec3 fw_TexCoord[1]; \n\
2097#define FW_MAXCLIPPLANES 4 \n\
2098uniform int fw_nclipplanes; \n\
2099uniform vec4 fw_clipplanes[FW_MAXCLIPPLANES]; \n\
2100bool clip (in vec3 vertex_object){ \n\
2101 bool iclip = false; \n\
2102 for ( int i=0; i<fw_nclipplanes; i++ ) { \n\
2103 if( dot( fw_clipplanes[i], vec4(vertex_object,1.0)) < 0.0) \n\
2114 debug_color = vec4(0.0); \n\
2115 float maxDist = length(fw_dimensions); //1.414214; //sqrt(2.0); \n\
2116 int numSamples = 128; \n\
2117 float fnumSamples = float(numSamples); \n\
2118 float stepSize = maxDist/fnumSamples; \n\
2119 float densityFactor = 5.0/fnumSamples; //.88; // 1.0=normal H3D, .5 see deeper \n\
2121 vec4 fragment_color; \n\
2123 vec3 rayDirection; \n\
2124 //convert window to frustum \n\
2125 rayDirection.xy = 2.0 * (gl_FragCoord.xy - fw_viewport.xy) / fw_viewport.zw - vec2(1.0); \n\
2126 rayDirection.z = 0.0; \n\
2127 vec3 rayOrigin; // = fw_RayOrigin; \n\
2128 //the equivalent of gluUnproject \n\
2129 //by unprojecting 2 points on ray here, this should also work with ortho viewpoint \n\
2130 vec4 ray4 = vec4(rayDirection,1.0); \n\
2131 vec4 org4 = ray4; \n\
2132 //if I back up the ray origin by -1.0 the front plane clipping works properly \n\
2133 ray4.z = 0.0; //1.0; \n\
2134 org4.z = -1.0; //0.0; \n\
2135 ray4 = fw_ModelViewProjInverse * ray4; \n\
2136 org4 = fw_ModelViewProjInverse * org4; \n\
2139 rayDirection = normalize(ray4.xyz - org4.xyz); \n\
2140 rayOrigin = org4.xyz; \n\
2142 Ray eye = Ray( rayOrigin, rayDirection); \n\
2143 vec3 half_dimensions = fw_dimensions * .5; \n\
2144 vec3 minus_half_dimensions = half_dimensions * -1.0; \n\
2145 AABB aabb = AABB(minus_half_dimensions,half_dimensions); \n\
2147 float tnear, tfar; \n\
2148 IntersectBox(eye, aabb, tnear, tfar); \n\
2149 if (tnear < 0.0) tnear = 0.0; \n\
2150 vec3 rayStart = eye.Origin + eye.Dir * tnear; \n\
2151 vec3 rayStop = eye.Origin + eye.Dir * tfar; \n\
2152 // Perform the ray marching: \n\
2153 vec3 pos = rayStart; \n\
2154 vec3 step = normalize(rayStop-rayStart) * stepSize; \n\
2155 float totaltravel = distance(rayStop, rayStart); \n\
2156 float travel = totaltravel; \n\
2158 vec3 Lo = vec3(0.0); \n\
2159 normal_eye = rayDirection; \n\
2160 vec3 pos2 = pos; \n\
2161 // Transform from object space to texture coordinate space: \n\
2162 pos2 = (pos2+half_dimensions)/fw_dimensions; \n\
2163 pos2 = clamp(pos2,0.001,.999); \n\
2164 raysum = vec4(0.0); \n\
2165 float depth = 0.0; \n\
2166 float lastdensity; \n\
2167 float lastdensity_iso; \n\
2169 for (int i=0; i < numSamples; ++i) { \n\
2170 //raysum = HeatMapColor(travel,0.0,2.0); \n\
2172 // ...lighting and absorption stuff here... \n\
2174 vertex_eye = pos2; \n\
2175 // Transform from object space to texture coordinate space: \n\
2176 pos2 = (pos2+half_dimensions)/fw_dimensions; \n\
2177 //pos2.z = 1.0 - pos2.z; //RHS to LHS \n\
2178 pos2 = clamp(pos2,0.001,.999); \n\
2179 vec3 texcoord3 = pos2; \n\
2180 bool iclip = false; \n\
2182 iclip = clip(vertex_eye); //clip(totaltravel - travel); \n\
2185 fragment_color = vec4(1.0,0.0,1.0,1.0); //do I need a default? seems not \n\
2186 /* PLUG: texture3D ( fragment_color, texcoord3) */ \n\
2189 if(inEnabledSegment(texcoord3,jstyle)){ \n\
2190 #endif //SEGMENT \n\
2191 //assuming we had a scalar input image and put L into .a, \n\
2192 // and computed gradient and put in .rgb : \n\
2193 float density = fragment_color.a; //recover the scalar value \n\
2194 vec3 gradient = fragment_color.rgb - vec3(.5,.5,.5); //we added 127 to (-127 to 127) in CPU gradient computation\n\
2195 //vec4 voxel = vec4(density,density,density,density); //this is where the black visual voxels come from\n\
2196 vec4 voxel = vec4(density,density,density,density); //this is where the black visual voxels come from\n\
2200 lastdensity = density; \n\
2201 lastdensity_iso = 0.0; \n\
2203 int MODE = fw_nVals == 1 ? 1 : 3; \n\
2204 MODE = fw_stepSize != 0.0 && MODE == 1 ? 2 : 1; \n\
2205 #ifdef ISO_MODE3 \n\
2207 for(int i=0;i<fw_nVals;i++){ \n\
2208 float iso = fw_surfaceVals[i]; \n\
2209 if( sign( density - iso) != sign( lastdensity - iso) && length(gradient) > fw_tolerance ){ \n\
2211 int jstyle = min(i,fw_nStyles-1); \n\
2212 jstyle = fw_surfaceStyles[jstyle]; \n\
2213 if(jstyle == 1){ \n\
2214 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2215 } else if(jstyle == 2) { \n\
2216 /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ \n\
2217 } else if(jstyle == 3) { \n\
2218 /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ \n\
2219 } else if(jstyle == 4) { \n\
2220 /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ \n\
2221 } else if(jstyle == 5) { \n\
2222 /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ \n\
2223 } else if(jstyle == 6) { \n\
2224 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2225 } else if(jstyle == 7) { \n\
2226 /* PLUG: voxel_apply_EDGE (voxel, gradient) */ \n\
2227 } else if(jstyle == 8) { \n\
2228 /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ \n\
2229 } else if(jstyle == 9) { \n\
2230 /* PLUG: voxel_apply_SHADED (voxel, gradient) */ \n\
2231 } else if(jstyle == 10) { \n\
2232 /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ \n\
2233 } else if(jstyle == 11) { \n\
2234 /* PLUG: voxel_apply_TONE (voxel, gradient) */ \n\
2237 voxel = vec4(0.0); //similar to discard \n\
2240 lastdensity = density; \n\
2242 #else //ISO_MODE3 \n\
2244 float iso = fw_surfaceVals[0]; \n\
2245 if( sign( density - iso) != sign( lastdensity - iso) && length(gradient) > fw_tolerance ){ \n\
2246 //debug_color = HeatMapColor(iso,0.0,.3); \n\
2248 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2250 voxel = vec4(0.0); //similar to discard \n\
2252 lastdensity = density; \n\
2253 } else if(MODE == 2){ \n\
2254 float iso = fw_surfaceVals[0]; \n\
2255 float density_iso = density / fw_stepSize; \n\
2256 if( sign( density_iso - iso) != sign( lastdensity_iso - iso) && length(gradient) > fw_tolerance ){ \n\
2258 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2260 voxel = vec4(0.0); //similar to discard \n\
2262 lastdensity = density; \n\
2263 lastdensity_iso = density_iso; \n\
2265 #endif //ISO_MODE3 \n\
2268 //debug_color = HeatMapColor(float(jstyle),1.0,12.0); \n\
2269 //debug_color.a = .2; \n\
2270 if(jstyle == 1){ \n\
2271 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2272 } else if(jstyle == 2) { \n\
2273 /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ \n\
2274 } else if(jstyle == 3) { \n\
2275 /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ \n\
2276 } else if(jstyle == 4) { \n\
2277 /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ \n\
2278 } else if(jstyle == 5) { \n\
2279 /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ \n\
2280 } else if(jstyle == 6) { \n\
2281 /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ \n\
2282 } else if(jstyle == 7) { \n\
2283 /* PLUG: voxel_apply_EDGE (voxel, gradient) */ \n\
2284 } else if(jstyle == 8) { \n\
2285 /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ \n\
2286 } else if(jstyle == 9) { \n\
2287 /* PLUG: voxel_apply_SHADED (voxel, gradient) */ \n\
2288 } else if(jstyle == 10) { \n\
2289 /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ \n\
2290 } else if(jstyle == 11) { \n\
2291 /* PLUG: voxel_apply_TONE (voxel, gradient) */ \n\
2294 //non-iso rendering styles \n\
2295 //void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) \n\
2296 /* PLUG: voxel_apply (voxel, gradient) */ \n\
2297 #endif //SEGMENT \n\
2299 density = voxel.a; \n\
2300 //debug_color = HeatMapColor(densityFactor,0.134,.135); \n\
2301 T = (1.0 - raysum.a); \n\
2302 raysum.a += density * T; \n\
2303 raysum.rgb += voxel.rgb * T * density; \n\
2304 if(raysum.a > .99) { \n\
2308 } //if inEnabledSegment \n\
2309 #endif //SEGMENT \n\
2311 travel -= stepSize; \n\
2312 depth += stepSize; \n\
2313 if(travel <= 0.0) break; \n\
2317 //void PLUG_ray_apply (inout vec4 raysum) \n\
2318 /* PLUG: ray_apply (raysum) */ \n\
2319 if(true) gl_FragColor = raysum; \n\
2320 else gl_FragColor = debug_color; \n\
2330static const GLchar *plug_voxel_DEFAULT =
"\
2331void voxel_apply_DEFAULT (inout vec4 voxel, inout vec3 gradient) { \n\
2332 float alpha = voxel.a; \n\
2333 //voxel.a = voxel.r; \n\
2334 //voxel.rgb = vec3(alpha); \n\
2336void PLUG_voxel_apply_DEFAULT (inout vec4 voxel, inout vec3 gradient) { \n\
2337 voxel_apply_DEFAULT(voxel,gradient); \n\
2339void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2340 voxel_apply_DEFAULT(voxel,gradient); \n\
2345static const GLchar *plug_voxel_OPACITY =
"\
2346uniform int fw_opacTexture; \n\
2347//uniform sampler2D fw_Texture_unit3; \n\
2348void voxel_apply_OPACITY (inout vec4 voxel, inout vec3 gradient) { \n\
2349 if(fw_opacTexture == 1){ \n\
2350 vec4 lookup_color; \n\
2351 float lum = voxel.r; \n\
2352 vec2 texcoord = vec2(lum,0.0); \n\
2353 //this is too simple for the lookups in the specs \n\
2354 //http://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/volume.html#t-transferFunctionTextureCoordinateMapping \n\
2355 lookup_color = texture2D(fw_Texture_unit3,texcoord); \n\
2356 voxel.rgb = lookup_color.rgb; \n\
2360 float alpha = voxel.a; \n\
2361 voxel.a = voxel.r; \n\
2362 voxel.rgb = vec3(alpha); \n\
2365void PLUG_voxel_apply_OPACITY (inout vec4 voxel, inout vec3 gradient) { \n\
2366 voxel_apply_OPACITY(voxel, gradient); \n\
2368void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2369 voxel_apply_OPACITY(voxel, gradient); \n\
2374static const GLchar *plug_voxel_BLENDED =
"\
2375void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2380static const GLchar *plug_voxel_BOUNDARY =
"\n\
2381uniform float fw_boundaryOpacity; \n\
2382uniform float fw_retainedOpacity; \n\
2383uniform float fw_opacityFactor; \n\
2384void voxel_apply_BOUNDARY (inout vec4 voxel, inout vec3 gradient) { \n\
2385 float magnitude = length(gradient); \n\
2386 float factor = (fw_retainedOpacity + fw_boundaryOpacity*pow(magnitude,fw_opacityFactor) ); \n\
2387 voxel.a = voxel.a * factor; \n\
2388 //debug_color = HeatMapColor(factor,0.0,1.0); \n\
2390void PLUG_voxel_apply_BOUNDARY (inout vec4 voxel, inout vec3 gradient) { \n\
2391 voxel_apply_BOUNDARY(voxel, gradient); \n\
2393void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2394 voxel_apply_BOUNDARY(voxel, gradient); \n\
2399static const GLchar *plug_voxel_CARTOON =
"\n\
2400uniform int fw_colorSteps; \n\
2401uniform vec4 fw_orthoColor; \n\
2402uniform vec4 fw_paraColor; \n\
2403void voxel_apply_CARTOON (inout vec4 voxel, inout vec3 gradient) { \n\
2404 float len = length(gradient); \n\
2405 if(len > 0.01) { \n\
2406 vec3 ng = normalize(gradient); \n\
2407 float ndotv = dot(normal_eye,ng); \n\
2408 if(ndotv > 0.01 && voxel.a > 0.0) { \n\
2409 ndotv = floor(ndotv/float(fw_colorSteps))*float(fw_colorSteps); \n\
2410 vec4 color = mix(fw_orthoColor,fw_paraColor,ndotv); \n\
2411 //voxel.rgb = color.rgb*voxel.a; \n\
2412 voxel.rgb = color.rgb; \n\
2414 voxel = vec4(0.0); //similar to discard \n\
2417 voxel = vec4(0.0); //similar to discard \n\
2420void PLUG_voxel_apply_CARTOON (inout vec4 voxel, inout vec3 gradient) { \n\
2421 voxel_apply_CARTOON(voxel, gradient); \n\
2423void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2424 voxel_apply_CARTOON(voxel, gradient); \n\
2429static const GLchar *plug_voxel_COMPOSED =
"\
2430void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2435static const GLchar *plug_voxel_EDGE =
"\
2436uniform float fw_cosGradientThreshold; \n\
2437uniform vec4 fw_edgeColor; \n\
2438void voxel_apply_EDGE (inout vec4 voxel, inout vec3 gradient) { \n\
2439 float len = length(gradient); \n\
2440 if(len > 0.01) { \n\
2441 vec3 ng = normalize(gradient); \n\
2442 float ndotv = abs(dot(normal_eye,ng)); \n\
2443 if( ndotv < fw_cosGradientThreshold ) { \n\
2444 voxel = mix(voxel,fw_edgeColor,1.0 -ndotv); \n\
2448void PLUG_voxel_apply_EDGE (inout vec4 voxel, inout vec3 gradient) { \n\
2449 voxel_apply_EDGE(voxel, gradient); \n\
2451void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2452 voxel_apply_EDGE(voxel, gradient); \n\
2457static const GLchar *plug_voxel_PROJECTION =
"\n\
2458uniform float fw_intensityThreshold; \n\
2459uniform int fw_projType; \n\
2460float MAXPROJ = 0.0; \n\
2461float MINPROJ = 1.0; \n\
2462float AVEPROJ = 0.0; \n\
2463float LMIP = 0.0; \n\
2465int PROJCOUNT = 0; \n\
2466void voxel_apply_PROJECTION (inout vec4 voxel, inout vec3 gradient) { \n\
2468 float cval = length(voxel.rgb); \n\
2469 if(fw_projType == 1){ \n\
2471 if(cval < MINPROJ){ \n\
2473 RGBAPROJ = voxel; \n\
2475 }else if(fw_projType == 2){ \n\
2477 if(fw_intensityThreshold > 0.0){ \n\
2479 if(LMIP == 0.0) { \n\
2481 RGBAPROJ = voxel; \n\
2485 if(cval > MAXPROJ){ \n\
2487 RGBAPROJ = voxel; \n\
2490 }else if(fw_projType==3){ \n\
2492 AVEPROJ += cval; \n\
2493 RGBAPROJ += voxel; \n\
2496void PLUG_voxel_apply_PROJECTION (inout vec4 voxel, inout vec3 gradient) { \n\
2497 voxel_apply_PROJECTION(voxel, gradient); \n\
2499void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2500 voxel_apply_PROJECTION(voxel, gradient); \n\
2502void PLUG_ray_apply (inout vec4 raysum) { \n\
2503 float value = 0.0; \n\
2504 vec4 color = vec4(1.0); \n\
2505 if(fw_projType == 1){ \n\
2507 value = MINPROJ; \n\
2508 color = RGBAPROJ; \n\
2509 }else if(fw_projType == 2){ \n\
2511 if(fw_intensityThreshold > 0.0){ \n\
2514 color = RGBAPROJ; \n\
2517 value = MAXPROJ; \n\
2518 color = RGBAPROJ; \n\
2520 }else if(fw_projType==3){ \n\
2522 value = AVEPROJ / float(PROJCOUNT); \n\
2523 color = RGBAPROJ / float(PROJCOUNT); \n\
2525 //raysum.rgb = color.rgb * color.a; \n\
2526 //raysum.a = color.a; \n\
2528 raysum.rgb = vec3(value,value,value); \n\
2529// raysum.a = 1.0 - value; \n\
2530 //raysum.a = value;\n\
2531 //raysum.a = color.a; \n\
2532 //raysum = color; \n\
2537static const GLchar *plug_voxel_SHADED =
"\
2539#define MAX_LIGHTS 8 \n\
2540uniform int lightcount; \n\
2541//uniform float lightRadius[MAX_LIGHTS]; \n\
2542uniform int lightType[MAX_LIGHTS];//ANGLE like this \n\
2543struct fw_LightSourceParameters { \n\
2548 vec4 halfVector; \n\
2549 vec4 spotDirection; \n\
2550 float spotBeamWidth; \n\
2551 float spotCutoff; \n\
2552 vec3 Attenuations; \n\
2553 float lightRadius; \n\
2556uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ;\n\
2563 float visibilityRange; \n\
2565 int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL \n\
2566 // ifdefed int haveFogCoords; \n\
2568uniform fogParams fw_fogparams; \n\
2572//per-fragment lighting ie phong \n\
2573struct fw_MaterialParameters { \n\
2578 float shininess; \n\
2580uniform fw_MaterialParameters fw_FrontMaterial; \n\
2582uniform fw_MaterialParameters fw_BackMaterial; \n\
2584vec3 castle_ColorES; \n\
2586//per-vertex lighting - interpolated Emissive-specular \n\
2587varying vec3 castle_ColorES; //emissive shininess term \n\
2590uniform int fw_phase; \n\
2591uniform int fw_lighting; \n\
2592uniform int fw_shadows; \n\
2593void voxel_apply_SHADED (inout vec4 voxel, inout vec3 gradient) { \n\
2594 float len = length(gradient); \n\
2595 vec3 ng = vec3(0.0); \n\
2597 ng = normalize(gradient); \n\
2598 vec4 color = vec4(1.0); \n\
2600 vec3 castle_ColorES = fw_FrontMaterial.specular.rgb; \n\
2601 color.rgb = fw_FrontMaterial.diffuse.rgb; \n\
2603 color.rgb = vec3(0,0,0.0,0.0); \n\
2604 vec3 castle_ColorES = vec3(0.0,0.0,0.0); \n\
2606 // void add_light_contribution2(inout vec4 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float shininess ); \n\
2607 vec4 vertex_eye4 = vec4(vertex_eye,1.0); \n\
2608 /* PLUG: add_light_contribution2 (color, castle_ColorES, vertex_eye4, ng, fw_FrontMaterial.shininess) */ \n\
2609 // voxel.rgb = color.rgb; \n\
2610 color.rgb = mix(color.rgb,castle_ColorES,dot(ng,normal_eye)); \n\
2611 voxel.rgb = color.rgb; \n\
2612 //voxel.rgb = voxel.rgb * color.rgb; \n\
2614void PLUG_voxel_apply_SHADED (inout vec4 voxel, inout vec3 gradient) { \n\
2615 voxel_apply_SHADED(voxel, gradient); \n\
2617void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2618 voxel_apply_SHADED(voxel, gradient); \n\
2623static const GLchar *plug_voxel_SILHOUETTE =
"\n\
2624uniform float fw_BoundaryOpacity; \n\
2625uniform float fw_RetainedOpacity; \n\
2626uniform float fw_Sharpness; \n\
2627void voxel_apply_SILHOUETTE (inout vec4 voxel, inout vec3 gradient) { \n\
2628 float len = length(gradient); \n\
2629 if(len > 0.01) { \n\
2630 vec3 ng = normalize(gradient); \n\
2631 float ndotv = abs(dot(ng,normal_eye)); \n\
2632 float factor = (fw_RetainedOpacity + fw_BoundaryOpacity*pow(1.0 - ndotv,fw_Sharpness)); \n\
2633 //float factor = (fw_RetainedOpacity + pow(fw_BoundaryOpacity*(1.0 - ndotv),fw_Sharpness)); \n\
2634 //debug_color = HeatMapColor(factor,0.0,1.0); \n\
2635 voxel.a = voxel.a * factor; \n\
2638void PLUG_voxel_apply_SILHOUETTE (inout vec4 voxel, inout vec3 gradient) { \n\
2639 voxel_apply_SILHOUETTE(voxel, gradient); \n\
2641void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2642 voxel_apply_SILHOUETTE(voxel, gradient); \n\
2647static const GLchar *plug_voxel_TONE =
"\
2648uniform vec4 fw_coolColor; \n\
2649uniform vec4 fw_warmColor; \n\
2650void voxel_apply_TONE (inout vec4 voxel, inout vec3 gradient) { \n\
2651 float len = length(gradient); \n\
2654 vec3 ng = normalize(gradient); \n\
2655 //vec3 L = normalize(vec3(-.707,-.707,.707)); \n\
2656 float cc = (1.0 + dot(normal_eye,ng))*.5; \n\
2657 //float cc = (1.0 + dot(L,ng))*.5; \n\
2658 //debug_color = HeatMapColor(cc,0.0,1.0); \n\
2659 color = mix(fw_coolColor.rgb,fw_warmColor.rgb,cc); \n\
2660 voxel = vec4(color,voxel.a); \n\
2663 //debug_color = vec4(0.0); \n\
2666void PLUG_voxel_apply_TONE (inout vec4 voxel, inout vec3 gradient) { \n\
2667 voxel_apply_TONE(voxel, gradient); \n\
2669void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) { \n\
2670 voxel_apply_TONE(voxel, gradient); \n\
2681static const GLchar *volumeBlendedFragmentGLES2 =
" \n\
2684//precision highp float; \n\
2685precision mediump float; \n\
2687 vec4 HeatMapColor(float value, float minValue, float maxValue) \n\
2689 //used for debugging. If min=0,max=1 then magenta is 0, blue,green,yellow, red is 1 \n\
2691 int HEATMAP_COLORS_COUNT; \n\
2693 HEATMAP_COLORS_COUNT = 6; \n\
2694 colors[0] = vec4(0.32, 0.00, 0.32, 1.0); \n\
2695 colors[1] = vec4( 0.00, 0.00, 1.00, 1.00); \n\
2696 colors[2] = vec4(0.00, 1.00, 0.00, 1.00); \n\
2697 colors[3] = vec4(1.00, 1.00, 0.00, 1.00); \n\
2698 colors[4] = vec4(1.00, 0.60, 0.00, 1.00); \n\
2699 colors[5] = vec4(1.00, 0.00, 0.00, 1.00); \n\
2700 float ratio=(float(HEATMAP_COLORS_COUNT)-1.0)*clamp((value-minValue)/(maxValue-minValue),0.0,1.0); \n\
2701 int indexMin=int(floor(ratio)); \n\
2702 int indexMax= indexMin+1 < HEATMAP_COLORS_COUNT-1 ? indexMin+1 : HEATMAP_COLORS_COUNT-1; \n\
2703 ret = mix(colors[indexMin], colors[indexMax], ratio-float(indexMin)); \n\
2704 if(value < minValue) ret = vec4(0.0,0.0,0.0,1.0); \n\
2705 if(value > maxValue) ret = vec4(1.0,1.0,1.0,1.0); \n\
2708vec4 debug_color; \n\
2710uniform vec4 fw_viewport; \n\
2711uniform sampler2D fw_Texture_unit0; \n\
2712uniform sampler2D fw_Texture_unit1; \n\
2713uniform sampler2D fw_Texture_unit2; \n\
2714uniform sampler2D fw_Texture_unit3; \n\
2715uniform float fw_iwtc1; \n\
2716uniform float fw_iwtc2; \n\
2717uniform int fw_iwtf1; \n\
2718uniform int fw_iwtf2; \n\
2719uniform int fw_haveTransfers; \n\
2720vec3 weightcolor( in vec3 color, in int func, in float wt, in float ov, in float oblend, in sampler2D table){ \n\
2723 ret = color * wt; \n\
2724 }else if(func == 2){ \n\
2725 ret = color * ov; \n\
2726 }else if(func == 3){ \n\
2727 ret = color * oblend; \n\
2728 }else if(func == 4){ \n\
2729 ret = color * (1.0 - oblend); \n\
2730 }else if(func == 5){ \n\
2731 vec2 texcoord = color.rg;\n\
2732 ret = color * texture2D(table,texcoord).r; \n\
2736float weightalpha( in float alpha, in int func, in float wt, in float ov, in float oblend, in sampler2D table){ \n\
2739 ret = alpha * wt; \n\
2740 }else if(func == 2){ \n\
2741 ret = alpha * ov; \n\
2742 }else if(func == 3){ \n\
2743 ret = alpha * oblend; \n\
2744 }else if(func == 4){ \n\
2745 ret = alpha * (1.0 - oblend); \n\
2746 }else if(func == 5){ \n\
2747 vec2 texcoord = vec2(alpha,0);\n\
2748 ret = alpha * texture2D(table,texcoord).r; \n\
2754 vec2 fc = (gl_FragCoord.xy - fw_viewport.xy) / fw_viewport.zw; \n\
2755 vec4 frag0 = texture2D(fw_Texture_unit0,fc); \n\
2756 vec4 frag1 = texture2D(fw_Texture_unit1,fc); \n\
2757 vec3 cv = frag0.rgb; \n\
2758 float ov = frag0.a; \n\
2759 vec3 cblend = frag1.rgb; \n\
2760 float oblend = frag1.a; \n\
2763 cvw = weightcolor(cv,fw_iwtf1,fw_iwtc1,ov,oblend,fw_Texture_unit2); \n\
2764 ovw = weightalpha(ov,fw_iwtf1,fw_iwtc1,ov,oblend,fw_Texture_unit2); \n\
2765 cbw = weightcolor(cblend,fw_iwtf2,fw_iwtc2,ov,oblend,fw_Texture_unit3); \n\
2766 obw = weightalpha(oblend,fw_iwtf2,fw_iwtc2,ov,oblend,fw_Texture_unit3); \n\
2767 vec3 cg = clamp( cvw + cbw, 0.0, 1.0); \n\
2768 float og = clamp(ovw + obw, 0.0, 1.0); \n\
2770 gl_FragColor = vec4(cg,og); \n\
2775const char *getVolumeVertex(
void){
2776 return volumeVertexGLES2;
2778const char *getVolumeFragment(){
2779 return volumeFragmentGLES2;
2781int getSpecificShaderSourceVolume (
const GLchar **vertexSource,
const GLchar **fragmentSource,
shaderflagsstruct whichOne)
2787 int retval, unique_int;
2788 unsigned int volflags;
2789 unsigned char volflag[7];
2791 char *CompleteCode[3];
2794 if(whichOne.usershaders )
2799 vs = strdup(getVolumeVertex());
2800 fs = strdup(getVolumeFragment());
2802 CompleteCode[SHADERPART_VERTEX] = vs;
2803 CompleteCode[SHADERPART_GEOMETRY] = NULL;
2804 if(whichOne.volume == SHADERFLAGS_VOLUME_STYLE_BLENDED << 4){
2805 CompleteCode[SHADERPART_FRAGMENT] = STRDUP(volumeBlendedFragmentGLES2);
2808 CompleteCode[SHADERPART_FRAGMENT] = fs;
2817 AddVersion(SHADERPART_VERTEX, 100, CompleteCode);
2818 AddVersion(SHADERPART_FRAGMENT, 100, CompleteCode);
2819 AddDefine(SHADERPART_FRAGMENT,
"MOBILE",CompleteCode);
2822 AddVersion(SHADERPART_VERTEX, 110, CompleteCode);
2823 AddVersion(SHADERPART_FRAGMENT, 110, CompleteCode);
2826 if(whichOne.volume == SHADERFLAGS_VOLUME_STYLE_BLENDED << 4){
2827 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
2828 *vertexSource = CompleteCode[SHADERPART_VERTEX];
2835 AddDefine(SHADERPART_FRAGMENT,
"TEX3D",CompleteCode);
2836 Plug(SHADERPART_FRAGMENT,plug_fragment_texture3D_apply_volume,CompleteCode,&unique_int);
2839 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_BASIC)){
2840 AddDefine(SHADERPART_FRAGMENT,
"BASIC",CompleteCode);
2842 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_ISO)){
2843 AddDefine(SHADERPART_FRAGMENT,
"ISO",CompleteCode);
2844 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_ISO_MODE3)){
2845 AddDefine(SHADERPART_FRAGMENT,
"ISO_MODE3",CompleteCode);
2848 if(DESIRE(whichOne.volume,SHADERFLAGS_VOLUME_DATA_SEGMENT)){
2849 AddDefine(SHADERPART_FRAGMENT,
"SEGMENT",CompleteCode);
2851 if(DESIRE(whichOne.base,CLIPPLANE_SHADER)){
2852 AddDefine(SHADERPART_FRAGMENT,
"CLIP",CompleteCode);
2858 volflags = whichOne.volume;
2862 int iflag = (volflags >> (7-i)*4) & 0xF;
2864 volflag[kflags] = iflag;
2869 for(k=0;k<kflags;k++){
2871 case SHADERFLAGS_VOLUME_STYLE_DEFAULT:
2872 AddDefine(SHADERPART_FRAGMENT,
"DEFAULT",CompleteCode);
2873 Plug(SHADERPART_FRAGMENT,plug_voxel_DEFAULT,CompleteCode,&unique_int);
2875 case SHADERFLAGS_VOLUME_STYLE_OPACITY:
2876 AddDefine(SHADERPART_FRAGMENT,
"OPACITY",CompleteCode);
2877 Plug(SHADERPART_FRAGMENT,plug_voxel_OPACITY,CompleteCode,&unique_int);
2879 case SHADERFLAGS_VOLUME_STYLE_BLENDED:
2880 AddDefine(SHADERPART_FRAGMENT,
"BLENDED",CompleteCode);
2881 Plug(SHADERPART_FRAGMENT,plug_voxel_BLENDED,CompleteCode,&unique_int);
2883 case SHADERFLAGS_VOLUME_STYLE_BOUNDARY:
2884 AddDefine(SHADERPART_FRAGMENT,
"BOUNDARY",CompleteCode);
2885 Plug(SHADERPART_FRAGMENT,plug_voxel_BOUNDARY,CompleteCode,&unique_int);
2887 case SHADERFLAGS_VOLUME_STYLE_CARTOON:
2888 AddDefine(SHADERPART_FRAGMENT,
"CARTOON",CompleteCode);
2889 Plug(SHADERPART_FRAGMENT,plug_voxel_CARTOON,CompleteCode,&unique_int);
2891 case SHADERFLAGS_VOLUME_STYLE_COMPOSED:
2892 AddDefine(SHADERPART_FRAGMENT,
"COMPOSED",CompleteCode);
2893 Plug(SHADERPART_FRAGMENT,plug_voxel_COMPOSED,CompleteCode,&unique_int);
2895 case SHADERFLAGS_VOLUME_STYLE_EDGE:
2896 AddDefine(SHADERPART_FRAGMENT,
"EDGE",CompleteCode);
2897 Plug(SHADERPART_FRAGMENT,plug_voxel_EDGE,CompleteCode,&unique_int);
2899 case SHADERFLAGS_VOLUME_STYLE_PROJECTION:
2900 AddDefine(SHADERPART_FRAGMENT,
"PROJECTION",CompleteCode);
2901 Plug(SHADERPART_FRAGMENT,plug_voxel_PROJECTION,CompleteCode,&unique_int);
2903 case SHADERFLAGS_VOLUME_STYLE_SHADED:
2904 AddDefine(SHADERPART_FRAGMENT,
"SHADED",CompleteCode);
2905 Plug(SHADERPART_FRAGMENT,plug_voxel_SHADED,CompleteCode,&unique_int);
2908 AddDefine(SHADERPART_FRAGMENT,
"LIT",CompleteCode);
2909 AddDefine(SHADERPART_FRAGMENT,
"LITE",CompleteCode);
2910 Plug(SHADERPART_FRAGMENT,plug_vertex_lighting_ADSLightModel,CompleteCode,&unique_int);
2912 case SHADERFLAGS_VOLUME_STYLE_SILHOUETTE:
2913 AddDefine(SHADERPART_FRAGMENT,
"SILHOUETTE",CompleteCode);
2914 Plug(SHADERPART_FRAGMENT,plug_voxel_SILHOUETTE,CompleteCode,&unique_int);
2916 case SHADERFLAGS_VOLUME_STYLE_TONE:
2917 AddDefine(SHADERPART_FRAGMENT,
"TONE",CompleteCode);
2918 Plug(SHADERPART_FRAGMENT,plug_voxel_TONE,CompleteCode,&unique_int);
2930 *fragmentSource = CompleteCode[SHADERPART_FRAGMENT];
2931 *vertexSource = CompleteCode[SHADERPART_VERTEX];
2938 FILE *fp = fopen(
"C:/tmp/composed_shader.vert",
"w+");
2939 fwrite(*vertexSource,strlen(*vertexSource),1,fp);
2941 fp = fopen(
"C:/tmp/composed_shader.frag",
"w+");
2942 fwrite(*fragmentSource,strlen(*fragmentSource),1,fp);