#include "evas_gl_private.h"
#include "evas_gl_3d_private.h"
+#define RENDER_MESH_NODE_ITERATE_BEGIN(param) \
+ Evas_Mat4 matrix_mv; \
+ Evas_Mat4 matrix_mvp; \
+ Eina_Iterator *it; \
+ void *ptr; \
+ evas_mat4_multiply(&matrix_mv, matrix_##param, &pd_mesh_node->data.mesh.matrix_local_to_world); \
+ evas_mat4_multiply(&matrix_mvp, &pd->projection, &matrix_mv); \
+ it = eina_hash_iterator_data_new(pd_mesh_node->data.mesh.node_meshes); \
+ while (eina_iterator_next(it, &ptr)) \
+ { \
+ Evas_3D_Node_Mesh *nm = (Evas_3D_Node_Mesh *)ptr; \
+ Evas_3D_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_3D_MESH_CLASS);
+
+#define RENDER_MESH_NODE_ITERATE_END \
+ } \
+ eina_iterator_free(it);
+
void
e3d_texture_param_update(E3D_Texture *texture)
{
e3d_drawable_new(int w, int h, int alpha, GLenum depth_format, GLenum stencil_format)
{
E3D_Drawable *drawable = NULL;
- GLuint tex, fbo, texDepth;
+ GLuint tex, fbo, texDepth, texcolorpick, color_pick_fb_id;
GLuint depth_stencil_buf = 0;
GLuint depth_buf = 0;
GLuint stencil_buf = 0;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, w, h, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
#endif
+ glGenTextures(1, &texcolorpick);
+ glBindTexture(GL_TEXTURE_2D, texcolorpick);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ 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);
+#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);
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;
if (tex)
glDeleteTextures(1, &tex);
+ if (texcolorpick)
+ glDeleteTextures(1, &texcolorpick);
if (fbo)
glDeleteFramebuffers(1, &fbo);
+ if (color_pick_fb_id)
+ glDeleteFramebuffers(1, &color_pick_fb_id);
if (depth_stencil_buf)
{
return drawable->tex;
}
+GLuint
+e3d_drawable_texture_color_pick_id_get(E3D_Drawable *drawable)
+{
+ return drawable->texcolorpick;
+}
+
GLenum
e3d_drawable_format_get(E3D_Drawable *drawable)
{
if (pdmesh->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->blending = pdmesh->blending;
data->blend_sfactor = pdmesh->blend_sfactor;
data->blend_dfactor = pdmesh->blend_dfactor;
{
BUILD(vertex_attrib, VERTEX_POSITION, EINA_TRUE);
}
+ else if (pdmesh->shade_mode == EVAS_3D_SHADE_MODE_COLOR_PICK)
+ {
+ BUILD(vertex_attrib, VERTEX_POSITION, EINA_TRUE);
+ }
else if (pdmesh->shade_mode == EVAS_3D_SHADE_MODE_DIFFUSE)
{
BUILD(vertex_attrib, VERTEX_POSITION, EINA_TRUE);
EINA_LIST_FOREACH(data->mesh_nodes, l, n)
{
- Evas_Mat4 matrix_mv;
- Evas_Mat4 matrix_mvp;
- Eina_Iterator *it;
- void *ptr;
-
Evas_3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, EVAS_3D_NODE_CLASS);
if (evas_is_sphere_in_frustum(&pd_mesh_node->bsphere, planes))
{
-
- evas_mat4_multiply(&matrix_mv, matrix_light_eye, &pd_mesh_node->data.mesh.matrix_local_to_world);
- evas_mat4_multiply(&matrix_mvp, &pd->projection,
- &matrix_mv);
-
- it = eina_hash_iterator_data_new(pd_mesh_node->data.mesh.node_meshes);
-
- while (eina_iterator_next(it, &ptr))
+ RENDER_MESH_NODE_ITERATE_BEGIN(light_eye)
{
- Evas_3D_Node_Mesh *nm = (Evas_3D_Node_Mesh *)ptr;
- Evas_3D_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_3D_MESH_CLASS);
shade_mode = pdmesh->shade_mode;
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);
pdmesh->shade_mode = shade_mode;
}
- eina_iterator_free(it);
+ RENDER_MESH_NODE_ITERATE_END
}
}
}
e3d_renderer_flush(renderer);
}
+
+Eina_Bool
+e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *renderer,
+ Evas_3D_Scene_Public_Data *data)
+{
+ const Evas_Mat4 *matrix_eye;
+ Evas_3D_Shade_Mode shade_mode;
+ Eina_Stringshare *tmp;
+ Eina_Iterator *itmn;
+ void *ptrmn;
+ Eina_List *repeat_node = NULL;
+ Evas_Color c = {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);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_TEXTURE_2D, drawable->depth_stencil_buf, 0);
+#else
+ glBindRenderbuffer(GL_RENDERBUFFER, drawable->depth_stencil_buf);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, drawable->depth_stencil_buf);
+#endif
+
+ e3d_renderer_clear(renderer, &c);
+
+ Evas_3D_Node_Data *pd_camera_node = eo_data_scope_get(data->camera_node, EVAS_3D_NODE_CLASS);
+ matrix_eye = &pd_camera_node->data.camera.matrix_world_to_eye;
+ Evas_3D_Camera_Data *pd = eo_data_scope_get(pd_camera_node->data.camera.camera, EVAS_3D_CAMERA_CLASS);
+
+ itmn = eina_hash_iterator_data_new(data->colors_node_mesh);
+
+ while (eina_iterator_next(itmn, &ptrmn))
+ {
+ Evas_3D_Node *n;
+ Eina_Array *arr = NULL;
+
+ arr = (Eina_Array *)ptrmn;
+ n = (Evas_3D_Node *)eina_array_data_get(arr, 0);
+ /*To avoid repeatedly render mesh*/
+ if (!repeat_node)
+ repeat_node = eina_list_append(repeat_node, (void*)n);
+ else
+ {
+ if (eina_list_data_find(repeat_node, (void *)n))
+ continue;
+ else
+ repeat_node = eina_list_append(repeat_node, (void *)n);
+ }
+ Evas_3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, EVAS_3D_NODE_CLASS);
+ RENDER_MESH_NODE_ITERATE_BEGIN(eye)
+ {
+ if (pdmesh->color_pick_enabled)
+ {
+ tmp = eina_stringshare_printf("%p %p", n, nm->mesh);
+ unic_color = (Evas_Color *)eina_hash_find(data->node_mesh_colors, tmp);
+ if (unic_color)
+ {
+ pdmesh->color_pick_key = unic_color->r;
+ 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,
+ &matrix_mvp, NULL);
+ pdmesh->shade_mode = shade_mode;
+ }
+ eina_stringshare_del(tmp);
+ }
+ }
+ RENDER_MESH_NODE_ITERATE_END
+ }
+
+ eina_iterator_free(itmn);
+ eina_list_free(repeat_node);
+ glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
+ return EINA_TRUE;
+}
+
+double
+e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y,
+ 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*/
+ glReadPixels(x, y, 1, 1, GL_RED, GL_UNSIGNED_SHORT, &pixel);
+ glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
+ return (double)pixel / USHRT_MAX;
+}
+
+#undef RENDER_MESH_NODE_ITERATE_BEGIN
+#undef RENDER_MESH_NODE_ITERATE_END