Evas 3D
Since
1.10

Table of Contents

Introduction

Evas 3D is an extension to support 3D scene graph rendering into 2D Evas canvases, with tree-based scene graph manipulation and other typical 3D rendering techniques.

3D objects are used to describe three dimensional scenes and to provide interfaces to connect the scene to an Evas image object for rendering.

Scenes are constructed by locating cameras and lights and selecting desired meshes, and organizing Node objects into hierarchical n-ary tree data structures. The scene is stacked on the canvas with existing Evas objects, which permits intermingling 3D rendered content in existing 2D application layouts.

Rendering techniques supported by Evas 3D include flat and phong shading, normal and texture mapping, and triangle meshes. Existing Evas objects may also be used as textures inside the 3D scene, including EFL widgets and even application windows. This latter capability makes it possible to create a 3D version of an arbitrary EFL application with minimal code changes.

Introductory Example

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define EFL_BETA_API_SUPPORT
#endif
#include <Eo.h>
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#define WIDTH 400
#define HEIGHT 400
typedef struct _Scene_Data
{
Eo *scene;
Eo *root_node;
Eo *camera_node;
Eo *light_node;
Eo *mesh_node;
Eo *camera;
Eo *light;
Eo *mesh;
Eo *material;
} Scene_Data;
static Ecore_Evas *ecore_evas = NULL;
static Evas *evas = NULL;
static Eo *background = NULL;
static Eo *image = NULL;
static const float cube_vertices[] =
{
/* Front */
-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0,
-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0,
/* Back */
1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0,
-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0,
/* Left */
-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0,
-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0,
-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0,
/* Right */
1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0,
1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,
1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0,
/* Top */
-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0,
/* Bottom */
1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0,
};
static const unsigned short cube_indices[] =
{
/* Front */
0, 1, 2, 2, 1, 3,
/* Back */
4, 5, 6, 6, 5, 7,
/* Left */
8, 9, 10, 10, 9, 11,
/* Right */
12, 13, 14, 14, 13, 15,
/* Top */
16, 17, 18, 18, 17, 19,
/* Bottom */
20, 21, 22, 22, 21, 23
};
static void
_on_delete(Ecore_Evas *ee EINA_UNUSED)
{
}
static void
_on_canvas_resize(Ecore_Evas *ee)
{
int w, h;
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
efl_gfx_entity_size_set(background, EINA_SIZE2D(w, h));
efl_gfx_entity_size_set(image, EINA_SIZE2D(w, h));
}
static Eina_Bool
_animate_scene(void *data)
{
static float angle = 0.0f;
Scene_Data *scene = (Scene_Data *)data;
angle += 0.5;
evas_canvas3d_node_orientation_angle_axis_set(scene->mesh_node, angle, 1.0, 1.0, 1.0);
/* Rotate */
if (angle > 360.0) angle -= 360.0f;
return EINA_TRUE;
}
static void
_camera_setup(Scene_Data *data)
{
data->camera = efl_add(EVAS_CANVAS3D_CAMERA_CLASS, evas);
evas_canvas3d_camera_projection_perspective_set(data->camera, 60.0, 1.0, 2.0, 50.0);
data->camera_node =
efl_add(EVAS_CANVAS3D_NODE_CLASS, evas, evas_canvas3d_node_type_set(efl_added, EVAS_CANVAS3D_NODE_TYPE_CAMERA));
evas_canvas3d_node_camera_set(data->camera_node, data->camera);
evas_canvas3d_node_position_set(data->camera_node, 0.0, 0.0, 10.0);
evas_canvas3d_node_look_at_set(data->camera_node, EVAS_CANVAS3D_SPACE_PARENT, 0.0, 0.0, 0.0, EVAS_CANVAS3D_SPACE_PARENT, 0.0, 1.0, 0.0);
evas_canvas3d_node_member_add(data->root_node, data->camera_node);
}
static void
_light_setup(Scene_Data *data)
{
data->light = efl_add(EVAS_CANVAS3D_LIGHT_CLASS, evas);
evas_canvas3d_light_ambient_set(data->light, 0.2, 0.2, 0.2, 1.0);
evas_canvas3d_light_diffuse_set(data->light, 1.0, 1.0, 1.0, 1.0);
evas_canvas3d_light_specular_set(data->light, 1.0, 1.0, 1.0, 1.0);
data->light_node =
efl_add(EVAS_CANVAS3D_NODE_CLASS, evas, evas_canvas3d_node_type_set(efl_added, EVAS_CANVAS3D_NODE_TYPE_LIGHT));
evas_canvas3d_node_light_set(data->light_node, data->light);
evas_canvas3d_node_position_set(data->light_node, 0.0, 0.0, 10.0);
evas_canvas3d_node_look_at_set(data->light_node, EVAS_CANVAS3D_SPACE_PARENT, 0.0, 0.0, 0.0, EVAS_CANVAS3D_SPACE_PARENT, 0.0, 1.0, 0.0);
evas_canvas3d_node_member_add(data->root_node, data->light_node);
}
static void
_mesh_setup(Scene_Data *data)
{
/* Setup material. */
data->material = efl_add(EVAS_CANVAS3D_MATERIAL_CLASS, evas);
evas_canvas3d_material_enable_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT, EINA_TRUE);
evas_canvas3d_material_enable_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE, EINA_TRUE);
evas_canvas3d_material_enable_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR, EINA_TRUE);
evas_canvas3d_material_color_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT, 0.2, 0.2, 0.2, 1.0);
evas_canvas3d_material_color_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE, 0.8, 0.8, 0.8, 1.0);
evas_canvas3d_material_color_set(data->material, EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR, 1.0, 1.0, 1.0, 1.0);
evas_canvas3d_material_shininess_set(data->material, 100.0);
/* Setup mesh. */
data->mesh = efl_add(EVAS_CANVAS3D_MESH_CLASS, evas);
evas_canvas3d_mesh_frame_vertex_data_set(data->mesh, 0, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION, 12 * sizeof(float), &cube_vertices[ 0]);
evas_canvas3d_mesh_frame_vertex_data_set(data->mesh, 0, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL, 12 * sizeof(float), &cube_vertices[ 3]);
evas_canvas3d_mesh_frame_vertex_data_set(data->mesh, 0, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR, 12 * sizeof(float), &cube_vertices[ 6]);
evas_canvas3d_mesh_frame_vertex_data_set(data->mesh, 0, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD, 12 * sizeof(float), &cube_vertices[10]);
evas_canvas3d_mesh_index_data_set(data->mesh, EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_SHORT, 36, &cube_indices[0]);
evas_canvas3d_mesh_vertex_assembly_set(data->mesh, EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLES);
evas_canvas3d_mesh_shader_mode_set(data->mesh, EVAS_CANVAS3D_SHADER_MODE_PHONG);
evas_canvas3d_mesh_frame_material_set(data->mesh, 0, data->material);
data->mesh_node =
efl_add(EVAS_CANVAS3D_NODE_CLASS, evas, evas_canvas3d_node_type_set(efl_added, EVAS_CANVAS3D_NODE_TYPE_MESH));
evas_canvas3d_node_member_add(data->root_node, data->mesh_node);
evas_canvas3d_node_mesh_add(data->mesh_node, data->mesh);
}
static void
_scene_setup(Scene_Data *data)
{
data->scene = efl_add(EVAS_CANVAS3D_SCENE_CLASS, evas);
evas_canvas3d_scene_size_set(data->scene, WIDTH, HEIGHT);
evas_canvas3d_scene_background_color_set(data->scene, 0.0, 0.0, 0.0, 0.0);
data->root_node =
efl_add(EVAS_CANVAS3D_NODE_CLASS, evas, evas_canvas3d_node_type_set(efl_added, EVAS_CANVAS3D_NODE_TYPE_NODE));
_camera_setup(data);
_light_setup(data);
_mesh_setup(data);
evas_canvas3d_scene_root_node_set(data->scene, data->root_node);
evas_canvas3d_scene_camera_node_set(data->scene, data->camera_node);
}
int
main(void)
{
// Unless Evas 3D supports Software renderer, we force use of the gl backend.
putenv("ECORE_EVAS_ENGINE=opengl_x11");
Scene_Data data;
if (!ecore_evas_init()) return 0;
ecore_evas = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
if (!ecore_evas) return 0;
ecore_evas_callback_delete_request_set(ecore_evas, _on_delete);
ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize);
ecore_evas_show(ecore_evas);
evas = ecore_evas_get(ecore_evas);
_scene_setup(&data);
/* Add a background rectangle object. */
background = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas);
efl_gfx_color_set(background, 0, 0, 0, 255);
efl_gfx_entity_size_set(background, EINA_SIZE2D(WIDTH, HEIGHT));
efl_gfx_entity_visible_set(background, EINA_TRUE);
/* Add an image object for 3D scene rendering. */
image = efl_add(EFL_CANVAS_SCENE3D_CLASS, evas);
efl_gfx_entity_size_set(image, EINA_SIZE2D(WIDTH, HEIGHT));
efl_gfx_entity_visible_set(image, EINA_TRUE);
/* Set the image object as render target for 3D scene. */
efl_canvas_scene3d_set(image, data.scene);
/* Add animation timer callback. */
ecore_timer_add(0.016, _animate_scene, &data);
/* Enter main loop. */
ecore_evas_free(ecore_evas);
return 0;
}
evas_canvas3d_node_position_set
EOAPI void evas_canvas3d_node_position_set(Eo *obj, Evas_Real x, Evas_Real y, Evas_Real z)
Set the position of the given node.
evas_canvas3d_node_look_at_set
EOAPI void evas_canvas3d_node_look_at_set(Eo *obj, Evas_Canvas3D_Space target_space, Evas_Real x, Evas_Real y, Evas_Real z, Evas_Canvas3D_Space up_space, Evas_Real ux, Evas_Real uy, Evas_Real uz)
Rotate the given node to look at desired position.
ecore_evas_new
EAPI Ecore_Evas * ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options)
Creates a new Ecore_Evas based on engine name and common parameters.
Definition: ecore_evas.c:1059
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition: ecore_evas.c:668
ecore_evas_geometry_get
EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
Gets the geometry of an Ecore_Evas.
Definition: ecore_evas.c:1382
evas_canvas3d_scene_size_set
EOAPI void evas_canvas3d_scene_size_set(Eo *obj, int w, int h)
Set the resolution of a scene.
ecore_evas_callback_resize_set
EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
Sets a callback for Ecore_Evas resize events.
Definition: ecore_evas.c:1160
evas_canvas3d_scene_camera_node_set
EOAPI void evas_canvas3d_scene_camera_node_set(Eo *obj, Evas_Canvas3D_Node *node)
The camera node of a scene.
ecore_main_loop_quit
void ecore_main_loop_quit(void)
Quits the main loop once all the events currently on the queue have been processed.
Definition: ecore_main.c:1289
evas_canvas3d_mesh_frame_add
EOAPI void evas_canvas3d_mesh_frame_add(Eo *obj, int frame)
Add a key frame to the given mesh.
EINA_UNUSED
#define EINA_UNUSED
Definition: eina_types.h:321
evas_canvas3d_scene_background_color_set
EOAPI void evas_canvas3d_scene_background_color_set(Eo *obj, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
Set the background color of a scene.
EVAS_CANVAS3D_MESH_CLASS
#define EVAS_CANVAS3D_MESH_CLASS
Evas 3D canvas mesh class.
Definition: evas_canvas3d_mesh.eo.h:21
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition: ecore_evas.c:1103
EVAS_CANVAS3D_CAMERA_CLASS
#define EVAS_CANVAS3D_CAMERA_CLASS
Evas 3D canvas camera class.
Definition: evas_canvas3d_camera.eo.h:21
evas_canvas3d_mesh_frame_vertex_data_set
EOAPI void evas_canvas3d_mesh_frame_vertex_data_set(Eo *obj, int frame, Evas_Canvas3D_Vertex_Attrib attrib, int stride, const void *data)
Set the vertex data of the key frame of the given mesh.
evas_canvas3d_mesh_frame_material_set
EOAPI void evas_canvas3d_mesh_frame_material_set(Eo *obj, int frame, Evas_Canvas3D_Material *material)
The material of the key frame of the given mesh.
ecore_evas_init
EAPI int ecore_evas_init(void)
Inits the Ecore_Evas system.
Definition: ecore_evas.c:604
evas_canvas3d_material_shininess_set
EOAPI void evas_canvas3d_material_shininess_set(Eo *obj, Evas_Real shininess)
The shininess of the given material.
evas_canvas3d_node_light_set
EOAPI void evas_canvas3d_node_light_set(Eo *obj, Evas_Canvas3D_Light *light)
A light attached to the given node.
efl_add
#define efl_add(klass, parent,...)
Create a new object and add it to an existing parent object.
Definition: Eo.h:1542
evas_canvas3d_mesh_vertex_assembly_set
EOAPI void evas_canvas3d_mesh_vertex_assembly_set(Eo *obj, Evas_Canvas3D_Vertex_Assembly assembly)
The vertex assembly of the given mesh.
evas_canvas3d_light_specular_set
EOAPI void evas_canvas3d_light_specular_set(Eo *obj, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
Set the specular color of the given light.
ecore_timer_add
Ecore_Timer * ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
Creates a timer to call the given function in the given period of time.
Definition: ecore_timer.c:178
evas_canvas3d_material_enable_set
EOAPI void evas_canvas3d_material_enable_set(Eo *obj, Evas_Canvas3D_Material_Attrib attrib, Eina_Bool enable)
The material attribute enable flag of the given material.
EVAS_CANVAS3D_SCENE_CLASS
#define EVAS_CANVAS3D_SCENE_CLASS
Efl 3D canvas scene class.
Definition: evas_canvas3d_scene.eo.h:21
ecore_evas_callback_delete_request_set
EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
Sets a callback for Ecore_Evas delete request events.
Definition: ecore_evas.c:1196
Ecore_Evas.h
Evas wrapper functions.
evas_canvas3d_node_orientation_angle_axis_set
EOAPI void evas_canvas3d_node_orientation_angle_axis_set(Eo *obj, Evas_Real angle, Evas_Real x, Evas_Real y, Evas_Real z)
Set the orientation of the given node using axis-angle.
ecore_evas_get
EAPI Evas * ecore_evas_get(const Ecore_Evas *ee)
Gets an Ecore_Evas's Evas.
Definition: ecore_evas.c:1320
evas_canvas3d_node_type_set
EOAPI void evas_canvas3d_node_type_set(Eo *obj, Evas_Canvas3D_Node_Type type)
Get the type of the given node.
EVAS_CANVAS3D_MATERIAL_CLASS
#define EVAS_CANVAS3D_MATERIAL_CLASS
Evas 3D canvas material class.
Definition: evas_canvas3d_material.eo.h:21
ecore_main_loop_begin
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition: ecore_main.c:1279
evas_canvas3d_scene_root_node_set
EOAPI void evas_canvas3d_scene_root_node_set(Eo *obj, Evas_Canvas3D_Node *node)
The root node of a scene.
evas_canvas3d_light_ambient_set
EOAPI void evas_canvas3d_light_ambient_set(Eo *obj, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
Set the ambient color of the given light.
evas_canvas3d_node_camera_set
EOAPI void evas_canvas3d_node_camera_set(Eo *obj, Evas_Canvas3D_Object *camera)
A camera attached to the given node.
Evas
Eo Evas
Definition: Evas_Common.h:158
EINA_TRUE
#define EINA_TRUE
Definition: eina_types.h:508
Eo
struct _Eo_Opaque Eo
Definition: Eo.h:173
evas_canvas3d_mesh_vertex_count_set
EOAPI void evas_canvas3d_mesh_vertex_count_set(Eo *obj, unsigned int count)
The vertex count of the given mesh.
evas_canvas3d_node_member_add
EOAPI void evas_canvas3d_node_member_add(Eo *obj, Evas_Canvas3D_Node *member)
Add a member node to the given node.
evas_canvas3d_node_mesh_add
EOAPI void evas_canvas3d_node_mesh_add(Eo *obj, Evas_Canvas3D_Mesh *mesh)
Add a mesh to the given node.
evas_canvas3d_light_diffuse_set
EOAPI void evas_canvas3d_light_diffuse_set(Eo *obj, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
Set the diffuse color of the given light.
Eina_Bool
unsigned char Eina_Bool
Definition: eina_types.h:496
evas_canvas3d_mesh_index_data_set
EOAPI void evas_canvas3d_mesh_index_data_set(Eo *obj, Evas_Canvas3D_Index_Format format, int count, const void *indices)
Set the vertex index data of the given mesh.
EVAS_CANVAS3D_LIGHT_CLASS
#define EVAS_CANVAS3D_LIGHT_CLASS
Evas 3D canvas light class.
Definition: evas_canvas3d_light.eo.h:21
evas_canvas3d_material_color_set
EOAPI void evas_canvas3d_material_color_set(Eo *obj, Evas_Canvas3D_Material_Attrib attrib, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
Set the material attribute color of the given material.
evas_canvas3d_mesh_shader_mode_set
EOAPI void evas_canvas3d_mesh_shader_mode_set(Eo *obj, Evas_Canvas3D_Shader_Mode mode)
Set the shader mode of the given mesh.
evas_canvas3d_camera_projection_perspective_set
EOAPI void evas_canvas3d_camera_projection_perspective_set(Eo *obj, Evas_Real fovy, Evas_Real aspect, Evas_Real dnear, Evas_Real dfar)
Set the projection matrix of the given camera with perspective projection.
ecore_evas_show
EAPI void ecore_evas_show(Ecore_Evas *ee)
Shows an Ecore_Evas' window.
Definition: ecore_evas.c:1500
EVAS_CANVAS3D_NODE_CLASS
#define EVAS_CANVAS3D_NODE_CLASS
Evas 3D canvas node class.
Definition: evas_canvas3d_node.eo.h:21