forked from enlightenment/efl
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:
parent
8915982562
commit
684c51360f
|
@ -124,8 +124,13 @@ _mesh_init(Evas_3D_Mesh_Data *pd)
|
||||||
pd->alpha_comparison = EVAS_3D_COMPARISON_ALWAYS;
|
pd->alpha_comparison = EVAS_3D_COMPARISON_ALWAYS;
|
||||||
pd->alpha_ref_value = 0.0f;
|
pd->alpha_ref_value = 0.0f;
|
||||||
pd->alpha_test_enabled = EINA_FALSE;
|
pd->alpha_test_enabled = EINA_FALSE;
|
||||||
|
#ifndef GL_GLES
|
||||||
pd->color_pick_key = -1.0;
|
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;
|
pd->color_pick_enabled = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
_generate_unic_color_key(Evas_Color *color, Evas_Color *bg_color, Evas_3D_Node *node, Evas_3D_Mesh *mesh,
|
||||||
Eina_Bool init)
|
Eina_Bool init)
|
||||||
{
|
{
|
||||||
|
#ifndef GL_GLES
|
||||||
static unsigned short red = USHRT_MAX;
|
static unsigned short red = USHRT_MAX;
|
||||||
|
|
||||||
if (init) 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--;
|
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);
|
return eina_stringshare_printf("%p %p", node, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_3D_Object_Data *pd_parent;
|
||||||
Evas_Public_Data *e;
|
Evas_Public_Data *e;
|
||||||
int tex = 0, px, py;;
|
int tex = 0, px, py;;
|
||||||
double redcomponent;
|
Evas_Color color = {0.0, 0.0, 0.0};
|
||||||
Eina_Stringshare *tmp;
|
Eina_Stringshare *tmp;
|
||||||
Eina_Array *arr = NULL;
|
Eina_Array *arr = NULL;
|
||||||
Eina_Bool update_scene = EINA_FALSE;
|
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);
|
tex = e->engine.func->drawable_texture_color_pick_id_get(pd->surface);
|
||||||
if (e->engine.func->drawable_texture_pixel_color_get)
|
if (e->engine.func->drawable_texture_pixel_color_get)
|
||||||
{
|
{
|
||||||
redcomponent = e->engine.func->drawable_texture_pixel_color_get(tex, px, py, pd->surface);
|
e->engine.func->drawable_texture_pixel_color_get(tex, px, py, &color, pd->surface);
|
||||||
tmp = eina_stringshare_printf("%f %f %f", redcomponent, 0.0, 0.0);
|
tmp = eina_stringshare_printf("%f %f %f", color.r, color.g, color.b);
|
||||||
arr = (Eina_Array *)eina_hash_find(pd->colors_node_mesh, tmp);
|
arr = (Eina_Array *)eina_hash_find(pd->colors_node_mesh, tmp);
|
||||||
if (arr)
|
if (arr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -382,8 +382,11 @@ struct _Evas_3D_Mesh
|
||||||
|
|
||||||
Evas_Color fog_color;
|
Evas_Color fog_color;
|
||||||
Eina_Bool fog_enabled :1;
|
Eina_Bool fog_enabled :1;
|
||||||
|
#ifndef GL_GLES
|
||||||
double color_pick_key;
|
double color_pick_key;
|
||||||
|
#else
|
||||||
|
Evas_Color color_pick_key;
|
||||||
|
#endif
|
||||||
Eina_Bool color_pick_enabled :1;
|
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);
|
Eina_Bool (*drawable_scene_render_to_texture) (void *data, void *drawable, void *scene_data);
|
||||||
|
|
||||||
int (*drawable_texture_color_pick_id_get) (void *drawable);
|
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_new) (void *data, Eina_Bool use_atlas);
|
||||||
void (*texture_free) (void *data, void *texture);
|
void (*texture_free) (void *data, void *texture);
|
||||||
|
|
|
@ -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);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
#ifndef GL_GLES
|
#ifndef GL_GLES
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
|
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
|
#endif
|
||||||
|
|
||||||
glGenFramebuffers(1, &fbo);
|
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->tex = tex;
|
||||||
drawable->fbo = fbo;
|
drawable->fbo = fbo;
|
||||||
drawable->depth_stencil_buf = depth_stencil_buf;
|
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->depth_buf = depth_buf;
|
||||||
drawable->stencil_buf = stencil_buf;
|
drawable->stencil_buf = stencil_buf;
|
||||||
drawable->texDepth = texDepth;
|
drawable->texDepth = texDepth;
|
||||||
|
@ -1317,13 +1317,13 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *rende
|
||||||
Eina_Iterator *itmn;
|
Eina_Iterator *itmn;
|
||||||
void *ptrmn;
|
void *ptrmn;
|
||||||
Eina_List *repeat_node = NULL;
|
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);
|
glBindFramebuffer(GL_FRAMEBUFFER, drawable->color_pick_fb_id);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, drawable->texcolorpick, 0);
|
GL_TEXTURE_2D, drawable->texcolorpick, 0);
|
||||||
#ifdef GL_GLES
|
#ifdef GL_GLES
|
||||||
glBindTexture(GL_TEXTURE_2D, drawable->depth_stencil_buf);
|
glBindRenderbuffer(GL_RENDERBUFFER, drawable->depth_stencil_buf);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||||
GL_TEXTURE_2D, drawable->depth_stencil_buf, 0);
|
GL_TEXTURE_2D, drawable->depth_stencil_buf, 0);
|
||||||
#else
|
#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);
|
unic_color = (Evas_Color *)eina_hash_find(data->node_mesh_colors, tmp);
|
||||||
if (unic_color)
|
if (unic_color)
|
||||||
{
|
{
|
||||||
|
#ifndef GL_GLES
|
||||||
pdmesh->color_pick_key = unic_color->r;
|
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;
|
shade_mode = pdmesh->shade_mode;
|
||||||
pdmesh->shade_mode = EVAS_3D_SHADE_MODE_COLOR_PICK;
|
pdmesh->shade_mode = EVAS_3D_SHADE_MODE_COLOR_PICK;
|
||||||
_mesh_draw(renderer, nm->mesh, nm->frame, NULL, matrix_eye, &matrix_mv,
|
_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;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
void
|
||||||
e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y,
|
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;
|
E3D_Drawable *d = (E3D_Drawable *)drawable;
|
||||||
GLuint pixel;
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, d->color_pick_fb_id);
|
glBindFramebuffer(GL_FRAMEBUFFER, d->color_pick_fb_id);
|
||||||
/*TODO Bottle neck - get more effective getting pixels from openGL*/
|
|
||||||
#ifndef GL_GLES
|
#ifndef GL_GLES
|
||||||
|
GLuint pixel = 0;
|
||||||
glReadPixels(x, y, 1, 1, GL_RED, GL_UNSIGNED_SHORT, &pixel);
|
glReadPixels(x, y, 1, 1, GL_RED, GL_UNSIGNED_SHORT, &pixel);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
|
color->r = (double)pixel / USHRT_MAX;
|
||||||
return (double)pixel / USHRT_MAX;
|
|
||||||
#else
|
#else
|
||||||
// FIXME: Verify this logic. UNTESTED! (build fix was required)
|
GLubyte pixel[4] = {0, 0, 0, 0};
|
||||||
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
|
color->r = (double)pixel[0] / 255;
|
||||||
return ((double)R_VAL(&pixel)) / 255.0;
|
color->g = (double)pixel[1] / 255;
|
||||||
|
color->b = (double)pixel[2] / 255;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef RENDER_MESH_NODE_ITERATE_BEGIN
|
#undef RENDER_MESH_NODE_ITERATE_BEGIN
|
||||||
|
|
|
@ -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);
|
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_id_get(E3D_Drawable *drawable);
|
||||||
GLuint e3d_drawable_texture_color_pick_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);
|
GLenum e3d_drawable_format_get(E3D_Drawable *drawable);
|
||||||
|
|
||||||
/* Renderer */
|
/* Renderer */
|
||||||
|
|
|
@ -106,7 +106,11 @@ struct _E3D_Draw_Data
|
||||||
Evas_Color specular;
|
Evas_Color specular;
|
||||||
} light;
|
} light;
|
||||||
Evas_Color fog_color;
|
Evas_Color fog_color;
|
||||||
|
#ifndef GL_GLES
|
||||||
double color_pick_key;
|
double color_pick_key;
|
||||||
|
#else
|
||||||
|
Evas_Color color_pick_key;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _E3D_Texture
|
struct _E3D_Texture
|
||||||
|
|
|
@ -580,9 +580,16 @@ _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data)
|
||||||
case E3D_UNIFORM_FOG_COLOR:
|
case E3D_UNIFORM_FOG_COLOR:
|
||||||
glUniform4f(loc, data->fog_color.r, data->fog_color.g, data->fog_color.b, 1);
|
glUniform4f(loc, data->fog_color.r, data->fog_color.g, data->fog_color.b, 1);
|
||||||
break;
|
break;
|
||||||
|
#ifndef GL_GLES
|
||||||
case E3D_UNIFORM_COLOR_PICK:
|
case E3D_UNIFORM_COLOR_PICK:
|
||||||
glUniform1f(loc, data->color_pick_key);
|
glUniform1f(loc, data->color_pick_key);
|
||||||
break;
|
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:
|
case E3D_UNIFORM_ALPHATEST_COMPARISON:
|
||||||
glUniform1i(loc,
|
glUniform1i(loc,
|
||||||
(data->alpha_comparison ? data->alpha_comparison : EVAS_3D_COMPARISON_GREATER));
|
(data->alpha_comparison ? data->alpha_comparison : EVAS_3D_COMPARISON_GREATER));
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
uniform float uColorPick;
|
#ifndef GL_ES
|
||||||
|
uniform float uColorPick;
|
||||||
|
#else
|
||||||
|
uniform vec4 uColorPick;
|
||||||
|
#endif
|
||||||
FRAGMENT_SHADER_USE_ALPHA_TEST_GLES
|
FRAGMENT_SHADER_USE_ALPHA_TEST_GLES
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 color = vec4(uColorPick);
|
vec4 color;
|
||||||
|
|
||||||
|
#ifndef GL_ES
|
||||||
|
color = vec4(uColorPick);
|
||||||
|
#else
|
||||||
|
color = uColorPick;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ALPHA_TEST_ENABLED
|
#ifdef ALPHA_TEST_ENABLED
|
||||||
FRAGMENT_SHADER_ALPHA_TEST_GLES_APPLY(color)
|
FRAGMENT_SHADER_ALPHA_TEST_GLES_APPLY(color)
|
||||||
|
|
|
@ -1658,14 +1658,23 @@ static const char color_pick_frag_glsl[] =
|
||||||
"precision mediump int;\n"
|
"precision mediump int;\n"
|
||||||
"precision lowp sampler2D;\n"
|
"precision lowp sampler2D;\n"
|
||||||
"#endif\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"
|
"#ifdef GL_ES\n"
|
||||||
"uniform int uAlphaTestComparison;\n"
|
"uniform int uAlphaTestComparison;\n"
|
||||||
"uniform float uAlphaTestRefValue;\n"
|
"uniform float uAlphaTestRefValue;\n"
|
||||||
"#endif //GL_ES\n"
|
"#endif //GL_ES\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\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 ALPHA_TEST_ENABLED\n"
|
||||||
" #ifdef GL_ES\n"
|
" #ifdef GL_ES\n"
|
||||||
"/*uAlphaTestComparison is value of the Evas_3D_Comparison type*/\n"
|
"/*uAlphaTestComparison is value of the Evas_3D_Comparison type*/\n"
|
||||||
|
|
|
@ -2182,10 +2182,11 @@ eng_drawable_texture_color_pick_id_get(void *drawable)
|
||||||
return e3d_drawable_texture_color_pick_id_get((E3D_Drawable *)drawable);
|
return e3d_drawable_texture_color_pick_id_get((E3D_Drawable *)drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static void
|
||||||
eng_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, void *drawable)
|
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
|
static Eina_Bool
|
||||||
|
|
Loading…
Reference in New Issue