forked from enlightenment/efl
evas sample code - remove makefile.am
Summary: evas gl sample Test Plan: cd efl/ > make examples > cd examples/evas > ./evas_gl Reviewers: Hermet Reviewed By: Hermet CC: cedric Differential Revision: https://phab.enlightenment.org/D1130
This commit is contained in:
parent
0b8423c961
commit
f86b05386c
|
@ -217,6 +217,11 @@ evas_3d_obj_SOURCES = evas-3d-obj.c
|
|||
evas_3d_obj_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
||||
evas_3d_obj_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
|
||||
|
||||
EXTRA_PROGRAMS += evas_gl
|
||||
evas_gl_SOURCES = evas-gl.c
|
||||
evas_gl_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
||||
evas_gl_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
|
||||
|
||||
.edc.edj:
|
||||
$(AM_V_EDJ)$(EDJE_CC) $(EDJE_CC_FLAGS) $< $(builddir)/$(@F)
|
||||
|
||||
|
|
|
@ -0,0 +1,488 @@
|
|||
//Add Evas_GL.h for Evas GL APIs access.
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
#include <Evas_GL.h>
|
||||
#include <math.h>
|
||||
|
||||
#define WIDTH 500
|
||||
#define HEIGHT 500
|
||||
|
||||
//GL related data here...
|
||||
typedef struct _GLData
|
||||
{
|
||||
Evas_Object *win;
|
||||
Evas_GL *evasgl;
|
||||
Evas_GL_API *glapi;
|
||||
Evas_GL_Context *ctx;
|
||||
Evas_GL_Surface *sfc;
|
||||
Evas_Object *img;
|
||||
|
||||
unsigned int program;
|
||||
unsigned int vtx_shader;
|
||||
unsigned int fgmt_shader;
|
||||
unsigned int vbo;
|
||||
float view[16];
|
||||
|
||||
float xangle;
|
||||
float yangle;
|
||||
Eina_Bool mouse_down : 1;
|
||||
Eina_Bool initialized : 1;
|
||||
|
||||
} GLData;
|
||||
|
||||
static GLData gldata;
|
||||
|
||||
//Define the cube's vertices
|
||||
//Each vertex consist of x, y, z, r, g, b
|
||||
const float cube_vertices[] =
|
||||
{
|
||||
//front surface is blue
|
||||
0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
0.5, -0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0,
|
||||
//left surface is green
|
||||
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 1.0, 0.0,
|
||||
//top surface is red
|
||||
-0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 1.0, 0.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 1.0, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 1.0, 0.0, 0.0,
|
||||
//right surface is yellow
|
||||
0.5, 0.5, -0.5, 1.0, 1.0, 0.0,
|
||||
0.5, -0.5, 0.5, 1.0, 1.0, 0.0,
|
||||
0.5, -0.5, -0.5, 1.0, 1.0, 0.0,
|
||||
0.5, 0.5, -0.5, 1.0, 1.0, 0.0,
|
||||
0.5, 0.5, 0.5, 1.0, 1.0, 0.0,
|
||||
0.5, -0.5, 0.5, 1.0, 1.0, 0.0,
|
||||
//back surface is cyan
|
||||
-0.5, 0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
0.5, -0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
0.5, 0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
0.5, -0.5, -0.5, 0.0, 1.0, 1.0,
|
||||
//bottom surface is magenta
|
||||
-0.5, -0.5, -0.5, 1.0, 0.0, 1.0,
|
||||
0.5, -0.5, 0.5, 1.0, 0.0, 1.0,
|
||||
-0.5, -0.5, 0.5, 1.0, 0.0, 1.0,
|
||||
-0.5, -0.5, -0.5, 1.0, 0.0, 1.0,
|
||||
0.5, -0.5, -0.5, 1.0, 0.0, 1.0,
|
||||
0.5, -0.5, 0.5, 1.0, 0.0, 1.0
|
||||
};
|
||||
|
||||
//Vertext Shader Source
|
||||
static const char vertex_shader[] =
|
||||
"attribute vec4 vPosition;\n"
|
||||
"attribute vec3 inColor;\n"
|
||||
"uniform mat4 mvpMatrix;"
|
||||
"varying vec3 outColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" outColor = inColor;\n"
|
||||
" gl_Position = mvpMatrix * vPosition;\n"
|
||||
"}\n";
|
||||
|
||||
//Fragment Shader Source
|
||||
static const char fragment_shader[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"varying vec3 outColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = vec4 ( outColor, 1.0 );\n"
|
||||
"}\n";
|
||||
|
||||
//Rotation Operation related functions here...
|
||||
static void
|
||||
init_matrix(float matrix[16])
|
||||
{
|
||||
matrix[0] = 1.0f;
|
||||
matrix[1] = 0.0f;
|
||||
matrix[2] = 0.0f;
|
||||
matrix[3] = 0.0f;
|
||||
|
||||
matrix[4] = 0.0f;
|
||||
matrix[5] = 1.0f;
|
||||
matrix[6] = 0.0f;
|
||||
matrix[7] = 0.0f;
|
||||
|
||||
matrix[8] = 0.0f;
|
||||
matrix[9] = 0.0f;
|
||||
matrix[10] = 1.0f;
|
||||
matrix[11] = 0.0f;
|
||||
|
||||
matrix[12] = 0.0f;
|
||||
matrix[13] = 0.0f;
|
||||
matrix[14] = 0.0f;
|
||||
matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
static void
|
||||
multiply_matrix(float matrix[16], const float matrix0[16],
|
||||
const float matrix1[16])
|
||||
{
|
||||
int i;
|
||||
int row;
|
||||
int column;
|
||||
float temp[16];
|
||||
|
||||
for (column = 0; column < 4; column++)
|
||||
{
|
||||
for (row = 0; row < 4; row++)
|
||||
{
|
||||
temp[(column * 4) + row] = 0.0f;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
temp[(column * 4) + row] += matrix0[(i * 4) + row] * matrix1[(column * 4) + i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
matrix[i] = temp[i];
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_xyz(float matrix[16], const float anglex, const float angley,
|
||||
const float anglez)
|
||||
{
|
||||
const float pi = 3.141592f;
|
||||
float temp[16];
|
||||
float rx = 2.0f * pi * anglex / 360.0f;
|
||||
float ry = 2.0f * pi * angley / 360.0f;
|
||||
float rz = 2.0f * pi * anglez / 360.0f;
|
||||
float sy = sinf(ry);
|
||||
float cy = cosf(ry);
|
||||
float sx = sinf(rx);
|
||||
float cx = cosf(rx);
|
||||
float sz = sinf(rz);
|
||||
float cz = cosf(rz);
|
||||
|
||||
init_matrix(temp);
|
||||
|
||||
temp[0] = (cy * cz) - (sx * sy * sz);
|
||||
temp[1] = (cz * sx * sy) + (cy * sz);
|
||||
temp[2] = -cx * sy;
|
||||
|
||||
temp[4] = -cx * sz;
|
||||
temp[5] = cx * cz;
|
||||
temp[6] = sx;
|
||||
|
||||
temp[8] = (cz * sy) + (cy * sx * sz);
|
||||
temp[9] = (-cy * cz * sx) + (sy * sz);
|
||||
temp[10] = cx * cy;
|
||||
|
||||
multiply_matrix(matrix, matrix, temp);
|
||||
}
|
||||
|
||||
static int
|
||||
view_set_ortho(float result[16], const float left, const float right,
|
||||
const float bottom, const float top, const float near,
|
||||
const float far)
|
||||
{
|
||||
if ((right - left) == 0.0f || (top - bottom) == 0.0f || (far - near) == 0.0f)
|
||||
return 0;
|
||||
|
||||
result[0] = 2.0f / (right - left);
|
||||
result[1] = 0.0f;
|
||||
result[2] = 0.0f;
|
||||
result[3] = 0.0f;
|
||||
result[4] = 0.0f;
|
||||
result[5] = 2.0f / (top - bottom);
|
||||
result[6] = 0.0f;
|
||||
result[7] = 0.0f;
|
||||
result[8] = 0.0f;
|
||||
result[9] = 0.0f;
|
||||
result[10] = -2.0f / (far - near);
|
||||
result[11] = 0.0f;
|
||||
result[12] = -(right + left) / (right - left);
|
||||
result[13] = -(top + bottom) / (top - bottom);
|
||||
result[14] = -(far + near) / (far - near);
|
||||
result[15] = 1.0f;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
init_shaders(GLData *gldata)
|
||||
{
|
||||
Evas_GL_API *gl = gldata->glapi;
|
||||
const char *p;
|
||||
|
||||
p = vertex_shader;
|
||||
gldata->vtx_shader = gl->glCreateShader(GL_VERTEX_SHADER);
|
||||
gl->glShaderSource(gldata->vtx_shader, 1, &p, NULL);
|
||||
gl->glCompileShader(gldata->vtx_shader);
|
||||
|
||||
p = fragment_shader;
|
||||
gldata->fgmt_shader = gl->glCreateShader(GL_FRAGMENT_SHADER);
|
||||
gl->glShaderSource(gldata->fgmt_shader, 1, &p, NULL);
|
||||
gl->glCompileShader(gldata->fgmt_shader);
|
||||
|
||||
gldata->program = gl->glCreateProgram();
|
||||
gl->glAttachShader(gldata->program, gldata->vtx_shader);
|
||||
gl->glAttachShader(gldata->program, gldata->fgmt_shader);
|
||||
gl->glBindAttribLocation(gldata->program, 0, "vPosition");
|
||||
gl->glBindAttribLocation(gldata->program, 1, "inColor");
|
||||
|
||||
gl->glLinkProgram(gldata->program);
|
||||
gl->glUseProgram(gldata->program);
|
||||
gl->glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
static void
|
||||
img_pixel_cb(void *data, Evas_Object *obj)
|
||||
{
|
||||
//Define the model view projection matrix
|
||||
float model[16], mvp[16];
|
||||
GLData *gldata = data;
|
||||
Evas_GL_API *glapi = gldata->glapi;
|
||||
|
||||
Evas_Coord w, h;
|
||||
evas_object_image_size_get(obj, &w, &h);
|
||||
|
||||
//Set up the context and surface as the current one
|
||||
evas_gl_make_current(gldata->evasgl, gldata->sfc, gldata->ctx);
|
||||
|
||||
//Initialize gl stuff just one time.
|
||||
if (!gldata->initialized)
|
||||
{
|
||||
float aspect;
|
||||
init_shaders(gldata);
|
||||
glapi->glGenBuffers(1, &gldata->vbo);
|
||||
glapi->glBindBuffer(GL_ARRAY_BUFFER, gldata->vbo);
|
||||
glapi->glBufferData(GL_ARRAY_BUFFER, 3 * 72 * 4, cube_vertices,GL_STATIC_DRAW);
|
||||
init_matrix(gldata->view);
|
||||
if(w > h)
|
||||
{
|
||||
aspect = (float)w/h;
|
||||
view_set_ortho(gldata->view, -1.0 * aspect, 1.0 * aspect, -1.0, 1.0, -1.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
aspect = (float)h/w;
|
||||
view_set_ortho(gldata->view, -1.0, 1.0, -1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
|
||||
}
|
||||
gldata->initialized = EINA_TRUE;
|
||||
}
|
||||
|
||||
glapi->glViewport(0, 0, w, h);
|
||||
glapi->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glapi->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
init_matrix(model);
|
||||
rotate_xyz(model, gldata->xangle, gldata->yangle, 0.0f);
|
||||
multiply_matrix(mvp, gldata->view, model);
|
||||
|
||||
glapi->glUseProgram(gldata->program);
|
||||
glapi->glBindBuffer(GL_ARRAY_BUFFER, gldata->vbo);
|
||||
glapi->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, 0);
|
||||
glapi->glEnableVertexAttribArray(0);
|
||||
|
||||
glapi->glBindBuffer(GL_ARRAY_BUFFER, gldata->vbo);
|
||||
glapi->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float)*3));
|
||||
glapi->glEnableVertexAttribArray(1);
|
||||
|
||||
glapi->glUniformMatrix4fv( glapi->glGetUniformLocation(gldata->program, "mvpMatrix"), 1, GL_FALSE, mvp);
|
||||
glapi->glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
glapi->glFinish();
|
||||
}
|
||||
|
||||
static void
|
||||
img_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
GLData *gldata = data;
|
||||
Evas_GL_API *glapi = gldata->glapi;
|
||||
|
||||
//Free the gl resources when image object is deleted.
|
||||
evas_gl_make_current(gldata->evasgl, gldata->sfc, gldata->ctx);
|
||||
|
||||
glapi->glDeleteShader(gldata->vtx_shader);
|
||||
glapi->glDeleteShader(gldata->fgmt_shader);
|
||||
glapi->glDeleteProgram(gldata->program);
|
||||
glapi->glDeleteBuffers(1, &gldata->vbo);
|
||||
|
||||
evas_gl_surface_destroy(gldata->evasgl, gldata->sfc);
|
||||
evas_gl_context_destroy(gldata->evasgl, gldata->ctx);
|
||||
|
||||
evas_gl_free(gldata->evasgl);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_animator_cb(void *data)
|
||||
{
|
||||
Evas_Object *img = data;
|
||||
|
||||
//Animate here whenever an animation tick happens and then mark the image as
|
||||
//"dirty" meaning it needs an update next time evas renders. it will call the
|
||||
//pixel get callback then.
|
||||
evas_object_image_pixels_dirty_set(img, EINA_TRUE);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
GLData *gldata = data;
|
||||
gldata->mouse_down = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||
{
|
||||
Evas_Event_Mouse_Move *ev;
|
||||
ev = (Evas_Event_Mouse_Move *)event_info;
|
||||
GLData *gldata = data;
|
||||
float dx = 0, dy = 0;
|
||||
|
||||
if( gldata->mouse_down)
|
||||
{
|
||||
dx = (ev->cur.canvas.x - ev->prev.canvas.x);
|
||||
dy = (ev->cur.canvas.y - ev->prev.canvas.y);
|
||||
gldata->xangle += dy;
|
||||
gldata->yangle += dx;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
GLData *gldata = data;
|
||||
gldata->mouse_down = EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_win_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
float aspect;
|
||||
Evas_Coord w,h;
|
||||
evas_object_geometry_get( obj, NULL, NULL, &w, &h);
|
||||
|
||||
GLData *gldata = data;
|
||||
evas_object_resize(gldata->img, w, h);
|
||||
|
||||
init_matrix(gldata->view);
|
||||
if(w > h)
|
||||
{
|
||||
aspect = (float)w/h;
|
||||
view_set_ortho(gldata->view, (-1.0 * aspect), (1.0 * aspect), -1.0, 1.0, -1.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
aspect = (float)h/w;
|
||||
view_set_ortho(gldata->view, -1.0, 1.0, (-1.0 * aspect), (1.0 * aspect), -1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
evas_gl_exam(Evas_Object *win)
|
||||
{
|
||||
Evas_Native_Surface ns;
|
||||
|
||||
//Config for the surface for evas gl
|
||||
Evas_GL_Config config =
|
||||
{
|
||||
EVAS_GL_RGBA_8888,
|
||||
EVAS_GL_DEPTH_BIT_32,
|
||||
EVAS_GL_STENCIL_NONE
|
||||
};
|
||||
|
||||
//Get the window size
|
||||
Evas_Coord w,h;
|
||||
evas_object_geometry_get(win, NULL, NULL, &w, &h);
|
||||
|
||||
//Get the evas gl handle for doing gl things
|
||||
gldata.evasgl = evas_gl_new(evas_object_evas_get(win));
|
||||
gldata.glapi = evas_gl_api_get(gldata.evasgl);
|
||||
|
||||
//Create a surface and context
|
||||
gldata.sfc = evas_gl_surface_create(gldata.evasgl, &config, w, h);
|
||||
gldata.ctx = evas_gl_context_create(gldata.evasgl, NULL);
|
||||
|
||||
//Set rotation variables
|
||||
gldata.xangle = 45.0f;
|
||||
gldata.yangle = 45.0f;
|
||||
gldata.mouse_down = EINA_FALSE;
|
||||
|
||||
//Set up the image object. A filled one by default.
|
||||
gldata.img = evas_object_image_filled_add(evas_object_evas_get(win));
|
||||
evas_object_event_callback_add(gldata.img, EVAS_CALLBACK_DEL, img_del_cb, &gldata);
|
||||
|
||||
//Set up an actual pixel size for the buffer data. It may be different to the
|
||||
//output size. Any windowing sysmtem has something like this, just evas has 2
|
||||
//sizes, a pixel size and the output object size.
|
||||
evas_object_image_size_set(gldata.img, w, h);
|
||||
|
||||
//Set up the native surface info to use the context and surface created
|
||||
//above.
|
||||
evas_gl_native_surface_get(gldata.evasgl, gldata.sfc, &ns);
|
||||
evas_object_image_native_surface_set(gldata.img, &ns);
|
||||
evas_object_image_pixels_get_callback_set(gldata.img, img_pixel_cb, &gldata);
|
||||
|
||||
evas_object_resize(gldata.img, w, h);
|
||||
evas_object_show(gldata.img);
|
||||
|
||||
//Add Mouse Event Callbacks
|
||||
evas_object_event_callback_add(gldata.img, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, &gldata);
|
||||
evas_object_event_callback_add(gldata.img, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, &gldata);
|
||||
evas_object_event_callback_add(gldata.img, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb, &gldata);
|
||||
//Add Window Resize Event Callback
|
||||
evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _win_resize_cb, &gldata);
|
||||
|
||||
ecore_animator_add(_animator_cb, gldata.img);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_delete_cb(Ecore_Evas *ee EINA_UNUSED)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_on_canvas_resize_cb(Ecore_Evas *ee)
|
||||
{
|
||||
int w, h;
|
||||
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
|
||||
evas_object_resize(gldata.win, w, h);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
if (!ecore_evas_init()) return 0;
|
||||
|
||||
Ecore_Evas *ecore_evas = ecore_evas_new("opengl_x11", 0, 0, WIDTH, HEIGHT, NULL);
|
||||
|
||||
if(!ecore_evas) return 0;
|
||||
|
||||
ecore_evas_callback_delete_request_set(ecore_evas, _on_delete_cb);
|
||||
ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize_cb);
|
||||
ecore_evas_show(ecore_evas);
|
||||
|
||||
Evas_Object *evas = ecore_evas_get(ecore_evas);
|
||||
|
||||
gldata.win = evas_object_rectangle_add(evas);
|
||||
evas_object_color_set(gldata.win, 255, 255, 255, 255);
|
||||
evas_object_resize(gldata.win, WIDTH, HEIGHT);
|
||||
evas_object_show(gldata.win);
|
||||
|
||||
evas_gl_exam(gldata.win);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
ecore_evas_free(ecore_evas);
|
||||
ecore_evas_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue