cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=684c51360f1591de4b8aee1f52d4edf8e8353822
commit 684c51360f1591de4b8aee1f52d4edf8e8353822 Author: se.osadchy <[email protected]> Date: Tue May 26 19:12:24 2015 +0200 evas: fix color pick compatibility of Evas_3D with GLES. Summary: Use fourth component texture. Update mechanism generation pixels, scene renderer to texture and geting color pixels from texture. Update shader for color pick. Reviewers: Hermet, raster, cedric Reviewed By: cedric Subscribers: Oleksander, cedric Differential Revision: https://phab.enlightenment.org/D2549 --- src/lib/evas/canvas/evas_3d_mesh.c | 7 +++- src/lib/evas/canvas/evas_3d_node.c | 47 +++++++++++++++++++++- src/lib/evas/canvas/evas_3d_scene.c | 6 +-- src/lib/evas/include/evas_private.h | 7 +++- src/modules/evas/engines/gl_common/evas_gl_3d.c | 35 +++++++++------- .../evas/engines/gl_common/evas_gl_3d_common.h | 2 +- .../evas/engines/gl_common/evas_gl_3d_private.h | 4 ++ .../evas/engines/gl_common/evas_gl_3d_shader.c | 7 ++++ .../gl_common/shader_3d/color_pick_frag.shd | 14 ++++++- .../gl_common/shader_3d/evas_gl_3d_shaders.x | 13 +++++- src/modules/evas/engines/gl_generic/evas_engine.c | 7 ++-- 11 files changed, 120 insertions(+), 29 deletions(-) diff --git a/src/lib/evas/canvas/evas_3d_mesh.c b/src/lib/evas/canvas/evas_3d_mesh.c index f15b42f..385820f 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.c +++ b/src/lib/evas/canvas/evas_3d_mesh.c @@ -124,8 +124,13 @@ _mesh_init(Evas_3D_Mesh_Data *pd) pd->alpha_comparison = EVAS_3D_COMPARISON_ALWAYS; pd->alpha_ref_value = 0.0f; pd->alpha_test_enabled = EINA_FALSE; - +#ifndef GL_GLES pd->color_pick_key = -1.0; +#else + pd->color_pick_key.r = 0.0; + pd->color_pick_key.g = 0.0; + pd->color_pick_key.b = 0.0; +#endif pd->color_pick_enabled = EINA_FALSE; } diff --git a/src/lib/evas/canvas/evas_3d_node.c b/src/lib/evas/canvas/evas_3d_node.c index ea54ca3..cce21f4 100644 --- a/src/lib/evas/canvas/evas_3d_node.c +++ b/src/lib/evas/canvas/evas_3d_node.c @@ -14,6 +14,7 @@ static Eina_Stringshare * _generate_unic_color_key(Evas_Color *color, Evas_Color *bg_color, Evas_3D_Node *node, Evas_3D_Mesh *mesh, Eina_Bool init) { +#ifndef GL_GLES static unsigned short red = USHRT_MAX; if (init) red = USHRT_MAX; @@ -26,8 +27,52 @@ _generate_unic_color_key(Evas_Color *color, Evas_Color *bg_color, Evas_3D_Node * red--; - if (red < 1) red = USHRT_MAX; + if (red == 0) + { + ERR("Overfill number of color. %d %s", __LINE__, __FILE__); + red = USHRT_MAX; + } + +#else + static unsigned char red = 0; + static unsigned char green = 0; + static unsigned char blue = 0; + if (init) red = green = blue = 0; + +#define GET_NEXT_COLOR \ + red++; \ + if (red == 255) \ + { \ + red = 0; \ + green++; \ + if (green == 255) \ + { \ + green = 0; \ + blue++; \ + } \ + } + + GET_NEXT_COLOR + /*Get another color if color equal with background color*/ + if ((bg_color->r == (double)red) && + (bg_color->g == (double)green) && + (bg_color->b == (double)blue)) + { + GET_NEXT_COLOR + } + + if ((red == 255) && (green == 255) && (blue == 255)) + { + ERR("Overfill number of color. %d %s", __LINE__, __FILE__); + red = green = blue = 0; + } + + color->r = (double)red / 255; + color->g = (double)green / 255; + color->b = (double)blue / 255; +#undef GET_NEXT_COLOR +#endif return eina_stringshare_printf("%p %p", node, mesh); } diff --git a/src/lib/evas/canvas/evas_3d_scene.c b/src/lib/evas/canvas/evas_3d_scene.c index 2b33c8a..6784c99 100644 --- a/src/lib/evas/canvas/evas_3d_scene.c +++ b/src/lib/evas/canvas/evas_3d_scene.c @@ -635,7 +635,7 @@ _evas_3d_scene_pick(Eo *obj, Evas_3D_Scene_Data *pd, Evas_Real x, Evas_Real y, Evas_3D_Object_Data *pd_parent; Evas_Public_Data *e; int tex = 0, px, py;; - double redcomponent; + Evas_Color color = {0.0, 0.0, 0.0}; Eina_Stringshare *tmp; Eina_Array *arr = NULL; Eina_Bool update_scene = EINA_FALSE; @@ -694,8 +694,8 @@ _evas_3d_scene_pick(Eo *obj, Evas_3D_Scene_Data *pd, Evas_Real x, Evas_Real y, tex = e->engine.func->drawable_texture_color_pick_id_get(pd->surface); if (e->engine.func->drawable_texture_pixel_color_get) { - redcomponent = e->engine.func->drawable_texture_pixel_color_get(tex, px, py, pd->surface); - tmp = eina_stringshare_printf("%f %f %f", redcomponent, 0.0, 0.0); + e->engine.func->drawable_texture_pixel_color_get(tex, px, py, &color, pd->surface); + tmp = eina_stringshare_printf("%f %f %f", color.r, color.g, color.b); arr = (Eina_Array *)eina_hash_find(pd->colors_node_mesh, tmp); if (arr) { diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index e7c8d02..4464a60 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -382,8 +382,11 @@ struct _Evas_3D_Mesh Evas_Color fog_color; Eina_Bool fog_enabled :1; - +#ifndef GL_GLES double color_pick_key; +#else + Evas_Color color_pick_key; +#endif Eina_Bool color_pick_enabled :1; }; @@ -1398,7 +1401,7 @@ struct _Evas_Func Eina_Bool (*drawable_scene_render_to_texture) (void *data, void *drawable, void *scene_data); int (*drawable_texture_color_pick_id_get) (void *drawable); - double (*drawable_texture_pixel_color_get) (unsigned int tex EINA_UNUSED, int x, int y, void *drawable); + void (*drawable_texture_pixel_color_get) (unsigned int tex EINA_UNUSED, int x, int y, Evas_Color *color, void *drawable); void *(*texture_new) (void *data, Eina_Bool use_atlas); void (*texture_free) (void *data, void *texture); 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 8caf9ae..0662612 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c @@ -316,6 +316,8 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #ifndef GL_GLES glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #endif glGenFramebuffers(1, &fbo); @@ -394,8 +396,6 @@ e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_fo drawable->tex = tex; drawable->fbo = fbo; drawable->depth_stencil_buf = depth_stencil_buf; - drawable->texcolorpick = texcolorpick; - drawable->color_pick_fb_id = color_pick_fb_id; drawable->depth_buf = depth_buf; drawable->stencil_buf = stencil_buf; drawable->texDepth = texDepth; @@ -1317,13 +1317,13 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende Eina_Iterator *itmn; void *ptrmn; Eina_List *repeat_node = NULL; - Evas_Color c = {0, 0, 0, 0}, *unic_color = NULL; + Evas_Color c = {0.0, 0.0, 0.0, 0.0}, *unic_color = NULL; glBindFramebuffer(GL_FRAMEBUFFER, drawable->color_pick_fb_id); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawable->texcolorpick, 0); #ifdef GL_GLES - glBindTexture(GL_TEXTURE_2D, drawable->depth_stencil_buf); + glBindRenderbuffer(GL_RENDERBUFFER, drawable->depth_stencil_buf); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, drawable->depth_stencil_buf, 0); #else @@ -1366,7 +1366,13 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende unic_color = (Evas_Color *)eina_hash_find(data->node_mesh_colors, tmp); if (unic_color) { +#ifndef GL_GLES pdmesh->color_pick_key = unic_color->r; +#else + pdmesh->color_pick_key.r = unic_color->r; + pdmesh->color_pick_key.g = unic_color->g; + pdmesh->color_pick_key.b = unic_color->b; +#endif shade_mode = pdmesh->shade_mode; pdmesh->shade_mode = EVAS_3D_SHADE_MODE_COLOR_PICK; _mesh_draw(renderer, nm->mesh, nm->frame, NULL, matrix_eye, &matrix_mv, @@ -1385,25 +1391,26 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende return EINA_TRUE; } -double +void e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, - void *drawable) + Evas_Color *color, void *drawable) { E3D_Drawable *d = (E3D_Drawable *)drawable; - GLuint pixel; glBindFramebuffer(GL_FRAMEBUFFER, d->color_pick_fb_id); - /*TODO Bottle neck - get more effective getting pixels from openGL*/ #ifndef GL_GLES + GLuint pixel = 0; glReadPixels(x, y, 1, 1, GL_RED, GL_UNSIGNED_SHORT, &pixel); - glBindFramebuffer(GL_FRAMEBUFFER, d->fbo); - return (double)pixel / USHRT_MAX; + color->r = (double)pixel / USHRT_MAX; #else - // FIXME: Verify this logic. UNTESTED! (build fix was required) - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); - glBindFramebuffer(GL_FRAMEBUFFER, d->fbo); - return ((double)R_VAL(&pixel)) / 255.0; + GLubyte pixel[4] = {0, 0, 0, 0}; + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); + color->r = (double)pixel[0] / 255; + color->g = (double)pixel[1] / 255; + color->b = (double)pixel[2] / 255; #endif + + glBindFramebuffer(GL_FRAMEBUFFER, d->fbo); } #undef RENDER_MESH_NODE_ITERATE_BEGIN diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_common.h b/src/modules/evas/engines/gl_common/evas_gl_3d_common.h index fdb4784..cda8548 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_3d_common.h @@ -31,7 +31,7 @@ Eina_Bool e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable void e3d_drawable_size_get(E3D_Drawable *drawable, int *w, int *h); GLuint e3d_drawable_texture_id_get(E3D_Drawable *drawable); GLuint e3d_drawable_texture_color_pick_id_get(E3D_Drawable *drawable); -double e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, void *drawable); +void e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, Evas_Color *color, void *drawable); GLenum e3d_drawable_format_get(E3D_Drawable *drawable); /* Renderer */ 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 ad8d992..d1c467b 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 @@ -106,7 +106,11 @@ struct _E3D_Draw_Data Evas_Color specular; } light; Evas_Color fog_color; +#ifndef GL_GLES double color_pick_key; +#else + Evas_Color color_pick_key; +#endif }; struct _E3D_Texture diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c b/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c index 7c9b2fc..694ce8a 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c @@ -580,9 +580,16 @@ _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data) case E3D_UNIFORM_FOG_COLOR: glUniform4f(loc, data->fog_color.r, data->fog_color.g, data->fog_color.b, 1); break; +#ifndef GL_GLES case E3D_UNIFORM_COLOR_PICK: glUniform1f(loc, data->color_pick_key); break; +#else + case E3D_UNIFORM_COLOR_PICK: + glUniform4f(loc, data->color_pick_key.r, data->color_pick_key.g, + data->color_pick_key.b, 1.0); + break; +#endif case E3D_UNIFORM_ALPHATEST_COMPARISON: glUniform1i(loc, (data->alpha_comparison ? data->alpha_comparison : EVAS_3D_COMPARISON_GREATER)); 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 index 071f60e..5a526b9 100644 --- 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 @@ -1,9 +1,19 @@ -uniform float uColorPick; +#ifndef GL_ES + uniform float uColorPick; +#else + uniform vec4 uColorPick; +#endif FRAGMENT_SHADER_USE_ALPHA_TEST_GLES void main() { - vec4 color = vec4(uColorPick); + vec4 color; + +#ifndef GL_ES + color = vec4(uColorPick); +#else + color = uColorPick; +#endif #ifdef ALPHA_TEST_ENABLED FRAGMENT_SHADER_ALPHA_TEST_GLES_APPLY(color) 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 0505e41..1a282f6 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 @@ -1658,14 +1658,23 @@ static const char color_pick_frag_glsl[] = "precision mediump int;\n" "precision lowp sampler2D;\n" "#endif\n" - "uniform float uColorPick;\n" + "#ifndef GL_ES\n" + " uniform float uColorPick;\n" + "#else\n" + " uniform vec4 uColorPick;\n" + "#endif\n" "#ifdef GL_ES\n" "uniform int uAlphaTestComparison;\n" "uniform float uAlphaTestRefValue;\n" "#endif //GL_ES\n" "void main()\n" "{\n" - " vec4 color = vec4(uColorPick);\n" + " vec4 color;\n" + "#ifndef GL_ES\n" + " color = vec4(uColorPick);\n" + "#else\n" + " color = uColorPick;\n" + "#endif\n" "#ifdef ALPHA_TEST_ENABLED\n" " #ifdef GL_ES\n" "/*uAlphaTestComparison is value of the Evas_3D_Comparison type*/\n" diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index eed3e2c..34d3f45 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2182,10 +2182,11 @@ eng_drawable_texture_color_pick_id_get(void *drawable) return e3d_drawable_texture_color_pick_id_get((E3D_Drawable *)drawable); } -static double -eng_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, void *drawable) +static void +eng_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, + Evas_Color *color, void *drawable) { - return e3d_drawable_texture_pixel_color_get(tex, x, y, drawable); + return e3d_drawable_texture_pixel_color_get(tex, x, y, color, drawable); } static Eina_Bool --
