evas: Evas_3D - refactor shader system.
authorDmytro Dadyka <d.dadyka@samsung.com>
Wed, 18 Feb 2015 20:19:28 +0000 (21:19 +0100)
committerCedric BAIL <cedric@osg.samsung.com>
Wed, 18 Feb 2015 21:42:07 +0000 (22:42 +0100)
Reviewers: Hermet, raster, jpeg, cedric

Subscribers: artem.popov, cedric

Differential Revision: https://phab.enlightenment.org/D1947

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
20 files changed:
.gitignore
src/Makefile_Evas.am
src/modules/evas/engines/gl_common/evas_gl_3d.c
src/modules/evas/engines/gl_common/evas_gl_3d_private.h
src/modules/evas/engines/gl_common/evas_gl_3d_shader.c
src/modules/evas/engines/gl_common/shader_3d/color_pick_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/color_pick_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/diffuse_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/diffuse_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/flat_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/flat_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh [new file with mode: 0755]
src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/normal_map_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/phong_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/phong_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/shadow_map_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/shadow_map_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/vertex_color_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader_3d/vertex_color_vert.shd [new file with mode: 0644]

index 4f04840..96345bf 100644 (file)
@@ -67,4 +67,5 @@ tags
 /config.rpath
 /coverage
 /src/lib/ecore_x/ecore_x_vsync
+/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x
 Session.vim
index 0651d7f..3cfbced 100644 (file)
@@ -586,6 +586,7 @@ modules/evas/engines/gl_common/evas_gl_api.c \
 modules/evas/engines/gl_common/evas_gl_api_gles1.c \
 modules/evas/engines/gl_common/evas_gl_api_ext.c \
 modules/evas/engines/gl_common/shader/evas_gl_shaders.x \
+modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x \
 modules/evas/engines/gl_common/shader/evas_gl_enum.x
 
 # 3D
@@ -729,6 +730,35 @@ modules/evas/engines/gl_common/shader/evas_gl_shaders.x: modules/evas/engines/gl
 
 modules/evas/engines/gl_common/shader/evas_gl_enum.x: modules/evas/engines/gl_common/shader/evas_gl_shaders.x
 
+# NOTE: order here should be equal with modes in file Evas_Eo.h
+GL_SHADERS_3D_GEN = \
+modules/evas/engines/gl_common/shader_3d/vertex_color_vert.shd \
+modules/evas/engines/gl_common/shader_3d/vertex_color_frag.shd \
+modules/evas/engines/gl_common/shader_3d/diffuse_vert.shd \
+modules/evas/engines/gl_common/shader_3d/diffuse_frag.shd \
+modules/evas/engines/gl_common/shader_3d/flat_vert.shd \
+modules/evas/engines/gl_common/shader_3d/flat_frag.shd \
+modules/evas/engines/gl_common/shader_3d/phong_vert.shd \
+modules/evas/engines/gl_common/shader_3d/phong_frag.shd \
+modules/evas/engines/gl_common/shader_3d/normal_map_vert.shd \
+modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd \
+modules/evas/engines/gl_common/shader_3d/shadow_map_vert.shd \
+modules/evas/engines/gl_common/shader_3d/shadow_map_frag.shd \
+modules/evas/engines/gl_common/shader_3d/color_pick_vert.shd \
+modules/evas/engines/gl_common/shader_3d/color_pick_frag.shd \
+$(NULL)
+
+EXTRA_DIST += \
+modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh
+
+BUILT_SOURCES += \
+modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x
+
+modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x: modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh $(GL_SHADERS_3D_GEN)
+       @echo "  SHADERS_3D  $@"
+       @modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh $(GL_SHADERS_3D_GEN)
+
+
 GL_GENERIC_SOURCES = \
 modules/evas/engines/gl_generic/evas_engine.c \
 modules/evas/engines/gl_generic/Evas_Engine_GL_Generic.h
index b1b277d..403aea6 100644 (file)
@@ -1144,13 +1144,10 @@ _mesh_draw_data_build(E3D_Draw_Data *data,
      }
 
    if (pdmesh->shadowed)
-        data->flags |= E3D_SHADER_FLAG_SHADOWED;
+     data->flags |= E3D_SHADER_FLAG_SHADOWED;
 
    if (pdmesh->color_pick_enabled)
-     {
-        data->flags |= E3D_SHADER_FLAG_COLOR_PICK_ENABLED;
-        data->color_pick_key = pdmesh->color_pick_key;
-     }
+     data->color_pick_key = pdmesh->color_pick_key;
 
    data->blending = pdmesh->blending;
    data->blend_sfactor = pdmesh->blend_sfactor;
index 6d956f5..78ddc42 100644 (file)
@@ -7,6 +7,7 @@ typedef struct _E3D_Program   E3D_Program;
 typedef struct _E3D_Draw_Data E3D_Draw_Data;
 typedef unsigned long         E3D_Shader_Flag;
 
+// NOTE: order here should be equal with flag names in file evas_gl_3d_shader.c
 #define E3D_SHADER_FLAG_NORMALIZE_NORMALS       (1 << 0)
 #define E3D_SHADER_FLAG_VERTEX_POSITION         (1 << 1)
 #define E3D_SHADER_FLAG_VERTEX_POSITION_BLEND   (1 << 2)
@@ -25,19 +26,19 @@ typedef unsigned long         E3D_Shader_Flag;
 #define E3D_SHADER_FLAG_DIFFUSE                 (1 << 15)
 #define E3D_SHADER_FLAG_SPECULAR                (1 << 16)
 #define E3D_SHADER_FLAG_EMISSION                (1 << 17)
-#define E3D_SHADER_FLAG_DIFFUSE_TEXTURE         (1 << 19)
-#define E3D_SHADER_FLAG_AMBIENT_TEXTURE         (1 << 20)
-#define E3D_SHADER_FLAG_SPECULAR_TEXTURE        (1 << 21)
-#define E3D_SHADER_FLAG_EMISSION_TEXTURE        (1 << 22)
-#define E3D_SHADER_FLAG_NORMAL_TEXTURE          (1 << 23)
-#define E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND   (1 << 24)
-#define E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND   (1 << 25)
-#define E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND  (1 << 26)
-#define E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND  (1 << 27)
-#define E3D_SHADER_FLAG_NORMAL_TEXTURE_BLEND    (1 << 28)
-#define E3D_SHADER_FLAG_FOG_ENABLED             (1 << 29)
-#define E3D_SHADER_FLAG_SHADOWED                (1 << 30)
-#define E3D_SHADER_FLAG_COLOR_PICK_ENABLED      (1 << 31)
+#define E3D_SHADER_FLAG_DIFFUSE_TEXTURE         (1 << 18)
+#define E3D_SHADER_FLAG_AMBIENT_TEXTURE         (1 << 19)
+#define E3D_SHADER_FLAG_SPECULAR_TEXTURE        (1 << 20)
+#define E3D_SHADER_FLAG_EMISSION_TEXTURE        (1 << 21)
+#define E3D_SHADER_FLAG_NORMAL_TEXTURE          (1 << 22)
+#define E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND   (1 << 23)
+#define E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND   (1 << 24)
+#define E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND  (1 << 25)
+#define E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND  (1 << 26)
+#define E3D_SHADER_FLAG_NORMAL_TEXTURE_BLEND    (1 << 27)
+#define E3D_SHADER_FLAG_FOG_ENABLED             (1 << 28)
+#define E3D_SHADER_FLAG_SHADOWED                (1 << 29)
+#define E3D_SHADER_FLAG_COUNT                    30
 
 static inline Eina_Bool
 _flags_need_tex_coord(E3D_Shader_Flag flags)
index 757b265..4f8fced 100644 (file)
@@ -1,4 +1,5 @@
 #include "evas_gl_3d_private.h"
+#include "shader_3d/evas_gl_3d_shaders.x"
 
 typedef enum _E3D_Uniform
 {
@@ -54,6 +55,40 @@ typedef enum _E3D_Uniform
    E3D_UNIFORM_COUNT,
 } E3D_Uniform;
 
+static const char *shader_flag_names[] =
+{
+   "NORMALIZE_NORMALS",
+   "VERTEX_POSITION",
+   "VERTEX_POSITION_BLEND",
+   "VERTEX_NORMAL",
+   "VERTEX_NORMAL_BLEND",
+   "VERTEX_TANGENT",
+   "VERTEX_TANGENT_BLEND",
+   "VERTEX_COLOR",
+   "VERTEX_COLOR_BLEND",
+   "VERTEX_TEXCOORD",
+   "VERTEX_TEXCOORD_BLEND",
+   "LIGHT_DIRECTIONAL",
+   "LIGHT_SPOT",
+   "LIGHT_ATTENUATION",
+   "AMBIENT",
+   "DIFFUSE",
+   "SPECULAR",
+   "EMISSION",
+   "DIFFUSE_TEXTURE",
+   "AMBIENT_TEXTURE",
+   "SPECULAR_TEXTURE",
+   "EMISSION_TEXTURE",
+   "NORMAL_TEXTURE",
+   "DIFFUSE_TEXTURE_BLEND",
+   "AMBIENT_TEXTURE_BLEND",
+   "SPECULAR_TEXTURE_BLEND",
+   "EMISSION_TEXTURE_BLEND",
+   "NORMAL_TEXTURE_BLEND",
+   "FOG_ENABLED",
+   "SHADOWED"
+};
+
 typedef struct _E3D_Shader_String
 {
    char *str;
@@ -117,1050 +152,21 @@ void _shader_string_add(E3D_Shader_String *shader, const char *str)
    shader->count += len;
 }
 
-#define ADD_LINE(str)   _shader_string_add(shader, str"\n")
-
-static void
-_vertex_shader_string_variable_add(E3D_Shader_String *shader,
-                                   Evas_3D_Shade_Mode mode, E3D_Shader_Flag flags)
-{
-   ADD_LINE("uniform mat4  uMatrixMvp;");
-
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("uniform mat4 uMatrixLight;");
-        ADD_LINE("varying vec4 lpos;");
-     }
-
-   /* Vertex attributes. */
-   if (flags & E3D_SHADER_FLAG_VERTEX_POSITION)
-     ADD_LINE("attribute   vec4  aPosition0;");
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_POSITION_BLEND)
-     {
-        ADD_LINE("attribute   vec4  aPosition1;");
-        ADD_LINE("uniform     float uPositionWeight;");
-     }
-
-   else if (mode == EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER) return;
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_NORMAL)
-     ADD_LINE("attribute   vec4  aNormal0;");
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_NORMAL_BLEND)
-     {
-        ADD_LINE("attribute   vec4  aNormal1;");
-        ADD_LINE("uniform     float uNormalWeight;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TANGENT)
-     ADD_LINE("attribute   vec4  aTangent0;");
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TANGENT_BLEND)
-     {
-        ADD_LINE("attribute   vec4  aTangent1;");
-        ADD_LINE("uniform     float uTangentWeight;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_COLOR)
-     ADD_LINE("attribute   vec4  aColor0;");
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_COLOR_BLEND)
-     {
-        ADD_LINE("attribute   vec4  aColor1;");
-        ADD_LINE("uniform     float uColorWeight;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TEXCOORD)
-     ADD_LINE("attribute   vec4  aTexCoord0;");
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TEXCOORD_BLEND)
-     {
-        ADD_LINE("attribute   vec4  aTexCoord1;");
-        ADD_LINE("uniform     float uTexCoordWeight;");
-     }
-
-   /* Texture coordinate. */
-   if (_flags_need_tex_coord(flags))
-     ADD_LINE("varying vec2 vTexCoord;");
-
-   /* Variables for each shade modes. */
-   if (mode == EVAS_3D_SHADE_MODE_VERTEX_COLOR)
-     {
-        ADD_LINE("varying     vec4  vColor;");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_DIFFUSE)
-     {
-        /* Nothing to declare. */
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     {
-        ADD_LINE("uniform   mat3  uMatrixNormal;");
-        ADD_LINE("uniform   mat4  uMatrixModelview;");
-        ADD_LINE("uniform   vec4  uLightPosition;");
-
-        ADD_LINE("varying   vec2  vFactor;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_SPOT)
-          {
-             ADD_LINE("uniform   vec3  uLightSpotDir;");
-             ADD_LINE("uniform   float uLightSpotExp;");
-             ADD_LINE("uniform   float uLightSpotCutoffCos;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR)
-          ADD_LINE("uniform float   uMaterialShininess;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-          ADD_LINE("uniform   vec3  uLightAtten;");
-   }
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG || mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     {
-        ADD_LINE("uniform  mat3  uMatrixNormal;");
-        ADD_LINE("uniform  mat4  uMatrixModelview;");
-        ADD_LINE("uniform  vec4  uLightPosition;");
-        ADD_LINE("varying  vec3  vLightVector;");
-        ADD_LINE("varying  vec3  vLightHalfVector;");
-
-       if (mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-          ADD_LINE("varying  vec3  vEyeVector;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-          ADD_LINE("varying  float vLightDist;");
-
-        if (mode == EVAS_3D_SHADE_MODE_PHONG || (flags & E3D_SHADER_FLAG_VERTEX_TANGENT) == 0)
-          ADD_LINE("varying   vec3  vNormal;");
-     }
-}
-
-static void
-_vertex_shader_string_func_flat_add(E3D_Shader_String *shader,
-                                    Evas_3D_Shade_Mode mode EINA_UNUSED, E3D_Shader_Flag flags)
-{
-   ADD_LINE("void vertexFlat(vec4 position, vec3 normal) {");
-
-   ADD_LINE("vec3  lv;");
-   ADD_LINE("float factor;");
-
-   ADD_LINE("normal = uMatrixNormal * normal;");
-   ADD_LINE("position = uMatrixModelview * position;");
-
-   if (flags & E3D_SHADER_FLAG_NORMALIZE_NORMALS)
-     ADD_LINE("normal = normalize(normal);");
-
-   if (flags & E3D_SHADER_FLAG_LIGHT_DIRECTIONAL)
-     {
-        ADD_LINE("lv = uLightPosition.xyz;");
-     }
-   else
-     {
-        ADD_LINE("lv = uLightPosition.xyz - position.xyz;");
-        ADD_LINE("lv = normalize(lv);");
-     }
-
-   ADD_LINE("factor = max(dot(lv, normal), 0.0);");
-
-   if (flags & E3D_SHADER_FLAG_LIGHT_SPOT)
-     {
-        ADD_LINE("float f = dot(-lv, uLightSpotDir);");
-        ADD_LINE("if (f > uLightSpotCutoffCos)");
-        ADD_LINE("factor *= pow(f, uLightSpotExp);");
-        ADD_LINE("else");
-        ADD_LINE("factor = 0.0;");
-     }
-
-   ADD_LINE("if (factor > 0.0) {");
-
-   /* Diffuse term. */
-   if (flags & E3D_SHADER_FLAG_DIFFUSE)
-     ADD_LINE("vFactor.x = factor;");
-   else
-     ADD_LINE("vFactor.x = 0.0;");
-
-   /* Specular term. */
-   if (flags & E3D_SHADER_FLAG_SPECULAR)
-     {
-        ADD_LINE("vec3  hv = normalize(normalize(-position.xyz) + lv);");
-        ADD_LINE("factor = pow(max(dot(hv, normal), 0.0), uMaterialShininess);");
-        ADD_LINE("vFactor.y = factor;");
-     }
-
-   ADD_LINE("} else {");
-   ADD_LINE("vFactor = vec2(0.0, 0.0);");
-   ADD_LINE("}");
-
-   /* Light attenuation. */
-   if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-     {
-        ADD_LINE("float dist = length(lv);");
-        ADD_LINE("vFactor /= dot(uLightAtten, vec3(1.0, dist, dist * dist));");
-     }
-
-   ADD_LINE("}");
-}
-
-static void
-_vertex_shader_string_func_phong_add(E3D_Shader_String *shader,
-                                     Evas_3D_Shade_Mode mode EINA_UNUSED, E3D_Shader_Flag flags)
-{
-   ADD_LINE("void vertexPhong(vec4 position, vec3 normal) {");
-
-   ADD_LINE("normal = uMatrixNormal * normal;");
-   ADD_LINE("position = uMatrixModelview * position;");
-
-   if (flags & E3D_SHADER_FLAG_NORMALIZE_NORMALS)
-     ADD_LINE("normal = normalize(normal);");
-
-   if (flags & E3D_SHADER_FLAG_LIGHT_DIRECTIONAL)
-     {
-        ADD_LINE("vLightVector = uLightPosition.xyz;");
-     }
-   else
-     {
-        ADD_LINE("vLightVector = uLightPosition.xyz - position.xyz;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-          ADD_LINE("vLightDist = length(vLightVector);");
-
-        ADD_LINE("vLightVector = normalize(vLightVector);");
-     }
-
-   ADD_LINE("vLightHalfVector = normalize(normalize(-position.xyz) + vLightVector);");
-   ADD_LINE("vNormal = normal;");
-   ADD_LINE("}");
-}
-
-static void
-_vertex_shader_string_func_normal_map_add(E3D_Shader_String *shader,
-                                          Evas_3D_Shade_Mode mode EINA_UNUSED,
-                                          E3D_Shader_Flag flags)
-{
-   if ((flags & E3D_SHADER_FLAG_VERTEX_TANGENT) == 0)
-     {
-        ADD_LINE("void vertexNormalMap(vec4 position, vec3 normal) {");
-
-        ADD_LINE("normal = uMatrixNormal * normal;");
-        ADD_LINE("position = uMatrixModelview * position;");
-        ADD_LINE("vEyeVector = normalize(-position.xyz);");
-
-        if (flags & E3D_SHADER_FLAG_NORMALIZE_NORMALS)
-          ADD_LINE("normal = normalize(normal);");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_DIRECTIONAL)
-          {
-             ADD_LINE("vLightVector = uLightPosition.xyz;");
-          }
-        else
-          {
-             ADD_LINE("vLightVector = uLightPosition.xyz - position.xyz;");
-
-             if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-               ADD_LINE("vLightDist = length(vLightVector);");
-
-             ADD_LINE("vLightVector = normalize(vLightVector);");
-          }
-
-        ADD_LINE("vLightHalfVector = normalize(vEyeVector + vLightVector);");
-        ADD_LINE("vNormal = normal;");
-        ADD_LINE("}");
-     }
-   else
-     {
-        ADD_LINE("void vertexNormalMap(vec4 position, vec3 normal, vec3 tangent) {");
-
-        ADD_LINE("vec3 n = normalize(uMatrixNormal * normal);");
-        ADD_LINE("vec3 t = normalize(uMatrixNormal * tangent);");
-        ADD_LINE("vec3 b = cross(n, t);");
-        ADD_LINE("vec3 tmp;");
-
-        ADD_LINE("position = uMatrixModelview * position;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_DIRECTIONAL)
-          {
-             ADD_LINE("vec3 lightDir = uLightPosition.xyz;");
-          }
-        else
-          {
-             ADD_LINE("vec3 lightDir = uLightPosition.xyz - position.xyz;");
-
-             if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-               ADD_LINE("vLightDist = length(lightDir);");
-
-             ADD_LINE("lightDir = normalize(lightDir);");
-          }
-
-        ADD_LINE("tmp.x = dot(lightDir, t);");
-        ADD_LINE("tmp.y = dot(lightDir, b);");
-        ADD_LINE("tmp.z = dot(lightDir, n);");
-        ADD_LINE("vLightVector = tmp;");
-
-        ADD_LINE("tmp.x = dot(position.xyz, t);");
-        ADD_LINE("tmp.y = dot(position.xyz, b);");
-        ADD_LINE("tmp.z = dot(position.xyz, n);");
-        ADD_LINE("vEyeVector = normalize(tmp);");
-
-        ADD_LINE("vec3 hv = normalize(normalize(-position.xyz) + lightDir);");
-        ADD_LINE("tmp.x = dot(hv, t);");
-        ADD_LINE("tmp.y = dot(hv, b);");
-        ADD_LINE("tmp.z = dot(hv, n);");
-        ADD_LINE("vLightHalfVector = tmp;");
-
-        ADD_LINE("}");
-     }
-}
-
-static void
-_vertex_shader_string_get(E3D_Shader_String *shader,
-                          Evas_3D_Shade_Mode mode, E3D_Shader_Flag flags)
-{
-   /* Add variables - vertex attributes. */
-   _vertex_shader_string_variable_add(shader, mode, flags);
-
-   /* Add functions. */
-   if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     _vertex_shader_string_func_flat_add(shader, mode, flags);
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG)
-     _vertex_shader_string_func_phong_add(shader, mode, flags);
-   else if (mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     _vertex_shader_string_func_normal_map_add(shader, mode, flags);
-
-   ADD_LINE("void main() {");
-
-   /* Process vertex attributes. */
-   if (flags & E3D_SHADER_FLAG_VERTEX_POSITION_BLEND)
-     {
-        ADD_LINE("vec4 position = aPosition0 * uPositionWeight + ");
-        ADD_LINE("aPosition1 * (1.0 - uPositionWeight);");
-        ADD_LINE("position = vec4(position.xyz, 1.0);");
-     }
-   else if (flags & E3D_SHADER_FLAG_VERTEX_POSITION)
-     {
-        ADD_LINE("vec4 position = vec4(aPosition0.xyz, 1.0);");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_NORMAL_BLEND)
-     {
-        ADD_LINE("vec3 normal = aNormal0.xyz * uNormalWeight + ");
-        ADD_LINE("aNormal1.xyz * (1.0 - uNormalWeight);");
-     }
-   else if (flags & E3D_SHADER_FLAG_VERTEX_NORMAL)
-     {
-        ADD_LINE("vec3 normal = aNormal0.xyz;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TANGENT_BLEND)
-     {
-        ADD_LINE("vec3 tangent = aTangent0.xyz * uTangentWeight + ");
-        ADD_LINE("aTangent1.xyz * (1.0 - uTangentWeight);");
-     }
-   else if (flags & E3D_SHADER_FLAG_VERTEX_TANGENT)
-     {
-        ADD_LINE("vec3 tangent = aTangent0.xyz;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_COLOR_BLEND)
-     {
-        ADD_LINE("vec4 color = aColor0 * uColorWeight + aColor1 * (1.0 - uColorWeight);");
-     }
-   else if (flags & E3D_SHADER_FLAG_VERTEX_COLOR)
-     {
-        ADD_LINE("vec4 color = aColor0;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_VERTEX_TEXCOORD_BLEND)
-     {
-        ADD_LINE("vTexCoord = aTexCoord0.st * uTexCoordWeight + ");
-        ADD_LINE("aTexCoord1.st * (1.0 - uTexCoordWeight);");
-     }
-   else if (flags & E3D_SHADER_FLAG_VERTEX_TEXCOORD)
-     {
-        ADD_LINE("vTexCoord = aTexCoord0.st;");
-     }
-
-   /* Transform vertex position. */
-   ADD_LINE("gl_Position = uMatrixMvp * position;");
-
-   /* Process according to the shade mode. */
-   if (mode == EVAS_3D_SHADE_MODE_VERTEX_COLOR)
-     {
-        ADD_LINE("vColor = color;");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     {
-        ADD_LINE("vertexFlat(position, normal);");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG)
-     {
-        ADD_LINE("vertexPhong(position, normal);");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     {
-        if (flags & E3D_SHADER_FLAG_VERTEX_TANGENT)
-          ADD_LINE("vertexNormalMap(position, normal, tangent);");
-        else
-          ADD_LINE("vertexNormalMap(position, normal);");
-     }
-
-     if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("lpos = uMatrixLight * position;");
-     }
-
-   ADD_LINE("}");
-}
-
-static void
-_fragment_shader_string_variable_add(E3D_Shader_String *shader,
-                                     Evas_3D_Shade_Mode mode, E3D_Shader_Flag flags)
-{
-   /* Texture coordinate. */
-   if (_flags_need_tex_coord(flags))
-     ADD_LINE("varying vec2   vTexCoord;");
-
-   if (flags & E3D_SHADER_FLAG_FOG_ENABLED)
-     {
-        ADD_LINE("uniform float uFogFactor;");
-        ADD_LINE("uniform vec4  uFogColor;");
-     }
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("varying vec4 lpos;");
-        ADD_LINE("uniform sampler2D uShadowMap;");
-     }
-
-       if (flags & E3D_SHADER_FLAG_COLOR_PICK_ENABLED)
-         ADD_LINE("uniform float uColorPick;");
-
-   /* Materials. */
-   if (flags & E3D_SHADER_FLAG_DIFFUSE)
-     {
-        ADD_LINE("uniform   vec4        uMaterialDiffuse;");
-
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE)
-          {
-             ADD_LINE("uniform sampler2D  uTextureDiffuse0;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND)
-          {
-             ADD_LINE("uniform sampler2D  uTextureDiffuse1;");
-             ADD_LINE("uniform float      uTextureDiffuseWeight;");
-          }
-     }
-
-   if (flags & E3D_SHADER_FLAG_SPECULAR)
-     {
-        ADD_LINE("uniform  vec4        uMaterialSpecular;");
-        ADD_LINE("uniform  float       uMaterialShininess;");
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE)
-          {
-             ADD_LINE("uniform sampler2D  uTextureSpecular0;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND)
-          {
-             ADD_LINE("uniform sampler2D  uTextureSpecular1;");
-             ADD_LINE("uniform float      uTextureSpecularWeight;");
-          }
-     }
-
-   if (flags & E3D_SHADER_FLAG_AMBIENT)
-     {
-        ADD_LINE("uniform  vec4        uMaterialAmbient;");
-
-        if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE)
-          {
-             ADD_LINE("uniform sampler2D  uTextureAmbient0;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND)
-          {
-             ADD_LINE("uniform sampler2D  uTextureAmbient1;");
-             ADD_LINE("uniform float      uTextureAmbientWeight;");
-          }
-     }
-
-   if (flags & E3D_SHADER_FLAG_EMISSION)
-     {
-        ADD_LINE("uniform vec4       uMaterialEmission;");
-
-        if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE)
-          {
-             ADD_LINE("uniform sampler2D  uTextureEmission0;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND)
-          {
-             ADD_LINE("uniform sampler2D  uTextureEmission1;");
-             ADD_LINE("uniform float      uTextureEmissionWeight;");
-          }
-     }
-
-   if (mode == EVAS_3D_SHADE_MODE_VERTEX_COLOR)
-     {
-        ADD_LINE("varying  vec4        vColor;");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_DIFFUSE)
-     {
-        /* Nothing to declare. */
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     {
-        ADD_LINE("varying vec2   vFactor;");
-
-        if (flags & E3D_SHADER_FLAG_DIFFUSE)
-          ADD_LINE("uniform   vec4        uLightDiffuse;");
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR)
-          ADD_LINE("uniform  vec4        uLightSpecular;");
-
-        if (flags & E3D_SHADER_FLAG_AMBIENT)
-          ADD_LINE("uniform  vec4        uLightAmbient;");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG || mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     {
-        ADD_LINE("varying  vec3        vLightVector;");
-        ADD_LINE("varying  vec3        vLightHalfVector;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_SPOT)
-          {
-             ADD_LINE("uniform   vec3  uLightSpotDir;");
-             ADD_LINE("uniform   float uLightSpotExp;");
-             ADD_LINE("uniform   float uLightSpotCutoffCos;");
-          }
-
-        if (flags & E3D_SHADER_FLAG_DIFFUSE)
-          ADD_LINE("uniform   vec4     uLightDiffuse;");
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR)
-          ADD_LINE("uniform   vec4     uLightSpecular;");
-
-        if (flags & E3D_SHADER_FLAG_AMBIENT)
-          ADD_LINE("uniform   vec4     uLightAmbient;");
-
-        if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-          ADD_LINE("varying   float    vLightDist;");
-
-        if (mode == EVAS_3D_SHADE_MODE_PHONG)
-          {
-             ADD_LINE("varying  vec3        vNormal;");
-          }
-        else /* Normal map. */
-          {
-             ADD_LINE("uniform  sampler2D   uTextureNormal0;");
-
-             if (flags & E3D_SHADER_FLAG_NORMAL_TEXTURE_BLEND)
-               {
-                  ADD_LINE("uniform  sampler2D  uTextureNormal1;");
-                  ADD_LINE("uniform  float      uTextureNormalWeight;");
-               }
-
-             ADD_LINE("varying  vec3        vEyeVector;");
-
-            if ((flags & E3D_SHADER_FLAG_VERTEX_TANGENT) == 0)
-              ADD_LINE("varying  vec3        vNormal;");
-          }
-     }
-}
-
-static void
-_fragment_shader_string_func_flat_add(E3D_Shader_String *shader,
-                                      Evas_3D_Shade_Mode mode EINA_UNUSED, E3D_Shader_Flag flags)
-{
-   ADD_LINE("void fragmentFlat() {");
-   ADD_LINE("vec4 color;");
-
-   if (flags & E3D_SHADER_FLAG_DIFFUSE)
-     {
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +");
-             ADD_LINE("texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);");
-             ADD_LINE("color *= uMaterialDiffuse;");
-          }
-        else if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord) * uMaterialDiffuse;");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialDiffuse;");
-          }
-
-        ADD_LINE("gl_FragColor = uLightDiffuse * color * vFactor.x;");
-     }
-   else
-     {
-        ADD_LINE("gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
-     }
-
-   if (flags & E3D_SHADER_FLAG_SPECULAR)
-     {
-        if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +");
-             ADD_LINE("texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);");
-             ADD_LINE("color *= uMaterialSpecular;");
-          }
-        else if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord) * uMaterialSpecular;");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialSpecular;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightSpecular * color * vFactor.y;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("gl_FragColor *= shadow;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_AMBIENT)
-     {
-        if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +");
-             ADD_LINE("texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight);");
-             ADD_LINE("color *= uMaterialAmbient;");
-          }
-        else if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord) * uMaterialAmbient;");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialAmbient;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightAmbient * color;");
-     }
-
-   if (flags & E3D_SHADER_FLAG_EMISSION)
-     {
-        if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +");
-             ADD_LINE("texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);");
-             ADD_LINE("color *= uMaterialEmission;");
-          }
-        else if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord) * uMaterialEmission;");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialEmission;");
-          }
-
-        ADD_LINE("gl_FragColor += color;");
-     }
-
-   ADD_LINE("}");
-}
-
-static void
-_fragment_shader_string_func_phong_add(E3D_Shader_String *shader,
-                                       Evas_3D_Shade_Mode mode EINA_UNUSED, E3D_Shader_Flag flags)
-{
-   ADD_LINE("void fragmentPhong() {");
-   ADD_LINE("vec3  normal = normalize(vNormal);");
-   ADD_LINE("vec3  lv = normalize(vLightVector);");
-   ADD_LINE("float factor = dot(lv, normal);");
-   ADD_LINE("vec4  color;");
-
-   if (flags & E3D_SHADER_FLAG_LIGHT_SPOT)
-     {
-        ADD_LINE("float f = dot(-lv, normalize(uLightSpotDir));");
-
-        ADD_LINE("if (f > uLightSpotCutoffCos)");
-        ADD_LINE("factor *= pow(f, uLightSpotExp);");
-        ADD_LINE("else");
-        ADD_LINE("factor = 0.0;");
-     }
-
-   ADD_LINE("if (factor > 0.0) {");
-
-   /* Diffuse term. */
-   if (flags & E3D_SHADER_FLAG_DIFFUSE)
-     {
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +");
-             ADD_LINE("texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialDiffuse;");
-          }
-
-        ADD_LINE("gl_FragColor = uLightDiffuse * color * factor;");
-     }
-   else
-     {
-        ADD_LINE("gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
-     }
-
-   /* Specular term. */
-   if (flags & E3D_SHADER_FLAG_SPECULAR)
-     {
-        ADD_LINE("factor = dot(normalize(vLightHalfVector), normal);");
-        ADD_LINE("if (factor > 0.0) {");
-        ADD_LINE("factor = pow(factor, uMaterialShininess);");
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +");
-             ADD_LINE("texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialSpecular;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightSpecular * color * factor;");
-        ADD_LINE("}");
-     }
-
-   ADD_LINE("} else {");
-   ADD_LINE("gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
-   ADD_LINE("}");
-
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("gl_FragColor *= shadow;");
-     }
-
-   /* Ambient term. */
-   if (flags & E3D_SHADER_FLAG_AMBIENT)
-     {
-        if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +");
-             ADD_LINE("texture2D(uTextureAmbient1 * vTexCoord) * (1.0 - uTextureAmbientWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialAmbient;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightAmbient * color;");
-     }
-
-   /* Light attenuation. */
-   if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-     ADD_LINE("gl_FragColor /= dot(uLightAtten, vec3(1.0, vLightDist, vLightDist * vLightDist));");
-
-   /* Emission term. */
-   if (flags & E3D_SHADER_FLAG_EMISSION)
-     {
-        if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +");
-             ADD_LINE("texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialEmission;");
-          }
-
-        ADD_LINE("gl_FragColor += color;");
-     }
-
-   ADD_LINE("}");
-}
-
-static void
-_fragment_shader_string_func_normal_map_add(E3D_Shader_String *shader,
-                                            Evas_3D_Shade_Mode mode EINA_UNUSED,
-                                            E3D_Shader_Flag flags)
+void _shader_flags_add(E3D_Shader_String *shader, E3D_Shader_Flag flags)
 {
-   if ((flags & E3D_SHADER_FLAG_VERTEX_TANGENT) == 0)
-     {
-        ADD_LINE("mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv) {");
-        ADD_LINE("vec3 dp1 = dFdx(p);");
-        ADD_LINE("vec3 dp2 = dFdy(p);");
-        ADD_LINE("vec2 duv1 = dFdx(uv);");
-        ADD_LINE("vec2 duv2 = dFdy(uv);");
-        ADD_LINE("vec3 dp2perp = cross(dp2, n);");
-        ADD_LINE("vec3 dp1perp = cross(n, dp1);");
-        ADD_LINE("vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;");
-        ADD_LINE("vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;");
-        ADD_LINE("float invmax = inversesqrt(max(dot(t, t), dot(b, b)));");
-        ADD_LINE("return mat3(t * invmax, b * invmax, n);");
-        ADD_LINE("}");
-
-        ADD_LINE("vec3 perturb_normal(vec3 normal) {");
-        ADD_LINE("mat3 tbn = cotangent_frame(vNormal, -vEyeVector, vTexCoord);");
-        ADD_LINE("return normalize(tbn * normal);");
-        ADD_LINE("}");
-     }
-
-   ADD_LINE("void fragmentNormalMap() {");
-   ADD_LINE("float factor;");
-   ADD_LINE("vec3  normal;");
-   ADD_LINE("vec4  color;");
-
-   if (flags & E3D_SHADER_FLAG_NORMAL_TEXTURE_BLEND)
-     {
-        ADD_LINE("normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight;");
-        ADD_LINE("normal += texture2D(uTextureNormal1, vTexCoord).rgb * ");
-        ADD_LINE("(1.0 - uTextureNormalWeight);");
-     }
-   else
-     {
-        ADD_LINE("normal = texture2D(uTextureNormal0, vTexCoord).rgb;");
-     }
-
-   ADD_LINE("normal = 2.0 * normal - 1.0;");
-
-   if ((flags & E3D_SHADER_FLAG_VERTEX_TANGENT) == 0)
-     {
-        ADD_LINE("normal = perturb_normal(normal);");
-     }
-
-   /* Can we skip this normalization?? */
-   ADD_LINE("vec3  lv = normalize(vLightVector);");
-   ADD_LINE("normal = normalize(normal);");
-
-   ADD_LINE("factor = dot(lv, normal);");
-
-   if (flags & E3D_SHADER_FLAG_LIGHT_SPOT)
-     {
-        ADD_LINE("float f = dot(-lv, normalize(uLightSpotDir));");
-
-        ADD_LINE("if (f > uLightSpotCutoffCos)");
-        ADD_LINE("factor *= pow(f, uLightSpotExp);");
-        ADD_LINE("else");
-        ADD_LINE("factor = 0.0;");
-     }
-
-   ADD_LINE("if (factor > 0.0) {");
-
-   /* Diffuse term. */
-   if (flags & E3D_SHADER_FLAG_DIFFUSE)
-     {
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +");
-             ADD_LINE("texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureDiffuse0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialDiffuse;");
-          }
-
-        ADD_LINE("gl_FragColor = uLightDiffuse * color * factor;");
-     }
-   else
-     {
-        ADD_LINE("gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
-     }
-
-   /* Specular term. */
-   if (flags & E3D_SHADER_FLAG_SPECULAR)
-     {
-        ADD_LINE("factor = dot(normalize(vLightHalfVector), normal);");
-        ADD_LINE("if (factor > 0.0) {");
-        ADD_LINE("factor = pow(factor, uMaterialShininess);");
-
-        if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +");
-             ADD_LINE("texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_SPECULAR_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureSpecular0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialSpecular;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightSpecular * color * factor;");
-        ADD_LINE("}");
-     }
-
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("gl_FragColor *= shadow;");
-     }
-
-   ADD_LINE("} else {");
-   ADD_LINE("gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
-   ADD_LINE("}");
-
-   /* Ambient term. */
-   if (flags & E3D_SHADER_FLAG_AMBIENT)
-     {
-        if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +");
-             ADD_LINE("texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_AMBIENT_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureAmbient0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialAmbient;");
-          }
-
-        ADD_LINE("gl_FragColor += uLightAmbient * color;");
-     }
-
-   /* Light attenuation. */
-   if (flags & E3D_SHADER_FLAG_LIGHT_ATTENUATION)
-     ADD_LINE("gl_FragColor /= dot(uLightAtten, vec3(1.0, vLightDist, vLightDist * vLightDist));");
-
-   /* Emission term. */
-   if (flags & E3D_SHADER_FLAG_EMISSION)
-     {
-        if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE_BLEND)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +");
-             ADD_LINE("texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);");
-          }
-        else if (flags & E3D_SHADER_FLAG_EMISSION_TEXTURE)
-          {
-             ADD_LINE("color = texture2D(uTextureEmission0, vTexCoord);");
-          }
-        else
-          {
-             ADD_LINE("color = uMaterialEmission;");
-          }
-
-        ADD_LINE("gl_FragColor += color;");
-     }
-
-   ADD_LINE("}");
-}
-
-static void
-_fragment_shader_string_pcf_even_func_add(E3D_Shader_String *shader,
-                                            Evas_3D_Shade_Mode mode EINA_UNUSED,
-                                            E3D_Shader_Flag flags EINA_UNUSED)
-{
-   ADD_LINE("float pcf(vec4 lpos, float size)");
-   ADD_LINE("{");
-   ADD_LINE("vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;");
-   ADD_LINE("float i, j, randx, randy, shadow;");
-   ADD_LINE("shadow = 0.0;");
-   ADD_LINE("for (i = -4.0; i < 4.0; i++)");
-   ADD_LINE("for (j = -4.0; j < 4.0; j++)");
-   ADD_LINE("{");
-   ADD_LINE("shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy +vec2(i / 8.0, j / 8.0)*size).x);");
-   ADD_LINE("}");
-   ADD_LINE("return shadow / 64.0;");
-   ADD_LINE("}");
-}
-
-static void
-_fragment_shader_string_get(E3D_Shader_String *shader,
-                            Evas_3D_Shade_Mode mode, E3D_Shader_Flag flags)
-{
-   /* Add variables - vertex attributes. */
-   _fragment_shader_string_variable_add(shader, mode, flags);
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("float shadow;");
-     }
-   /* Add functions. */
-   if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     _fragment_shader_string_func_flat_add(shader, mode, flags);
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG)
-     _fragment_shader_string_func_phong_add(shader, mode, flags);
-   else if (mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     _fragment_shader_string_func_normal_map_add(shader, mode, flags);
-
-   // TODO Add flexible bluring algorithm of shadows boundaries.
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     _fragment_shader_string_pcf_even_func_add(shader, mode, flags);
-
-   /* Add main function. */
-   ADD_LINE("void main() {");
-   if (flags & E3D_SHADER_FLAG_SHADOWED)
-     {
-        ADD_LINE("shadow = pcf(lpos, 1.0 / 200.0);");
-     }
-
-   if (mode == EVAS_3D_SHADE_MODE_VERTEX_COLOR)
-     {
-        ADD_LINE("gl_FragColor = vColor;");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_DIFFUSE)
-     {
-        if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE_BLEND)
-          {
-             ADD_LINE("gl_FragColor = (texture2D(uTextureDiffuse0, vTexCoord) *");
-             ADD_LINE("uTextureDiffuseWeight + texture2D(uTextureDiffuse1, vTexCoord) *");
-             ADD_LINE("(1.0 - uTextureDiffuseWeight)) * uMaterialDiffuse;");
-          }
-        else if (flags & E3D_SHADER_FLAG_DIFFUSE_TEXTURE)
-          {
-             ADD_LINE("gl_FragColor = texture2D(uTextureDiffuse0, vTexCoord) * uMaterialDiffuse;");
-          }
-        else
-          {
-             ADD_LINE("gl_FragColor = uMaterialDiffuse;");
-          }
-     }
-   else if(mode == EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER)
-     {
-        ADD_LINE("gl_FragColor = vec4(gl_FragCoord.z);");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_FLAT)
-     {
-        ADD_LINE("fragmentFlat();");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_PHONG)
-     {
-        ADD_LINE("fragmentPhong();");
-     }
-   else if (mode == EVAS_3D_SHADE_MODE_NORMAL_MAP)
-     {
-        ADD_LINE("fragmentNormalMap();");
-     }
-
-     if ((flags & E3D_SHADER_FLAG_FOG_ENABLED) && (mode != EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER))
-     {
-        ADD_LINE("float z = gl_FragCoord.z / gl_FragCoord.w;");
-        ADD_LINE("float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44 );");
-        ADD_LINE("fogFactor = clamp(fogFactor, 0.0, 1.0);");
-        ADD_LINE("gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor );");
-     }
-
-   if (mode == EVAS_3D_SHADE_MODE_COLOR_PICK)
-     {
-       ADD_LINE("gl_FragColor = vec4(uColorPick);");
-     }
+   int i;
 
-   ADD_LINE("}");
+   for (i = 0; i < E3D_SHADER_FLAG_COUNT; i++)
+     if (flags & (1 << i))
+       {
+          int len = strlen("#define ") + strlen(shader_flag_names[i]) + 2;
+          char str[len];
+          snprintf(str, len, "#define %s\n", shader_flag_names[i]);
+          _shader_string_add(shader, str);
+       }
+
+   if(_flags_need_tex_coord(flags))
+     _shader_string_add(shader, "#define NEED_TEX_COORD\n");
 }
 
 static inline Eina_Bool
@@ -1543,8 +549,11 @@ e3d_program_new(Evas_3D_Shade_Mode mode, E3D_Shader_Flag flags)
    program->mode = mode;
    program->flags = flags;
 
-   _vertex_shader_string_get(&vert, mode, flags);
-   _fragment_shader_string_get(&frag, mode, flags);
+   _shader_flags_add(&vert, flags);
+   _shader_string_add(&frag, vert.str);
+
+   _shader_string_add(&vert, vertex_shaders[mode]);
+   _shader_string_add(&frag, fragment_shaders[mode]);
 
    if (! _program_build(program, vert.str, frag.str))
      goto error;
diff --git a/src/modules/evas/engines/gl_common/shader_3d/color_pick_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/color_pick_frag.shd
new file mode 100644 (file)
index 0000000..5e0fc6c
--- /dev/null
@@ -0,0 +1,7 @@
+uniform float uColorPick;
+
+void main()
+{
+   gl_FragColor = vec4(uColorPick);
+}
+
diff --git a/src/modules/evas/engines/gl_common/shader_3d/color_pick_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/color_pick_vert.shd
new file mode 100644 (file)
index 0000000..472866f
--- /dev/null
@@ -0,0 +1,28 @@
+uniform mat4  uMatrixMvp;
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+void main()
+{
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+   gl_Position = uMatrixMvp * position;
+}
+
diff --git a/src/modules/evas/engines/gl_common/shader_3d/diffuse_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/diffuse_frag.shd
new file mode 100644 (file)
index 0000000..7b6dc2b
--- /dev/null
@@ -0,0 +1,47 @@
+#ifdef NEED_TEX_COORD
+varying vec2   vTexCoord;
+#endif //TEX_COORD
+
+#ifdef FOG_ENABLED
+uniform float uFogFactor;
+uniform vec4  uFogColor;
+#endif //FOG_ENABLED
+
+#ifdef DIFFUSE
+uniform   vec4        uMaterialDiffuse;
+
+#ifdef DIFFUSE_TEXTURE
+uniform sampler2D  uTextureDiffuse0;
+#endif //DIFFUSE_TEXTURE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+uniform sampler2D  uTextureDiffuse1;
+uniform float      uTextureDiffuseWeight;
+#endif //DIFFUSE_TEXTURE_BLEND
+
+#endif //DIFFUSE
+
+void main() {
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+   gl_FragColor = (texture2D(uTextureDiffuse0, vTexCoord) *
+   uTextureDiffuseWeight + texture2D(uTextureDiffuse1, vTexCoord) *
+   (1.0 - uTextureDiffuseWeight)) * uMaterialDiffuse;
+#else
+
+#ifdef DIFFUSE_TEXTURE
+   gl_FragColor = texture2D(uTextureDiffuse0, vTexCoord) * uMaterialDiffuse;
+#else
+   gl_FragColor = uMaterialDiffuse;
+#endif //DIFFUSE_TEXTURE
+
+#endif //DIFFUSE_TEXTURE_BLEND
+
+#ifdef FOG_ENABLED
+   float z = gl_FragCoord.z / gl_FragCoord.w;
+   float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);
+   fogFactor = clamp(fogFactor, 0.0, 1.0);
+   gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);
+#endif //FOG_ENABLED
+
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/diffuse_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/diffuse_vert.shd
new file mode 100644 (file)
index 0000000..2b62b82
--- /dev/null
@@ -0,0 +1,52 @@
+uniform mat4  uMatrixMvp;
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_TEXCOORD
+attribute   vec4  aTexCoord0;
+#endif //VERTEX_TEXCOORD
+
+#ifdef VERTEX_TEXCOORD_BLEND
+attribute   vec4  aTexCoord1;
+uniform     float uTexCoordWeight;
+#endif //VERTEX_TEXCOORD_BLEND
+
+#ifdef NEED_TEX_COORD
+varying vec2 vTexCoord;
+#endif //NEED_TEX_COORD
+
+void main()
+{
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_TEXCOORD_BLEND
+   vTexCoord = aTexCoord0.st * uTexCoordWeight +
+   aTexCoord1.st * (1.0 - uTexCoordWeight);
+#else
+
+#ifdef VERTEX_TEXCOORD
+   vTexCoord = aTexCoord0.st;
+#endif //VERTEX_TEXCOORD
+
+#endif //VERTEX_TEXCOORD_BLEND
+
+   gl_Position = uMatrixMvp * position;
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/flat_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/flat_frag.shd
new file mode 100644 (file)
index 0000000..824fb66
--- /dev/null
@@ -0,0 +1,195 @@
+varying vec2   vFactor;
+
+#ifdef NEED_TEX_COORD
+varying vec2   vTexCoord;
+#endif //TEX_COORD
+
+#ifdef FOG_ENABLED
+uniform float uFogFactor;
+uniform vec4  uFogColor;
+#endif //FOG_ENABLED
+
+#ifdef  SHADOWED
+varying vec4 vLightPosition;
+uniform sampler2D uShadowMap;
+float shadow;
+#endif //SHADOWED
+
+#ifdef DIFFUSE
+uniform   vec4        uMaterialDiffuse;
+uniform   vec4        uLightDiffuse;
+
+#ifdef DIFFUSE_TEXTURE
+uniform sampler2D  uTextureDiffuse0;
+#endif //DIFFUSE_TEXTURE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+uniform sampler2D  uTextureDiffuse1;
+uniform float      uTextureDiffuseWeight;
+#endif //DIFFUSE_TEXTURE_BLEND
+
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+uniform   vec4     uLightSpecular;
+uniform   float    uMaterialShininess;
+uniform   vec4     uMaterialSpecular;
+
+#ifdef SPECULAR_TEXTURE
+uniform sampler2D  uTextureSpecular0;
+#endif //SPECULAR_TEXTURE
+
+#ifdef SPECULAR_TEXTURE_BLEND
+uniform sampler2D  uTextureSpecular1;
+uniform float      uTextureSpecularWeight;
+#endif //SPECULAR_TEXTURE_BLEND
+
+#endif //SPECULAR
+
+#ifdef AMBIENT
+uniform  vec4       uMaterialAmbient;
+uniform  vec4       uLightAmbient;
+
+#ifdef AMBIENT_TEXTURE
+uniform sampler2D  uTextureAmbient0;
+#endif //AMBIENT_TEXTURE
+
+#ifdef AMBIENT_TEXTURE_BLEND
+uniform sampler2D  uTextureAmbient1;
+uniform float      uTextureAmbientWeight;
+#endif //AMBIENT_TEXTURE_BLEND
+
+#endif //AMBIENT
+
+#ifdef EMISSION
+uniform vec4       uMaterialEmission;
+
+#ifdef EMISSION_TEXTURE
+uniform sampler2D  uTextureEmission0;
+#endif //EMISSION_TEXTURE
+
+#ifdef EMISSION_TEXTURE_BLEND
+uniform sampler2D  uTextureEmission1;
+uniform float      uTextureEmissionWeight;
+#endif //EMISSION_TEXTURE_BLEND
+
+#endif //EMISSION
+
+#ifdef  SHADOWED
+float pcf(vec4 lpos, float size)
+{
+   vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;
+   float i, j, randx, randy, shadow;
+   shadow = 0.0;
+   for (i = -4.0; i < 4.0; i++)
+     for (j = -4.0; j < 4.0; j++)
+        shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy +vec2(i / 8.0, j / 8.0)*size).x);
+   return shadow / 64.0;
+}
+#endif //SHADOWED
+
+void fragmentFlat()
+{
+   vec4 color;
+
+#ifdef DIFFUSE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+        color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +
+        texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);
+        color *= uMaterialDiffuse;
+#else
+
+#ifdef  DIFFUSE_TEXTURE
+        color = texture2D(uTextureDiffuse0, vTexCoord)  * uMaterialDiffuse;
+#else
+        color = uMaterialDiffuse;
+#endif //DIFFUSE_TEXTURE
+
+#endif //DIFFUSE_TEXTURE_BLEND
+        gl_FragColor = uLightDiffuse * color * vFactor.x;
+#else
+        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+
+#ifdef SPECULAR_TEXTURE_BLEND
+   color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +
+   texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);
+   color *= uMaterialSpecular;
+#else
+
+#ifdef SPECULAR_TEXTURE
+   color = texture2D(uTextureSpecular0, vTexCoord) * uMaterialSpecular;
+#else
+   color = uMaterialSpecular;
+#endif //SPECULAR_TEXTURE
+
+#endif //SPECULAR_TEXTURE_BLEND
+
+   gl_FragColor += uLightSpecular * color * vFactor.y;
+
+#endif //SPECULAR
+
+#ifdef SHADOWED
+   gl_FragColor *= shadow;
+#endif //SHADOWED
+
+#ifdef E3D_SHADER_FLAG_AMBIENT
+
+#ifdef AMBIENT_TEXTURE_BLEND
+
+   color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +
+   texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight);
+   color *= uMaterialAmbient;
+
+#else
+
+#ifdef AMBIENT_TEXTURE
+   color = texture2D(uTextureAmbient0, vTexCoord) * uMaterialAmbient;
+#else
+   color = uMaterialAmbient;
+#endif //AMBIENT_TEXTURE
+
+#endif //AMBIENT_TEXTURE_BLEND
+   gl_FragColor += uLightAmbient * color;
+#endif //AMBIENT
+
+#ifdef EMISSION
+
+#ifdef EMISSION_TEXTURE_BLEND
+   color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +
+   texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);
+   color *= uMaterialEmission;
+#else
+
+#ifdef EMISSION_TEXTURE
+   color = texture2D(uTextureEmission0, vTexCoord) * uMaterialEmission;
+#else
+   color = uMaterialEmission;
+#endif //EMISSION_TEXTURE
+
+#endif //EMISSION_TEXTURE_BLEND
+
+   gl_FragColor += color;
+#endif //EMISSION
+
+}
+
+void main() {
+
+#ifdef SHADOWED
+   shadow = pcf(vLightPosition, 1.0 / 200.0);
+#endif //SHADOWED
+
+   fragmentFlat();
+
+#ifdef FOG_ENABLED
+   float z = gl_FragCoord.z / gl_FragCoord.w;
+   float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);
+   fogFactor = clamp(fogFactor, 0.0, 1.0);
+   gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);
+#endif //FOG_ENABLED
+
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/flat_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/flat_vert.shd
new file mode 100644 (file)
index 0000000..37aba1c
--- /dev/null
@@ -0,0 +1,154 @@
+uniform   mat4  uMatrixMvp;
+uniform   mat3  uMatrixNormal;
+uniform   mat4  uMatrixModelview;
+uniform   vec4  uLightPosition;
+varying   vec2  vFactor;
+
+#ifdef SHADOWED
+uniform mat4 uMatrixLight;
+varying vec4 vLightPosition;
+#endif //SHADOWED
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL
+attribute   vec4  aNormal0;
+#endif //VERTEX_NORMAL
+
+#ifdef VERTEX_NORMAL_BLEND
+attribute   vec4  aNormal1;
+uniform     float uNormalWeight;
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TEXCOORD
+attribute   vec4  aTexCoord0;
+#endif //VERTEX_TEXCOORD
+
+#ifdef VERTEX_TEXCOORD_BLEND
+attribute   vec4  aTexCoord1;
+uniform     float uTexCoordWeight;
+#endif //VERTEX_TEXCOORD_BLEND
+
+#ifdef NEED_TEX_COORD
+varying vec2 vTexCoord;
+#endif //NEED_TEX_COORD
+
+#ifdef LIGHT_SPOT
+uniform   vec3  uLightSpotDir;
+uniform   float uLightSpotExp;
+uniform   float uLightSpotCutoffCos;
+#endif //LIGHT_SPOT
+
+#ifdef SPECULAR
+uniform float   uMaterialShininess;
+#endif //SPECULAR
+
+#ifdef LIGHT_ATTENUATION
+uniform   vec3  uLightAtten;
+#endif //LIGHT_ATTENUATION
+
+void vertexFlat(vec4 position, vec3 normal)
+{
+   vec3  lv;
+   float factor;
+   normal = uMatrixNormal * normal;
+   position = uMatrixModelview * position;
+
+#ifdef NORMALIZE_NORMALS
+   normal = normalize(normal);
+#endif //NORMALIZE_NORMALS
+
+#ifdef LIGHT_DIRECTIONAL
+   lv = uLightPosition.xyz;
+#else
+   lv = uLightPosition.xyz - position.xyz;
+   lv = normalize(lv);
+#endif //LIGHT_DIRECTIONAL
+
+   factor = max(dot(lv, normal), 0.0);
+
+#ifdef LIGHT_SPOT
+   float f = dot(-lv, uLightSpotDir);
+   if (f > uLightSpotCutoffCos)
+     factor *= pow(f, uLightSpotExp);
+   else
+      factor = 0.0;
+#endif //LIGHT_SPOT
+
+   if (factor > 0.0)
+     {
+
+#ifdef DIFFUSE
+        vFactor.x = factor;
+#else
+        vFactor.x = 0.0;
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+        vec3  hv = normalize(normalize(-position.xyz) + lv);
+        factor = pow(max(dot(hv, normal), 0.0), uMaterialShininess);
+        vFactor.y = factor;
+#endif //SPECULAR
+
+     }
+   else
+     vFactor = vec2(0.0, 0.0);
+
+   /* Light attenuation. */
+#ifdef LIGHT_ATTENUATION
+   float dist = length(lv);
+   vFactor /= dot(uLightAtten, vec3(1.0, dist, dist * dist));
+#endif //LIGHT_ATTENUATION
+}
+
+void main()
+{
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL_BLEND
+   vec3 normal = aNormal0.xyz * uNormalWeight +
+   aNormal1.xyz * (1.0 - uNormalWeight);
+#else
+
+#ifdef VERTEX_NORMAL
+   vec3 normal = aNormal0.xyz;
+#endif //VERTEX_NORMAL
+
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TEXCOORD_BLEND
+   vTexCoord = aTexCoord0.st * uTexCoordWeight +
+   aTexCoord1.st * (1.0 - uTexCoordWeight);
+#else
+
+#ifdef VERTEX_TEXCOORD
+   vTexCoord = aTexCoord0.st;
+#endif //VERTEX_TEXCOORD
+
+#endif //VERTEX_TEXCOORD_BLEND
+
+   gl_Position = uMatrixMvp * position;
+   vertexFlat(position, normal);
+
+#ifdef SHADOWED
+   vLightPosition = uMatrixLight * position;
+#endif
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh b/src/modules/evas/engines/gl_common/shader_3d/gen_shaders_3d.sh
new file mode 100755 (executable)
index 0000000..8bb6a2a
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# This script will generate a C file containing all the shaders used by Evas_3D
+
+DIR=`dirname $0`
+
+OUTPUT=${DIR}/evas_gl_3d_shaders.x
+
+exec 1<&-
+exec 1>${OUTPUT}
+
+SHADERS="$@"
+vert_shaders_source=""
+frag_shaders_source=""
+
+# Write header
+printf "/* DO NOT MODIFY THIS FILE AS IT IS AUTO-GENERATED\n * See: $0 */\n\n"
+for shd in ${SHADERS} ; do
+  lname=`basename ${shd} .shd`
+
+  if echo ${lname} |grep _vert 2>&1 >> /dev/null ; then
+    vert_shaders_source="${vert_shaders_source}    ${lname}_glsl,\n"
+  fi
+  if echo ${lname} |grep _frag 2>&1 >> /dev/null ; then
+    frag_shaders_source="${frag_shaders_source}    ${lname}_glsl,\n"
+  fi
+  OIFS=$IFS
+  IFS=$'\n'
+  printf "static const char const ${lname}_glsl[] ="
+  for line in `cat ${shd}` ; do
+      printf "\n   \"${line}\\\n\""
+  done
+  printf ";\n\n"
+  IFS=${OIFS}
+done
+
+printf "static const char *vertex_shaders[] =
+{\n"
+      printf "${vert_shaders_source}"
+printf "};\n\n"
+
+printf "static const char *fragment_shaders[] =
+{\n"
+      printf "${frag_shaders_source}"
+printf "};\n"
diff --git a/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/normal_map_frag.shd
new file mode 100644 (file)
index 0000000..766e07f
--- /dev/null
@@ -0,0 +1,283 @@
+varying  vec3        vLightVector;
+varying  vec3        vLightHalfVector;
+uniform  sampler2D   uTextureNormal0;
+varying  vec3        vEyeVector;
+
+#ifdef NEED_TEX_COORD
+varying vec2   vTexCoord;
+#endif //TEX_COORD
+
+#ifdef FOG_ENABLED
+uniform float uFogFactor;
+uniform vec4  uFogColor;
+#endif //FOG_ENABLED
+
+#ifdef  SHADOWED
+varying vec4 vLightPosition;
+uniform sampler2D uShadowMap;
+float shadow;
+#endif //SHADOWED
+
+#ifdef NORMAL_TEXTURE_BLEND
+uniform  sampler2D  uTextureNormal1;
+uniform  float      uTextureNormalWeight;
+#endif //NORMAL_TEXTURE_BLEND
+
+#ifndef VERTEX_TANGENT
+varying  vec3        vNormal;
+#endif //VERTEX_TANGENT
+
+#ifdef DIFFUSE
+uniform   vec4        uMaterialDiffuse;
+uniform   vec4        uLightDiffuse;
+
+#ifdef DIFFUSE_TEXTURE
+uniform sampler2D  uTextureDiffuse0;
+#endif //DIFFUSE_TEXTURE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+uniform sampler2D  uTextureDiffuse1;
+uniform float      uTextureDiffuseWeight;
+#endif //DIFFUSE_TEXTURE_BLEND
+
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+uniform   vec4     uLightSpecular;
+uniform   float    uMaterialShininess;
+uniform   vec4     uMaterialSpecular;
+
+#ifdef SPECULAR_TEXTURE
+uniform sampler2D  uTextureSpecular0;
+#endif //SPECULAR_TEXTURE
+
+#ifdef SPECULAR_TEXTURE_BLEND
+uniform sampler2D  uTextureSpecular1;
+uniform float      uTextureSpecularWeight;
+#endif //SPECULAR_TEXTURE_BLEND
+
+#endif //SPECULAR
+
+#ifdef AMBIENT
+uniform  vec4       uMaterialAmbient;
+uniform  vec4       uLightAmbient;
+
+#ifdef AMBIENT_TEXTURE
+uniform sampler2D  uTextureAmbient0;
+#endif //AMBIENT_TEXTURE
+
+#ifdef AMBIENT_TEXTURE_BLEND
+uniform sampler2D  uTextureAmbient1;
+uniform float      uTextureAmbientWeight;
+#endif //AMBIENT_TEXTURE_BLEND
+
+#endif //AMBIENT
+
+#ifdef EMISSION
+uniform vec4       uMaterialEmission;
+
+#ifdef EMISSION_TEXTURE
+uniform sampler2D  uTextureEmission0;
+#endif //EMISSION_TEXTURE
+
+#ifdef EMISSION_TEXTURE_BLEND
+uniform sampler2D  uTextureEmission1;
+uniform float      uTextureEmissionWeight;
+#endif //EMISSION_TEXTURE_BLEND
+
+#endif //EMISSION
+
+#ifdef LIGHT_SPOT
+uniform   vec3  uLightSpotDir;
+uniform   float uLightSpotExp;
+uniform   float uLightSpotCutoffCos;
+#endif //LIGHT_SPOT
+
+#ifdef LIGHT_ATTENUATION
+varying   float    vLightDist;
+#endif //LIGHT_ATTENUATION
+
+#ifndef VERTEX_TANGENT
+
+mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv)
+{
+   vec3 dp1 = dFdx(p);
+   vec3 dp2 = dFdy(p);
+   vec2 duv1 = dFdx(uv);
+   vec2 duv2 = dFdy(uv);
+   vec3 dp2perp = cross(dp2, n);
+   vec3 dp1perp = cross(n, dp1);
+   vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
+   vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
+   float invmax = inversesqrt(max(dot(t, t), dot(b, b)));
+   return mat3(t * invmax, b * invmax, n);
+}
+
+vec3 perturb_normal(vec3 normal)
+{
+   mat3 tbn = cotangent_frame(vNormal, -vEyeVector, vTexCoord);
+   return normalize(tbn * normal);
+}
+#endif //VERTEX_TANGENT
+
+void fragmentNormalMap()
+{
+   float factor;
+   vec3  normal;
+   vec4  color;
+
+#ifdef NORMAL_TEXTURE_BLEND
+   normal = texture2D(uTextureNormal0, vTexCoord).rgb * uTextureNormalWeight;
+   normal += texture2D(uTextureNormal1, vTexCoord).rgb *
+   (1.0 - uTextureNormalWeight);
+#else
+   normal = texture2D(uTextureNormal0, vTexCoord).rgb;
+#endif //NORMAL_TEXTURE_BLEND
+
+   normal = 2.0 * normal - 1.0;
+
+#ifndef VERTEX_TANGENT
+   normal = perturb_normal(normal);
+#endif //VERTEX_TANGENT
+
+   vec3  lv = normalize(vLightVector);
+   normal = normalize(normal);
+
+   factor = dot(lv, normal);
+
+#ifdef LIGHT_SPOT
+   float f = dot(-lv, normalize(uLightSpotDir));
+
+   if (f > uLightSpotCutoffCos)
+     factor *= pow(f, uLightSpotExp);
+   else
+     factor = 0.0;
+#endif //LIGHT_SPOT
+
+   if (factor > 0.0)
+     {
+
+#ifdef DIFFUSE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+        color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +
+        texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);
+#else
+
+#ifdef DIFFUSE_TEXTURE
+        color = texture2D(uTextureDiffuse0, vTexCoord);
+#else
+        color = uMaterialDiffuse;
+#endif //DIFFUSE_TEXTURE
+
+#endif //DIFFUSE_TEXTURE_BLEND
+
+        gl_FragColor = uLightDiffuse * color * factor;
+
+#else
+        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+
+        factor = dot(normalize(vLightHalfVector), normal);
+        if (factor > 0.0)
+          {
+             factor = pow(factor, uMaterialShininess);
+
+#ifdef SPECULAR_TEXTURE_BLEND
+             color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +
+             texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);
+#else
+#ifdef SPECULAR_TEXTURE
+             color = texture2D(uTextureSpecular0, vTexCoord);
+#else
+             color = uMaterialSpecular;
+#endif //SPECULAR_TEXTURE
+
+#endif //SPECULAR_TEXTURE_BLEND
+
+             gl_FragColor += uLightSpecular * color * factor;
+          }
+
+#endif //SPECULAR
+
+#ifdef SHADOWED
+        gl_FragColor *= shadow;
+#endif //SHADOWED
+
+     }
+   else
+     gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+
+#ifdef AMBIENT
+#ifdef AMBIENT_TEXTURE_BLEND
+   color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +
+   texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight);
+#else
+
+#ifdef AMBIENT_TEXTURE
+   color = texture2D(uTextureAmbient0, vTexCoord);
+#else
+   color = uMaterialAmbient;
+#endif //AMBIENT_TEXTURE
+
+#endif //AMBIENT_TEXTURE_BLEND
+
+     gl_FragColor += uLightAmbient * color;
+#endif //AMBIENT
+
+#ifdef LIGHT_ATTENUATION
+   gl_FragColor /= dot(uLightAtten, vec3(1.0, vLightDist, vLightDist * vLightDist));
+#endif //LIGHT_ATTENUATION
+
+#ifdef EMISSION
+
+#ifdef EMISSION_TEXTURE_BLEND
+   color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +
+   texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);
+#else
+
+#ifdef EMISSION_TEXTURE
+   color = texture2D(uTextureEmission0, vTexCoord);
+#else
+   color = uMaterialEmission;
+#endif //EMISSION_TEXTURE
+
+#endif //EMISSION_TEXTURE_BLEND
+
+   gl_FragColor += color;
+#endif //EMISSION
+
+}
+
+#ifdef SHADOWED
+float pcf(vec4 lpos, float size)
+{
+   vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;
+   float i, j, randx, randy, shadow;
+   shadow = 0.0;
+   for (i = -4.0; i < 4.0; i++)
+     for (j = -4.0; j < 4.0; j++)
+        shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy +vec2(i / 8.0, j / 8.0)*size).x);
+   return shadow / 64.0;
+}
+#endif //SHADOWED
+
+void main() {
+
+#ifdef SHADOWED
+   shadow = pcf(vLightPosition, 1.0 / 200.0);
+#endif //SHADOWED
+
+   fragmentNormalMap();
+
+#ifdef FOG_ENABLED
+   float z = gl_FragCoord.z / gl_FragCoord.w;
+   float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);
+   fogFactor = clamp(fogFactor, 0.0, 1.0);
+   gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);
+#endif //FOG_ENABLED
+
+}
+
diff --git a/src/modules/evas/engines/gl_common/shader_3d/normal_map_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/normal_map_vert.shd
new file mode 100644 (file)
index 0000000..3dc42d2
--- /dev/null
@@ -0,0 +1,189 @@
+uniform  mat4  uMatrixMvp;
+uniform  mat3  uMatrixNormal;
+uniform  mat4  uMatrixModelview;
+uniform  vec4  uLightPosition;
+varying  vec3  vLightVector;
+varying  vec3  vLightHalfVector;
+varying  vec3  vEyeVector;
+
+#ifndef VERTEX_TANGENT
+varying  vec3  vNormal;
+#endif //VERTEX_TANGENT
+
+#ifdef SHADOWED
+uniform mat4 uMatrixLight;
+varying vec4 vLightPosition;
+#endif //SHADOWED
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL
+attribute   vec4  aNormal0;
+#endif //VERTEX_NORMAL
+
+#ifdef VERTEX_NORMAL_BLEND
+attribute   vec4  aNormal1;
+uniform     float uNormalWeight;
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TANGENT
+attribute   vec4  aTangent0;
+#endif //VERTEX_TANGENT
+
+#ifdef VERTEX_TANGENT_BLEND
+attribute   vec4  aTangent1;
+uniform     float uTangentWeight;
+#endif //VERTEX_TANGENT_BLEND
+
+#ifdef VERTEX_TEXCOORD
+attribute   vec4  aTexCoord0;
+#endif //VERTEX_TEXCOORD
+
+#ifdef VERTEX_TEXCOORD_BLEND
+attribute   vec4  aTexCoord1;
+uniform     float uTexCoordWeight;
+#endif //VERTEX_TEXCOORD_BLEND
+
+#ifdef NEED_TEX_COORD
+varying vec2 vTexCoord;
+#endif //NEED_TEX_COORD
+
+#ifdef LIGHT_ATTENUATION
+varying  float vLightDist;
+#endif //LIGHT_ATTENUATION
+
+#ifndef VERTEX_TANGENT
+void vertexNormalMap(vec4 position, vec3 normal)
+{
+   normal = uMatrixNormal * normal;
+   position = uMatrixModelview * position;
+   vEyeVector = normalize(-position.xyz);
+
+#ifdef NORMALIZE_NORMALS
+   normal = normalize(normal);
+#endif //NORMALIZE_NORMALS
+
+#ifdef LIGHT_DIRECTIONAL
+   vLightVector = uLightPosition.xyz;
+#else
+   vLightVector = uLightPosition.xyz - position.xyz;
+
+#ifdef LIGHT_ATTENUATION
+   vLightDist = length(vLightVector);
+#endif //LIGHT_ATTENUATION
+
+   vLightVector = normalize(vLightVector);
+#endif //LIGHT_DIRECTIONAL
+
+   vLightHalfVector = normalize(vEyeVector + vLightVector);
+   vNormal = normal;
+}
+
+#else
+
+void vertexNormalMap(vec4 position, vec3 normal, vec3 tangent)
+{
+   vec3 n = normalize(uMatrixNormal * normal);
+   vec3 t = normalize(uMatrixNormal * tangent);
+   vec3 b = cross(n, t);
+   vec3 tmp;
+
+   position = uMatrixModelview * position;
+
+#ifdef LIGHT_DIRECTIONAL
+   vec3 lightDir = uLightPosition.xyz;
+#else
+   vec3 lightDir = uLightPosition.xyz - position.xyz;
+
+#ifdef LIGHT_ATTENUATION
+   vLightDist = length(lightDir);
+#endif //LIGHT_ATTENUATION
+
+   lightDir = normalize(lightDir);
+#endif //LIGHT_DIRECTIONAL
+
+   tmp.x = dot(lightDir, t);
+   tmp.y = dot(lightDir, b);
+   tmp.z = dot(lightDir, n);
+   vLightVector = tmp;
+
+   tmp.x = dot(position.xyz, t);
+   tmp.y = dot(position.xyz, b);
+   tmp.z = dot(position.xyz, n);
+   vEyeVector = normalize(tmp);
+
+   vec3 hv = normalize(normalize(-position.xyz) + lightDir);
+   tmp.x = dot(hv, t);
+   tmp.y = dot(hv, b);
+   tmp.z = dot(hv, n);
+   vLightHalfVector = tmp;
+}
+#endif //VERTEX_TANGENT
+
+void main()
+{
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL_BLEND
+   vec3 normal = aNormal0.xyz * uNormalWeight +
+   aNormal1.xyz * (1.0 - uNormalWeight);
+#else
+
+#ifdef VERTEX_NORMAL
+   vec3 normal = aNormal0.xyz;
+#endif //VERTEX_NORMAL
+
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TANGENT_BLEND
+   vec3 tangent = aTangent0.xyz * uTangentWeight +
+   aTangent1.xyz * (1.0 - uTangentWeight);
+#else
+
+#ifdef VERTEX_TANGENT
+   vec3 tangent = aTangent0.xyz;
+#endif //VERTEX_TANGENT
+
+#endif //VERTEX_TANGENT_BLEND
+
+#ifdef VERTEX_TEXCOORD_BLEND
+   vTexCoord = aTexCoord0.st * uTexCoordWeight +
+   aTexCoord1.st * (1.0 - uTexCoordWeight);
+#else
+
+#ifdef VERTEX_TEXCOORD
+   vTexCoord = aTexCoord0.st;
+#endif //VERTEX_TEXCOORD
+
+#endif //VERTEX_TEXCOORD_BLEND
+
+   gl_Position = uMatrixMvp * position;
+
+#ifdef  VERTEX_TANGENT
+   vertexNormalMap(position, normal, tangent);
+#else
+   vertexNormalMap(position, normal);
+#endif //VERTEX_TANGENT
+
+#ifdef SHADOWED
+   vLightPosition = uMatrixLight * position;
+#endif
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/phong_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/phong_frag.shd
new file mode 100644 (file)
index 0000000..f668984
--- /dev/null
@@ -0,0 +1,235 @@
+varying  vec3        vLightVector;
+varying  vec3        vLightHalfVector;
+varying  vec3        vNormal;
+
+#ifdef NEED_TEX_COORD
+varying vec2   vTexCoord;
+#endif //TEX_COORD
+
+#ifdef FOG_ENABLED
+uniform float uFogFactor;
+uniform vec4  uFogColor;
+#endif //FOG_ENABLED
+
+#ifdef  SHADOWED
+varying vec4 vLightPosition;
+uniform sampler2D uShadowMap;
+float shadow;
+#endif //SHADOWED
+
+#ifdef DIFFUSE
+uniform   vec4        uMaterialDiffuse;
+uniform   vec4        uLightDiffuse;
+
+#ifdef DIFFUSE_TEXTURE
+uniform sampler2D  uTextureDiffuse0;
+#endif //DIFFUSE_TEXTURE
+
+#ifdef DIFFUSE_TEXTURE_BLEND
+uniform sampler2D  uTextureDiffuse1;
+uniform float      uTextureDiffuseWeight;
+#endif //DIFFUSE_TEXTURE_BLEND
+
+#endif //DIFFUSE
+
+#ifdef SPECULAR
+uniform   vec4     uLightSpecular;
+uniform   float    uMaterialShininess;
+uniform   vec4     uMaterialSpecular;
+
+#ifdef SPECULAR_TEXTURE
+uniform sampler2D  uTextureSpecular0;
+#endif //SPECULAR_TEXTURE
+
+#ifdef SPECULAR_TEXTURE_BLEND
+uniform sampler2D  uTextureSpecular1;
+uniform float      uTextureSpecularWeight;
+#endif //SPECULAR_TEXTURE_BLEND
+
+#endif //SPECULAR
+
+#ifdef AMBIENT
+uniform  vec4       uMaterialAmbient;
+uniform  vec4       uLightAmbient;
+
+#ifdef AMBIENT_TEXTURE
+uniform sampler2D  uTextureAmbient0;
+#endif //AMBIENT_TEXTURE
+
+#ifdef AMBIENT_TEXTURE_BLEND
+uniform sampler2D  uTextureAmbient1;
+uniform float      uTextureAmbientWeight;
+#endif //AMBIENT_TEXTURE_BLEND
+
+#endif //AMBIENT
+
+#ifdef EMISSION
+uniform vec4       uMaterialEmission;
+
+#ifdef EMISSION_TEXTURE
+uniform sampler2D  uTextureEmission0;
+#endif //EMISSION_TEXTURE
+
+#ifdef EMISSION_TEXTURE_BLEND
+uniform sampler2D  uTextureEmission1;
+uniform float      uTextureEmissionWeight;
+#endif //EMISSION_TEXTURE_BLEND
+
+#endif //EMISSION
+
+#ifdef LIGHT_SPOT
+uniform   vec3  uLightSpotDir;
+uniform   float uLightSpotExp;
+uniform   float uLightSpotCutoffCos;
+#endif //LIGHT_SPOT
+
+#ifdef LIGHT_ATTENUATION
+varying   float    vLightDist;
+#endif //LIGHT_ATTENUATION
+
+void fragmentPhong()
+{
+   vec3  normal = normalize(vNormal);
+   vec3  lv = normalize(vLightVector);
+   float factor = dot(lv, normal);
+   vec4  color;
+
+#ifdef  LIGHT_SPOT
+   float f = dot(-lv, normalize(uLightSpotDir));
+
+   if (f > uLightSpotCutoffCos)
+      factor *= pow(f, uLightSpotExp);
+   else
+     factor = 0.0;
+#endif //LIGHT_SPOT
+
+   if (factor > 0.0)
+     {
+
+   /* Diffuse term. */
+#ifdef  DIFFUSE
+
+#ifdef  DIFFUSE_TEXTURE_BLEND
+        color = texture2D(uTextureDiffuse0, vTexCoord) * uTextureDiffuseWeight +
+        texture2D(uTextureDiffuse1, vTexCoord) * (1.0 - uTextureDiffuseWeight);
+#else
+
+#ifdef  DIFFUSE_TEXTURE
+        color = texture2D(uTextureDiffuse0, vTexCoord);
+#else
+        color = uMaterialDiffuse;
+#endif //DIFFUSE_TEXTURE
+
+#endif //DIFFUSE_TEXTURE_BLEND
+
+        gl_FragColor = uLightDiffuse * color * factor;
+#else
+        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+#endif //DIFFUSE
+
+   /* Specular term. */
+#ifdef SPECULAR
+        factor = dot(normalize(vLightHalfVector), normal);
+        if (factor > 0.0)
+          {
+             factor = pow(factor, uMaterialShininess);
+
+#ifdef  SPECULAR_TEXTURE_BLEND
+             color = texture2D(uTextureSpecular0, vTexCoord) * uTextureSpecularWeight +
+             texture2D(uTextureSpecular1, vTexCoord) * (1.0 - uTextureSpecularWeight);
+#else
+
+#ifdef   SPECULAR_TEXTURE
+             color = texture2D(uTextureSpecular0, vTexCoord);
+#else
+             color = uMaterialSpecular;
+#endif
+
+#endif
+
+             gl_FragColor += uLightSpecular * color * factor;
+          }
+#endif
+
+     }
+   else
+     gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+
+#ifdef  SHADOWED
+   gl_FragColor *= shadow;
+#endif //SHADOWED
+
+#ifdef AMBIENT
+#ifdef AMBIENT_TEXTURE_BLEND
+   color = texture2D(uTextureAmbient0, vTexCoord) * uTextureAmbientWeight +
+   texture2D(uTextureAmbient1, vTexCoord) * (1.0 - uTextureAmbientWeight);
+#else
+
+#ifdef AMBIENT_TEXTURE
+   color = texture2D(uTextureAmbient0, vTexCoord);
+#else
+   color = uMaterialAmbient;
+#endif
+
+#endif
+
+   gl_FragColor += uLightAmbient * color;
+#endif
+
+   /* Light attenuation. */
+#ifdef  LIGHT_ATTENUATION
+   gl_FragColor /= dot(uLightAtten, vec3(1.0, vLightDist, vLightDist * vLightDist));
+#endif
+
+   /* Emission term. */
+#ifdef  EMISSION
+
+#ifdef  EMISSION_TEXTURE_BLEND
+   color = texture2D(uTextureEmission0, vTexCoord) * uTextureEmissionWeight +
+   texture2D(uTextureEmission1, vTexCoord) * (1.0 - uTextureEmissionWeight);
+#else
+
+#ifdef  EMISSION_TEXTURE
+   color = texture2D(uTextureEmission0, vTexCoord);
+#else
+   color = uMaterialEmission;
+#endif
+
+#endif
+
+   gl_FragColor += color;
+#endif
+
+}
+
+#ifdef  SHADOWED
+float pcf(vec4 lpos, float size)
+{
+   vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;
+   float i, j, randx, randy, shadow;
+   shadow = 0.0;
+   for (i = -4.0; i < 4.0; i++)
+     for (j = -4.0; j < 4.0; j++)
+        shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy +vec2(i / 8.0, j / 8.0)*size).x);
+   return shadow / 64.0;
+}
+#endif //SHADOWED
+
+void main()
+{
+
+#ifdef SHADOWED
+   shadow = pcf(vLightPosition, 1.0 / 300.0);
+#endif //SHADOWED
+
+   fragmentPhong();
+
+#ifdef FOG_ENABLED
+   float z = gl_FragCoord.z / gl_FragCoord.w;
+   float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);
+   fogFactor = clamp(fogFactor, 0.0, 1.0);
+   gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);
+#endif //FOG_ENABLED
+
+}
+
diff --git a/src/modules/evas/engines/gl_common/shader_3d/phong_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/phong_vert.shd
new file mode 100644 (file)
index 0000000..fb2c5d4
--- /dev/null
@@ -0,0 +1,116 @@
+uniform  mat4  uMatrixMvp;
+uniform  mat3  uMatrixNormal;
+uniform  mat4  uMatrixModelview;
+uniform  vec4  uLightPosition;
+varying  vec3  vLightVector;
+varying  vec3  vLightHalfVector;
+varying  vec3  vNormal;
+
+#ifdef SHADOWED
+uniform mat4 uMatrixLight;
+varying vec4 vLightPosition;
+#endif //SHADOWED
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL
+attribute   vec4  aNormal0;
+#endif //VERTEX_NORMAL
+
+#ifdef VERTEX_NORMAL_BLEND
+attribute   vec4  aNormal1;
+uniform     float uNormalWeight;
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TEXCOORD
+attribute   vec4  aTexCoord0;
+#endif //VERTEX_TEXCOORD
+
+#ifdef VERTEX_TEXCOORD_BLEND
+attribute   vec4  aTexCoord1;
+uniform     float uTexCoordWeight;
+#endif //VERTEX_TEXCOORD_BLEND
+
+#ifdef NEED_TEX_COORD
+varying vec2 vTexCoord;
+#endif //NEED_TEX_COORD
+
+#ifdef LIGHT_ATTENUATION
+varying  float vLightDist;
+#endif //LIGHT_ATTENUATION
+
+void vertexPhong(vec4 position, vec3 normal)
+{
+   normal = uMatrixNormal * normal;
+   position = uMatrixModelview * position;
+
+#ifdef NORMALIZE_NORMALS
+   normal = normalize(normal);
+#endif //NORMALIZE_NORMALS
+
+#ifdef LIGHT_DIRECTIONAL
+   vLightVector = uLightPosition.xyz;
+#else
+   vLightVector = uLightPosition.xyz - position.xyz;
+
+#ifdef LIGHT_ATTENUATION
+   vLightDist = length(vLightVector);
+#endif //LIGHT_ATTENUATION
+
+   vLightVector = normalize(vLightVector);
+#endif //LIGHT_DIRECTIONAL
+
+   vLightHalfVector = normalize(normalize(-position.xyz) + vLightVector);
+   vNormal = normal;
+}
+
+void main() {
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_NORMAL_BLEND
+   vec3 normal = aNormal0.xyz * uNormalWeight +
+   aNormal1.xyz * (1.0 - uNormalWeight);
+#else
+
+#ifdef VERTEX_NORMAL
+   vec3 normal = aNormal0.xyz;
+#endif //VERTEX_NORMAL
+
+#endif //VERTEX_NORMAL_BLEND
+
+#ifdef VERTEX_TEXCOORD_BLEND
+   vTexCoord = aTexCoord0.st * uTexCoordWeight +
+   aTexCoord1.st * (1.0 - uTexCoordWeight);
+#else
+
+#ifdef VERTEX_TEXCOORD
+   vTexCoord = aTexCoord0.st;
+#endif //VERTEX_TEXCOORD
+
+#endif //VERTEX_TEXCOORD_BLEND
+
+   gl_Position = uMatrixMvp * position;
+   vertexPhong(position, normal);
+
+#ifdef SHADOWED
+   vLightPosition = uMatrixLight * position;
+#endif //SHADOWED
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/shadow_map_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/shadow_map_frag.shd
new file mode 100644 (file)
index 0000000..84a586a
--- /dev/null
@@ -0,0 +1,4 @@
+void main()
+{
+   gl_FragColor.r = gl_FragCoord.z;
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/shadow_map_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/shadow_map_vert.shd
new file mode 100644 (file)
index 0000000..3f12a69
--- /dev/null
@@ -0,0 +1,28 @@
+uniform mat4  uMatrixMvp;
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+void main()
+{
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+   gl_Position = uMatrixMvp * position;
+}
diff --git a/src/modules/evas/engines/gl_common/shader_3d/vertex_color_frag.shd b/src/modules/evas/engines/gl_common/shader_3d/vertex_color_frag.shd
new file mode 100644 (file)
index 0000000..9b0c023
--- /dev/null
@@ -0,0 +1,20 @@
+varying  vec4        vColor;
+
+#ifdef FOG_ENABLED
+uniform float uFogFactor;
+uniform vec4  uFogColor;
+#endif //FOG_ENABLED
+
+void main()
+{
+   gl_FragColor = vColor;
+
+#ifdef FOG_ENABLED
+   float z = gl_FragCoord.z / gl_FragCoord.w;
+   float fogFactor = exp2( -uFogFactor * uFogFactor * z * z * 1.44);
+   fogFactor = clamp(fogFactor, 0.0, 1.0);
+   gl_FragColor = mix(uFogColor, gl_FragColor, fogFactor);
+#endif //FOG_ENABLED
+
+}
+
diff --git a/src/modules/evas/engines/gl_common/shader_3d/vertex_color_vert.shd b/src/modules/evas/engines/gl_common/shader_3d/vertex_color_vert.shd
new file mode 100644 (file)
index 0000000..560baad
--- /dev/null
@@ -0,0 +1,50 @@
+uniform     mat4  uMatrixMvp;
+varying     vec4  vColor;
+
+#ifdef VERTEX_POSITION
+attribute   vec4  aPosition0;
+#endif //VERTEX_POSITION
+
+#ifdef VERTEX_POSITION_BLEND
+attribute   vec4  aPosition1;
+uniform     float uPositionWeight;
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_COLOR
+attribute   vec4  aColor0;
+#endif //VERTEX_COLOR
+
+#ifdef VERTEX_COLOR_BLEND
+attribute   vec4  aColor1;
+uniform     float uColorWeight;
+#endif //VERTEX_COLOR_BLEND
+
+void main()
+{
+
+#ifdef VERTEX_POSITION_BLEND
+   vec4 position = aPosition0 * uPositionWeight +
+   aPosition1 * (1.0 - uPositionWeight);
+   position = vec4(position.xyz, 1.0);
+#else
+
+#ifdef VERTEX_POSITION
+   vec4 position = vec4(aPosition0.xyz, 1.0);
+#endif // VERTEX_POSITION
+
+#endif //VERTEX_POSITION_BLEND
+
+#ifdef VERTEX_COLOR_BLEND
+   vec4 color = aColor0 * uColorWeight + aColor1 * (1.0 - uColorWeight);
+#else
+
+#ifdef VERTEX_COLOR
+   vec4 color = aColor0;
+#endif //VERTEX_COLOR
+
+#endif //VERTEX_COLOR_BLEND
+
+   vColor = color;
+   gl_Position = uMatrixMvp * position;
+}
+