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
This commit is contained in:
se.osadchy 2015-05-26 19:12:24 +02:00 committed by Cedric BAIL
parent 8915982562
commit 684c51360f
11 changed files with 120 additions and 29 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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));

View File

@ -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)

View File

@ -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"

View File

@ -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