diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d.c b/src/modules/evas/engines/gl_common/evas_gl_3d.c index 1c393159e9..8caf9ae620 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c @@ -276,6 +276,9 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo GLuint depth_stencil_buf = 0; GLuint depth_buf = 0; GLuint stencil_buf = 0; +#ifdef GL_GLES + GLuint shadow_fbo, depth_render_buf; +#endif Eina_Bool depth_stencil = EINA_FALSE; glGenTextures(1, &tex); @@ -298,8 +301,13 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #ifndef GL_GLES glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0); +#else + glGenFramebuffers(1, &shadow_fbo); + glGenFramebuffers(1, &depth_render_buf); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #endif + glGenFramebuffers(1, &color_pick_fb_id); glGenTextures(1, &texcolorpick); glBindTexture(GL_TEXTURE_2D, texcolorpick); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -310,8 +318,6 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0); #endif - glGenFramebuffers(1, &color_pick_fb_id); - glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); @@ -393,7 +399,10 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo drawable->depth_buf = depth_buf; drawable->stencil_buf = stencil_buf; drawable->texDepth = texDepth; - +#ifdef GL_GLES + drawable->shadow_fbo = shadow_fbo; + drawable->depth_render_buf = depth_render_buf; +#endif return drawable; error: @@ -403,6 +412,8 @@ error: glDeleteTextures(1, &tex); if (texcolorpick) glDeleteTextures(1, &texcolorpick); + if (texDepth) + glDeleteTextures(1, &texDepth); if (fbo) glDeleteFramebuffers(1, &fbo); @@ -424,6 +435,13 @@ error: if (stencil_buf) glDeleteRenderbuffers(1, &stencil_buf); +#ifdef GL_GLES + if (shadow_fbo) + glDeleteFramebuffers(1, &shadow_fbo); + if (depth_render_buf) + glDeleteFramebuffers(1, &depth_render_buf); +#endif + return NULL; } @@ -1146,7 +1164,9 @@ _mesh_draw(E3D_Renderer *renderer, Evas_3D_Mesh *mesh, int frame, Evas_3D_Node * e3d_renderer_draw(renderer, &data); } -void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_Scene_Public_Data *data, Evas_Mat4 *matrix_light_eye, Evas_3D_Node *light) +void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, + Evas_3D_Scene_Public_Data *data, Evas_Mat4 *matrix_light_eye, + Evas_3D_Node *light) { Eina_List *l; Evas_3D_Node *n; @@ -1157,12 +1177,24 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(4.0, 100.0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawable->texDepth, 0); +#ifdef GL_GLES + glBindFramebuffer(GL_FRAMEBUFFER, drawable->shadow_fbo); + glBindRenderbuffer(GL_RENDERBUFFER, drawable->depth_render_buf); +#endif + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + drawable->texDepth, 0); +#ifdef GL_GLES + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, drawable->w, + drawable->h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + drawable->depth_render_buf); +#endif e3d_renderer_target_set(renderer, drawable); e3d_renderer_clear(renderer, &c); Evas_3D_Node_Data *pd_light_node = eo_data_scope_get(light, EVAS_3D_NODE_CLASS); - Evas_3D_Light_Data *pd = eo_data_scope_get(pd_light_node->data.light.light, EVAS_3D_LIGHT_CLASS); + Evas_3D_Light_Data *pd = eo_data_scope_get(pd_light_node->data.light.light, + EVAS_3D_LIGHT_CLASS); Evas_Vec4 planes[6]; evas_mat4_multiply(&matrix_vp, &pd->projection, matrix_light_eye); @@ -1180,7 +1212,8 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S blend_enabled = pdmesh->blending; pdmesh->blending = EINA_FALSE; pdmesh->shade_mode = EVAS_3D_SHADE_MODE_SHADOW_MAP_RENDER; - _mesh_draw(renderer, nm->mesh, nm->frame, light, matrix_light_eye, &matrix_mv, &matrix_mvp, &matrix_mvp); + _mesh_draw(renderer, nm->mesh, nm->frame, light, matrix_light_eye, + &matrix_mv, &matrix_mvp, &matrix_mvp); pdmesh->shade_mode = shade_mode; pdmesh->blending = blend_enabled; } @@ -1189,6 +1222,9 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_3D_S } glDisable(GL_POLYGON_OFFSET_FILL); +#ifdef GL_GLES + glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo); +#endif glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawable->tex, 0); } diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_private.h b/src/modules/evas/engines/gl_common/evas_gl_3d_private.h index 87fbb8a31c..ad8d992c8a 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_3d_private.h @@ -147,6 +147,10 @@ struct _E3D_Drawable GLuint texDepth; GLuint texcolorpick; GLuint color_pick_fb_id; +#ifdef GL_GLES + GLuint shadow_fbo; + GLuint depth_render_buf; +#endif }; /* Texture internal functions. */ diff --git a/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x b/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x index d4bd7ebb4f..0505e412f9 100644 --- a/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x +++ b/src/modules/evas/engines/gl_common/shader_3d/evas_gl_3d_shaders.x @@ -403,19 +403,25 @@ static const char flat_frag_glsl[] = "uniform sampler2D uShadowMap;\n" "float shadow;\n" "float pcf(vec4 lpos, float size)\n" - " {\n" + "{\n" + " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" + " float i, j, shadow;\n" + " shadow = 0.0;\n" "#ifndef GL_ES\n" - " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" - " float i, j, randx, randy, shadow;\n" - " shadow = 0.0;\n" - " for (i = -4.0; i < 4.0; i++)\n" - " for (j = -4.0; j < 4.0; j++)\n" - " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" - " return shadow / 64.0;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" "#else\n" - " /*TODO Add algorithm generate shadow*/\n" - " return 1.0;\n" + " const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n" + " const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " {\n" + " vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n" + " shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n" + " }\n" "#endif //GL_ES\n" + " return shadow / 64.0;\n" "}\n" "#endif //SHADOWED\n" "#ifdef DIFFUSE\n" @@ -734,19 +740,25 @@ static const char phong_frag_glsl[] = "uniform sampler2D uShadowMap;\n" "float shadow;\n" "float pcf(vec4 lpos, float size)\n" - " {\n" + "{\n" + " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" + " float i, j, shadow;\n" + " shadow = 0.0;\n" "#ifndef GL_ES\n" - " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" - " float i, j, randx, randy, shadow;\n" - " shadow = 0.0;\n" - " for (i = -4.0; i < 4.0; i++)\n" - " for (j = -4.0; j < 4.0; j++)\n" - " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" - " return shadow / 64.0;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" "#else\n" - " /*TODO Add algorithm generate shadow*/\n" - " return 1.0;\n" + " const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n" + " const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " {\n" + " vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n" + " shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n" + " }\n" "#endif //GL_ES\n" + " return shadow / 64.0;\n" "}\n" "#endif //SHADOWED\n" "#ifdef DIFFUSE\n" @@ -1158,19 +1170,25 @@ static const char normal_map_frag_glsl[] = "uniform sampler2D uShadowMap;\n" "float shadow;\n" "float pcf(vec4 lpos, float size)\n" - " {\n" + "{\n" + " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" + " float i, j, shadow;\n" + " shadow = 0.0;\n" "#ifndef GL_ES\n" - " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" - " float i, j, randx, randy, shadow;\n" - " shadow = 0.0;\n" - " for (i = -4.0; i < 4.0; i++)\n" - " for (j = -4.0; j < 4.0; j++)\n" - " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" - " return shadow / 64.0;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" "#else\n" - " /*TODO Add algorithm generate shadow*/\n" - " return 1.0;\n" + " const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n" + " const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " {\n" + " vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n" + " shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n" + " }\n" "#endif //GL_ES\n" + " return shadow / 64.0;\n" "}\n" "#endif //SHADOWED\n" "#ifdef NORMAL_TEXTURE\n" @@ -1461,6 +1479,7 @@ static const char shadow_map_vert_glsl[] = "precision lowp sampler2D;\n" "#endif\n" "uniform mat4 uMatrixMvp;\n" + "varying vec4 shadowmapposition;\n" "#ifdef VERTEX_POSITION\n" "attribute vec4 aPosition0;\n" "#endif //VERTEX_POSITION\n" @@ -1500,6 +1519,7 @@ static const char shadow_map_vert_glsl[] = "#endif //VERTEX_TEXCOORD_BLEND\n" "#endif //ALPHA_TEST_ENABLED\n" " gl_Position = uMatrixMvp * position;\n" + " shadowmapposition = gl_Position;\n" "}\n"; static const char shadow_map_frag_glsl[] = @@ -1508,6 +1528,7 @@ static const char shadow_map_frag_glsl[] = "precision mediump int;\n" "precision lowp sampler2D;\n" "#endif\n" + "varying vec4 shadowmapposition;\n" "#ifdef ALPHA_TEST_ENABLED\n" "#ifdef NEED_TEX_COORD\n" "varying vec2 vTexCoord;\n" @@ -1544,7 +1565,7 @@ static const char shadow_map_frag_glsl[] = " (1.0 - uTextureDiffuseWeight));\n" "#else\n" "#ifdef DIFFUSE_TEXTURE\n" - " color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse)) ;\n" + " color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse));\n" "#else\n" " color = vec4(1);\n" "#endif //DIFFUSE_TEXTURE\n" @@ -1590,7 +1611,18 @@ static const char shadow_map_frag_glsl[] = " gl_FragColor = color;\n" "#endif //GL_ES\n" "#endif //ALPHA_TEST_ENABLED\n" + "#ifndef GL_ES\n" " gl_FragColor.r = gl_FragCoord.z;\n" + "#else\n" + " const vec4 pack = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n" + " const vec4 mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n" + " vec4 depthcolor;\n" + " float normdist = shadowmapposition.z / shadowmapposition.w;\n" + " normdist = ((normdist + 1.0) / 2.0);\n" + " depthcolor = vec4(fract(pack * normdist));\n" + " depthcolor -= depthcolor.xxyz * mask;\n" + " gl_FragColor = depthcolor;\n" + "#endif\n" "}\n"; static const char color_pick_vert_glsl[] = @@ -1832,19 +1864,25 @@ static const char parallax_occlusion_frag_glsl[] = "uniform sampler2D uShadowMap;\n" "float shadow;\n" "float pcf(vec4 lpos, float size)\n" - " {\n" + "{\n" + " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" + " float i, j, shadow;\n" + " shadow = 0.0;\n" "#ifndef GL_ES\n" - " vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5;\n" - " float i, j, randx, randy, shadow;\n" - " shadow = 0.0;\n" - " for (i = -4.0; i < 4.0; i++)\n" - " for (j = -4.0; j < 4.0; j++)\n" - " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" - " return shadow / 64.0;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " shadow += float(smcoord.z <= texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size).x);\n" "#else\n" - " /*TODO Add algorithm generate shadow*/\n" - " return 1.0;\n" + " const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n" + " const float bias = 0.00015 /*TODO Optimizate set of offset*/;\n" + " for (i = -4.0; i < 4.0; i++)\n" + " for (j = -4.0; j < 4.0; j++)\n" + " {\n" + " vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size);\n" + " shadow += float(smcoord.z < dot(zvalue, unpack) + bias);\n" + " }\n" "#endif //GL_ES\n" + " return shadow / 64.0;\n" "}\n" "#endif //SHADOWED\n" "#ifdef DIFFUSE\n" diff --git a/src/modules/evas/engines/gl_common/shader_3d/include.shd b/src/modules/evas/engines/gl_common/shader_3d/include.shd index 706def92c4..3b92e827d0 100644 --- a/src/modules/evas/engines/gl_common/shader_3d/include.shd +++ b/src/modules/evas/engines/gl_common/shader_3d/include.shd @@ -42,19 +42,25 @@ varying vec4 vLightPosition; uniform sampler2D uShadowMap; float shadow; float pcf(vec4 lpos, float size) - { +{ + vec3 smcoord = lpos.xyz / lpos.w * 0.5 + 0.5; + float i, j, shadow; + shadow = 0.0; `#ifndef GL_ES' - 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; + 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); `#else' - /*TODO Add algorithm generate shadow*/ - return 1.0; + const vec4 unpack = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0); + const float bias = 0.00015 /*TODO Optimizate set of offset*/; + for (i = -4.0; i < 4.0; i++) + for (j = -4.0; j < 4.0; j++) + { + vec4 zvalue = texture2D(uShadowMap, smcoord.xy + vec2(i / 8.0, j / 8.0) * size); + shadow += float(smcoord.z < dot(zvalue, unpack) + bias); + } `#endif //GL_ES' + return shadow / 64.0; } #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 index cfdd298db4..bdb16e59bb 100644 --- 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 @@ -1,3 +1,4 @@ +varying vec4 shadowmapposition; #ifdef ALPHA_TEST_ENABLED FRAGMENT_SHADER_USE_TEX_COORD FRAGMENT_SHADER_USE_ALPHA_TEST_GLES @@ -39,7 +40,7 @@ void main() { #else #ifdef DIFFUSE_TEXTURE - color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse)) ; + color = texture2D(uTextureDiffuse0, vec2(Tex0CoordDiffuse)); #else color = vec4(1); #endif //DIFFUSE_TEXTURE @@ -49,5 +50,16 @@ void main() { FRAGMENT_SHADER_ALPHA_TEST_GLES_APPLY(color) #endif //ALPHA_TEST_ENABLED +#ifndef GL_ES gl_FragColor.r = gl_FragCoord.z; +#else + const vec4 pack = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); + const vec4 mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); + vec4 depthcolor; + float normdist = shadowmapposition.z / shadowmapposition.w; + normdist = ((normdist + 1.0) / 2.0); + depthcolor = vec4(fract(pack * normdist)); + depthcolor -= depthcolor.xxyz * mask; + gl_FragColor = depthcolor; +#endif } 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 index 095fc9c9c9..66ce4f3d62 100644 --- 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 @@ -1,5 +1,5 @@ uniform mat4 uMatrixMvp; - +varying vec4 shadowmapposition; VERTEX_SHADER_USE_POSITION #ifdef ALPHA_TEST_ENABLED @@ -17,4 +17,5 @@ VERTEX_SHADER_POSITION #endif //ALPHA_TEST_ENABLED gl_Position = uMatrixMvp * position; + shadowmapposition = gl_Position; }