cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=13b1756394006a60eb7e9fc59ed9fd3017a3b7f9

commit 13b1756394006a60eb7e9fc59ed9fd3017a3b7f9
Author: Oleksandr Shcherbina <o.shcherb...@samsung.com>
Date:   Tue Nov 10 15:10:09 2015 -0800

    evas: add possibility to render current 3D scene to texture in Evas.Canvas3d
    
    Summary:
    Refactoring code of functions e3d_drawable_scene_render,
    e3d_drawable_scene_render_to_texture,_shadowmap_render to have possibility
    render in scene to additional texture
    See T2761
    
    Reviewers: Hermet, cedric
    
    Subscribers: cedric
    
    Differential Revision: https://phab.enlightenment.org/D3142
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/lib/evas/canvas/evas_canvas3d_scene.c          |   1 +
 src/lib/evas/include/evas_private.h                |   1 +
 src/modules/evas/engines/gl_common/evas_gl_3d.c    | 144 +++++++++++----------
 .../evas/engines/gl_common/evas_gl_3d_private.h    |   1 +
 .../evas/engines/gl_common/evas_gl_3d_renderer.c   |  19 +++
 5 files changed, 101 insertions(+), 65 deletions(-)

diff --git a/src/lib/evas/canvas/evas_canvas3d_scene.c 
b/src/lib/evas/canvas/evas_canvas3d_scene.c
index 6bc4487..d0634d4 100644
--- a/src/lib/evas/canvas/evas_canvas3d_scene.c
+++ b/src/lib/evas/canvas/evas_canvas3d_scene.c
@@ -11,6 +11,7 @@ evas_canvas3d_scene_data_init(Evas_Canvas3D_Scene_Public_Data 
*data)
    data->mesh_nodes = NULL;
    data->node_mesh_colors = NULL;
    data->colors_node_mesh = NULL;
+   data->render_to_texture = EINA_FALSE;
 }
 
 void
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index f237a2e..92c4444 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -447,6 +447,7 @@ struct _Evas_Canvas3D_Scene_Public_Data
    /*sets constant for shadow rendering*/
    Evas_Real depth_offset;
    Evas_Real depth_constant;
+   Eina_Bool render_to_texture;
 };
 
 struct _Evas_Canvas3D_Pick_Data
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 93c2e85..357039c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_3d.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c
@@ -1200,11 +1200,21 @@ void _shadowmap_render(E3D_Drawable *drawable, 
E3D_Renderer *renderer,
 
      glDisable(GL_POLYGON_OFFSET_FILL);
 
-     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_2D, drawable->tex, 0);
+     if (data->render_to_texture)
+       {
+          data->render_to_texture = EINA_FALSE;
+          e3d_renderer_color_pick_target_set(renderer, drawable);
+       }
+     else
+       {
+          glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_2D,
+                                 drawable->tex, 0);
+          e3d_renderer_clear(renderer, &data->bg_color);
+       }
 }
 
 void
-e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, 
Evas_Canvas3D_Scene_Public_Data *data)
+_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, 
Evas_Canvas3D_Scene_Public_Data *data)
 {
    Eina_List        *l;
    Evas_Canvas3D_Node     *n;
@@ -1232,12 +1242,9 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, 
E3D_Renderer *renderer, Evas_C
          _shadowmap_render(drawable, renderer, data, &matrix_light_eye, light);
      }
 
-   /* Set up render target. */
-   e3d_renderer_target_set(renderer, drawable);
-   e3d_renderer_clear(renderer, &data->bg_color);
-
    eina_matrix4_multiply(&matrix_vp, &pd->projection, matrix_eye);
    evas_frustum_calculate(planes, &matrix_vp);
+
    EINA_LIST_FOREACH(data->mesh_nodes, l, n)
      {
         Eina_Matrix4          matrix_mv;
@@ -1282,6 +1289,17 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, 
E3D_Renderer *renderer, Evas_C
    e3d_renderer_flush(renderer);
 }
 
+void
+e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, 
Evas_Canvas3D_Scene_Public_Data *data)
+{
+   /* Set up render target. */
+   e3d_renderer_target_set(renderer, drawable);
+   e3d_renderer_clear(renderer, &data->bg_color);
+
+   /*Render scene data*/
+   _scene_render(drawable, renderer, data);
+}
+
 Eina_Bool
 e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer 
*renderer,
                                      Evas_Canvas3D_Scene_Public_Data *data)
@@ -1294,71 +1312,67 @@ e3d_drawable_scene_render_to_texture(E3D_Drawable 
*drawable, E3D_Renderer *rende
    Eina_List *repeat_node = 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
-   glBindRenderbuffer(GL_RENDERBUFFER, 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_color_pick_target_set(renderer, drawable);
    e3d_renderer_clear(renderer, &c);
 
-   Evas_Canvas3D_Node_Data *pd_camera_node = 
eo_data_scope_get(data->camera_node, EVAS_CANVAS3D_NODE_CLASS);
-   matrix_eye = &pd_camera_node->data.camera.matrix_world_to_eye;
-   Evas_Canvas3D_Camera_Data *pd = 
eo_data_scope_get(pd_camera_node->data.camera.camera, 
EVAS_CANVAS3D_CAMERA_CLASS);
-
-   itmn = eina_hash_iterator_data_new(data->colors_node_mesh);
-
-   while (eina_iterator_next(itmn, &ptrmn))
+   if (data->color_pick_enabled) //Use rendering to texture in color pick 
mechanism
      {
-        Evas_Canvas3D_Node      *n;
-        Eina_Array *arr = NULL;
-
-        arr = (Eina_Array *)ptrmn;
-        n = (Evas_Canvas3D_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_Canvas3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, 
EVAS_CANVAS3D_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.r = unic_color->r;
-                       pdmesh->color_pick_key.g = unic_color->g;
-                       pdmesh->color_pick_key.b = unic_color->b;
-                       shade_mode = pdmesh->shade_mode;
-                       pdmesh->shade_mode = 
EVAS_CANVAS3D_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
+         Evas_Canvas3D_Node_Data *pd_camera_node = 
eo_data_scope_get(data->camera_node, EVAS_CANVAS3D_NODE_CLASS);
+         matrix_eye = &pd_camera_node->data.camera.matrix_world_to_eye;
+         Evas_Canvas3D_Camera_Data *pd = 
eo_data_scope_get(pd_camera_node->data.camera.camera, 
EVAS_CANVAS3D_CAMERA_CLASS);
+
+         itmn = eina_hash_iterator_data_new(data->colors_node_mesh);
+
+         while (eina_iterator_next(itmn, &ptrmn))
+           {
+              Evas_Canvas3D_Node      *n;
+              Eina_Array *arr = NULL;
+
+              arr = (Eina_Array *)ptrmn;
+              n = (Evas_Canvas3D_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_Canvas3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, 
EVAS_CANVAS3D_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.r = unic_color->r;
+                             pdmesh->color_pick_key.g = unic_color->g;
+                             pdmesh->color_pick_key.b = unic_color->b;
+                             shade_mode = pdmesh->shade_mode;
+                             pdmesh->shade_mode = 
EVAS_CANVAS3D_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);
+     }
+   else
+     {
+        _scene_render(drawable, renderer, data); //Just render scene in texture
      }
 
-   eina_iterator_free(itmn);
-   eina_list_free(repeat_node);
    glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
+
    return EINA_TRUE;
 }
 
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 387eafe..56f98c1 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
@@ -170,5 +170,6 @@ void                 e3d_renderer_viewport_set(E3D_Renderer 
*renderer, int x, in
 void                 e3d_renderer_clear(E3D_Renderer *renderer, const 
Evas_Color *color);
 void                 e3d_renderer_draw(E3D_Renderer *renderer, E3D_Draw_Data 
*data);
 void                 e3d_renderer_flush(E3D_Renderer *renderer);
+void                 e3d_renderer_color_pick_target_set(E3D_Renderer 
*renderer, E3D_Drawable *drawable);
 
 #endif /* EVAS_GL_3D_PRIVATE_H */
diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_renderer.c 
b/src/modules/evas/engines/gl_common/evas_gl_3d_renderer.c
index 2b0e7ae..aff604c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_3d_renderer.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_3d_renderer.c
@@ -272,6 +272,25 @@ e3d_renderer_target_set(E3D_Renderer *renderer, 
E3D_Drawable *target)
 }
 
 void
+e3d_renderer_color_pick_target_set(E3D_Renderer *renderer, E3D_Drawable 
*drawable)
+{
+   glBindFramebuffer(GL_FRAMEBUFFER, drawable->color_pick_fb_id);
+   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                          GL_TEXTURE_2D, drawable->texcolorpick, 0);
+#ifdef GL_GLES
+   glBindRenderbuffer(GL_RENDERBUFFER, 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
+   glViewport(0, 0, drawable->w, drawable->h);
+   renderer->texDepth = drawable->texDepth;
+}
+
+void
 e3d_renderer_clear(E3D_Renderer *renderer EINA_UNUSED, const Evas_Color *color)
 {
    glClearColor(color->r, color->g, color->b, color->a);

-- 


Reply via email to