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 <cedric@osg.samsung.com>
This commit is contained in:
Oleksandr Shcherbina 2015-11-10 15:10:09 -08:00 committed by Cedric BAIL
parent 705b08ed74
commit 13b1756394
5 changed files with 100 additions and 64 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -271,6 +271,25 @@ e3d_renderer_target_set(E3D_Renderer *renderer, E3D_Drawable *target)
renderer->texDepth = target->texDepth;
}
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)
{