forked from enlightenment/efl
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:
parent
705b08ed74
commit
13b1756394
|
@ -11,6 +11,7 @@ evas_canvas3d_scene_data_init(Evas_Canvas3D_Scene_Public_Data *data)
|
||||||
data->mesh_nodes = NULL;
|
data->mesh_nodes = NULL;
|
||||||
data->node_mesh_colors = NULL;
|
data->node_mesh_colors = NULL;
|
||||||
data->colors_node_mesh = NULL;
|
data->colors_node_mesh = NULL;
|
||||||
|
data->render_to_texture = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -447,6 +447,7 @@ struct _Evas_Canvas3D_Scene_Public_Data
|
||||||
/*sets constant for shadow rendering*/
|
/*sets constant for shadow rendering*/
|
||||||
Evas_Real depth_offset;
|
Evas_Real depth_offset;
|
||||||
Evas_Real depth_constant;
|
Evas_Real depth_constant;
|
||||||
|
Eina_Bool render_to_texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Canvas3D_Pick_Data
|
struct _Evas_Canvas3D_Pick_Data
|
||||||
|
|
|
@ -1200,11 +1200,21 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer,
|
||||||
|
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
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
|
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;
|
Eina_List *l;
|
||||||
Evas_Canvas3D_Node *n;
|
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);
|
_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);
|
eina_matrix4_multiply(&matrix_vp, &pd->projection, matrix_eye);
|
||||||
evas_frustum_calculate(planes, &matrix_vp);
|
evas_frustum_calculate(planes, &matrix_vp);
|
||||||
|
|
||||||
EINA_LIST_FOREACH(data->mesh_nodes, l, n)
|
EINA_LIST_FOREACH(data->mesh_nodes, l, n)
|
||||||
{
|
{
|
||||||
Eina_Matrix4 matrix_mv;
|
Eina_Matrix4 matrix_mv;
|
||||||
|
@ -1282,6 +1289,17 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_C
|
||||||
e3d_renderer_flush(renderer);
|
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
|
Eina_Bool
|
||||||
e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *renderer,
|
e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *renderer,
|
||||||
Evas_Canvas3D_Scene_Public_Data *data)
|
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;
|
Eina_List *repeat_node = NULL;
|
||||||
Evas_Color c = {0.0, 0.0, 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);
|
e3d_renderer_color_pick_target_set(renderer, drawable);
|
||||||
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_clear(renderer, &c);
|
e3d_renderer_clear(renderer, &c);
|
||||||
|
|
||||||
Evas_Canvas3D_Node_Data *pd_camera_node = eo_data_scope_get(data->camera_node, EVAS_CANVAS3D_NODE_CLASS);
|
if (data->color_pick_enabled) //Use rendering to texture in color pick mechanism
|
||||||
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;
|
Evas_Canvas3D_Node_Data *pd_camera_node = eo_data_scope_get(data->camera_node, EVAS_CANVAS3D_NODE_CLASS);
|
||||||
Eina_Array *arr = NULL;
|
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;
|
itmn = eina_hash_iterator_data_new(data->colors_node_mesh);
|
||||||
n = (Evas_Canvas3D_Node *)eina_array_data_get(arr, 0);
|
|
||||||
/*To avoid repeatedly render mesh*/
|
while (eina_iterator_next(itmn, &ptrmn))
|
||||||
if (!repeat_node)
|
{
|
||||||
repeat_node = eina_list_append(repeat_node, (void*)n);
|
Evas_Canvas3D_Node *n;
|
||||||
else
|
Eina_Array *arr = NULL;
|
||||||
{
|
|
||||||
if (eina_list_data_find(repeat_node, (void *)n))
|
arr = (Eina_Array *)ptrmn;
|
||||||
continue;
|
n = (Evas_Canvas3D_Node *)eina_array_data_get(arr, 0);
|
||||||
else
|
/*To avoid repeatedly render mesh*/
|
||||||
repeat_node = eina_list_append(repeat_node, (void *)n);
|
if (!repeat_node)
|
||||||
}
|
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);
|
else
|
||||||
RENDER_MESH_NODE_ITERATE_BEGIN(eye)
|
{
|
||||||
{
|
if (eina_list_data_find(repeat_node, (void *)n))
|
||||||
if (pdmesh->color_pick_enabled)
|
continue;
|
||||||
{
|
else
|
||||||
tmp = eina_stringshare_printf("%p %p", n, nm->mesh);
|
repeat_node = eina_list_append(repeat_node, (void *)n);
|
||||||
unic_color = (Evas_Color *)eina_hash_find(data->node_mesh_colors, tmp);
|
}
|
||||||
if (unic_color)
|
Evas_Canvas3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, EVAS_CANVAS3D_NODE_CLASS);
|
||||||
{
|
RENDER_MESH_NODE_ITERATE_BEGIN(eye)
|
||||||
pdmesh->color_pick_key.r = unic_color->r;
|
{
|
||||||
pdmesh->color_pick_key.g = unic_color->g;
|
if (pdmesh->color_pick_enabled)
|
||||||
pdmesh->color_pick_key.b = unic_color->b;
|
{
|
||||||
shade_mode = pdmesh->shade_mode;
|
tmp = eina_stringshare_printf("%p %p", n, nm->mesh);
|
||||||
pdmesh->shade_mode = EVAS_CANVAS3D_SHADE_MODE_COLOR_PICK;
|
unic_color = (Evas_Color *)eina_hash_find(data->node_mesh_colors, tmp);
|
||||||
_mesh_draw(renderer, nm->mesh, nm->frame, NULL, matrix_eye, &matrix_mv,
|
if (unic_color)
|
||||||
&matrix_mvp, NULL);
|
{
|
||||||
pdmesh->shade_mode = shade_mode;
|
pdmesh->color_pick_key.r = unic_color->r;
|
||||||
}
|
pdmesh->color_pick_key.g = unic_color->g;
|
||||||
eina_stringshare_del(tmp);
|
pdmesh->color_pick_key.b = unic_color->b;
|
||||||
}
|
shade_mode = pdmesh->shade_mode;
|
||||||
}
|
pdmesh->shade_mode = EVAS_CANVAS3D_SHADE_MODE_COLOR_PICK;
|
||||||
RENDER_MESH_NODE_ITERATE_END
|
_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);
|
glBindFramebuffer(GL_FRAMEBUFFER, drawable->fbo);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_clear(E3D_Renderer *renderer, const Evas_Color *color);
|
||||||
void e3d_renderer_draw(E3D_Renderer *renderer, E3D_Draw_Data *data);
|
void e3d_renderer_draw(E3D_Renderer *renderer, E3D_Draw_Data *data);
|
||||||
void e3d_renderer_flush(E3D_Renderer *renderer);
|
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 */
|
#endif /* EVAS_GL_3D_PRIVATE_H */
|
||||||
|
|
|
@ -271,6 +271,25 @@ e3d_renderer_target_set(E3D_Renderer *renderer, E3D_Drawable *target)
|
||||||
renderer->texDepth = target->texDepth;
|
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
|
void
|
||||||
e3d_renderer_clear(E3D_Renderer *renderer EINA_UNUSED, const Evas_Color *color)
|
e3d_renderer_clear(E3D_Renderer *renderer EINA_UNUSED, const Evas_Color *color)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue