\section{glview\+\_\+example\+\_\+01.\+c}

\begin{DoxyCodeInclude}

\textcolor{preprocessor}{#include <Elementary.h>}
\textcolor{preprocessor}{#include <Evas\_GL.h>}
\textcolor{preprocessor}{#include <stdio.h>}

\textcolor{keyword}{typedef} \textcolor{keyword}{struct }\_GLData GLData;

\textcolor{comment}{// GL related data here..}
\textcolor{keyword}{struct }\_GLData
\{
   Evas\_GL\_API *glapi;
   GLuint       program;
   GLuint       vtx\_shader;
   GLuint       fgmt\_shader;
   GLuint       vbo;
   \textcolor{keywordtype}{int}          initialized : 1;
\};

\textcolor{keyword}{static} \textcolor{keywordtype}{float} red = 1.0;

\textcolor{comment}{//--------------------------------//}
\textcolor{comment}{// a helper function to load shaders from a shader source}
\textcolor{keyword}{static} GLuint
load\_shader( GLData *gld, GLenum type, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *shader\_src )
\{
   Evas\_GL\_API *gl = gld->glapi;
   GLuint shader;
   GLint compiled;

   \textcolor{comment}{// Create the shader object}
   shader = gl->glCreateShader(type);
   \textcolor{keywordflow}{if} (shader==0)
     \textcolor{keywordflow}{return} 0;

   \textcolor{comment}{// Load/Compile shader source}
   gl->glShaderSource(shader, 1, &shader\_src, NULL);
   gl->glCompileShader(shader);
   gl->glGetShaderiv(shader, GL\_COMPILE\_STATUS, &compiled);

   \textcolor{keywordflow}{if} (!compiled)
     \{
        GLint info\_len = 0;
        gl->glGetShaderiv(shader, GL\_INFO\_LOG\_LENGTH, &info\_len);
        \textcolor{keywordflow}{if} (info\_len > 1)
          \{
             \textcolor{keywordtype}{char}* info\_log = malloc(\textcolor{keyword}{sizeof}(\textcolor{keywordtype}{char}) * info\_len);

             gl->glGetShaderInfoLog(shader, info\_len, NULL, info\_log);
             printf(\textcolor{stringliteral}{"Error compiling shader:\(\backslash\)n%s\(\backslash\)n======\(\backslash\)n%s\(\backslash\)n======\(\backslash\)n"}, info\_log, shader\_src );
             free(info\_log);
          \}
        gl->glDeleteShader(shader);
        \textcolor{keywordflow}{return} 0;
     \}

   \textcolor{keywordflow}{return} shader;
\}

\textcolor{comment}{// Initialize the shader and program object}
\textcolor{keyword}{static} \textcolor{keywordtype}{int}
init\_shaders(GLData *gld)
\{
   Evas\_GL\_API *gl = gld->glapi;
   GLbyte vShaderStr[] =
      \textcolor{stringliteral}{"attribute vec4 vPosition;    \(\backslash\)n"}
      \textcolor{stringliteral}{"void main()                  \(\backslash\)n"}
      \textcolor{stringliteral}{"\{                            \(\backslash\)n"}
      \textcolor{stringliteral}{"   gl\_Position = vPosition;  \(\backslash\)n"}
      \textcolor{stringliteral}{"\}                            \(\backslash\)n"};

   GLbyte fShaderStr[] =
      \textcolor{stringliteral}{"#ifdef GL\_ES                                 \(\backslash\)n"}
      \textcolor{stringliteral}{"precision mediump float;                     \(\backslash\)n"}
      \textcolor{stringliteral}{"#endif                                       \(\backslash\)n"}
      \textcolor{stringliteral}{"void main()                                  \(\backslash\)n"}
      \textcolor{stringliteral}{"\{                                            \(\backslash\)n"}
      \textcolor{stringliteral}{"  gl\_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\(\backslash\)n"}
      \textcolor{stringliteral}{"\}                                            \(\backslash\)n"};

   GLint linked;

   \textcolor{comment}{// Load the vertex/fragment shaders}
   gld->vtx\_shader  = load\_shader(gld, GL\_VERTEX\_SHADER, (\textcolor{keyword}{const} \textcolor{keywordtype}{char}*)vShaderStr);
   gld->fgmt\_shader = load\_shader(gld, GL\_FRAGMENT\_SHADER, (\textcolor{keyword}{const} \textcolor{keywordtype}{char}*)fShaderStr);

   \textcolor{comment}{// Create the program object}
   gld->program = gl->glCreateProgram( );
   \textcolor{keywordflow}{if} (gld->program==0)
     \textcolor{keywordflow}{return} 0;

   gl->glAttachShader(gld->program, gld->vtx\_shader);
   gl->glAttachShader(gld->program, gld->fgmt\_shader);

   gl->glBindAttribLocation(gld->program, 0, \textcolor{stringliteral}{"vPosition"});
   gl->glLinkProgram(gld->program);
   gl->glGetProgramiv(gld->program, GL\_LINK\_STATUS, &linked);

   \textcolor{keywordflow}{if} (!linked)
     \{
        GLint info\_len = 0;
        gl->glGetProgramiv(gld->program, GL\_INFO\_LOG\_LENGTH, &info\_len);
        \textcolor{keywordflow}{if} (info\_len > 1)
          \{
             \textcolor{keywordtype}{char}* info\_log = malloc(\textcolor{keyword}{sizeof}(\textcolor{keywordtype}{char}) * info\_len);

             gl->glGetProgramInfoLog(gld->program, info\_len, NULL, info\_log);
             printf(\textcolor{stringliteral}{"Error linking program:\(\backslash\)n%s\(\backslash\)n"}, info\_log);
             free(info\_log);
          \}
        gl->glDeleteProgram(gld->program);
        \textcolor{keywordflow}{return} 0;
     \}
   \textcolor{keywordflow}{return} 1;
\}

\textcolor{comment}{// Callbacks}
\textcolor{comment}{// intialize callback that gets called once for intialization}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_init\_gl(Evas\_Object *obj)
\{
   GLData *gld = evas\_object\_data\_get(obj, \textcolor{stringliteral}{"gld"});
   Evas\_GL\_API *gl = gld->glapi;
   GLfloat vVertices[] = \{
        0.0f,  0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f \};

   \textcolor{keywordflow}{if} (!init\_shaders(gld))
     \{
        printf(\textcolor{stringliteral}{"Error Initializing Shaders\(\backslash\)n"});
        \textcolor{keywordflow}{return};
     \}

   gl->glGenBuffers(1, &gld->vbo);
   gl->glBindBuffer(GL\_ARRAY\_BUFFER, gld->vbo);
   gl->glBufferData(GL\_ARRAY\_BUFFER, 3 * 3 * 4, vVertices, GL\_STATIC\_DRAW);
\}

\textcolor{comment}{// delete callback gets called when glview is deleted}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_del\_gl(Evas\_Object *obj)
\{
   GLData *gld = evas\_object\_data\_get(obj, \textcolor{stringliteral}{"gld"});
   \textcolor{keywordflow}{if} (!gld)
     \{
        printf(\textcolor{stringliteral}{"Unable to get GLData. \(\backslash\)n"});
        \textcolor{keywordflow}{return};
     \}
   Evas\_GL\_API *gl = gld->glapi;

   gl->glDeleteShader(gld->vtx\_shader);
   gl->glDeleteShader(gld->fgmt\_shader);
   gl->glDeleteProgram(gld->program);
   gl->glDeleteBuffers(1, &gld->vbo);

   evas\_object\_data\_del((Evas\_Object*)obj, \textcolor{stringliteral}{"..gld"});
   free(gld);
\}

\textcolor{comment}{// resize callback gets called every time object is resized}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_resize\_gl(Evas\_Object *obj)
\{
   \textcolor{keywordtype}{int} w, h;
   GLData *gld = evas\_object\_data\_get(obj, \textcolor{stringliteral}{"gld"});
   Evas\_GL\_API *gl = gld->glapi;

   elm\_glview\_size\_get(obj, &w, &h);

   \textcolor{comment}{// GL Viewport stuff. you can avoid doing this if viewport is all the}
   \textcolor{comment}{// same as last frame if you want}
   gl->glViewport(0, 0, w, h);
\}

\textcolor{comment}{// draw callback is where all the main GL rendering happens}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_draw\_gl(Evas\_Object *obj)
\{
   Evas\_GL\_API *gl = elm\_glview\_gl\_api\_get(obj);
   GLData *gld = evas\_object\_data\_get(obj, \textcolor{stringliteral}{"gld"});
   \textcolor{keywordflow}{if} (!gld) \textcolor{keywordflow}{return};
   \textcolor{keywordtype}{int} w, h;

   elm\_glview\_size\_get(obj, &w, &h);

   gl->glViewport(0, 0, w, h);
   gl->glClearColor(red,0.8,0.3,1);
   gl->glClear(GL\_COLOR\_BUFFER\_BIT);

   \textcolor{comment}{// Draw a Triangle}
   gl->glEnable(GL\_BLEND);

   gl->glUseProgram(gld->program);

   gl->glBindBuffer(GL\_ARRAY\_BUFFER, gld->vbo);
   gl->glVertexAttribPointer(0, 3, GL\_FLOAT, GL\_FALSE,
                             0, 0);
   gl->glEnableVertexAttribArray(0);

   gl->glDrawArrays(GL\_TRIANGLES, 0, 3);

   \textcolor{comment}{// Optional - Flush the GL pipeline}
   gl->glFinish();

   red -= 0.1;
   \textcolor{keywordflow}{if} (red < 0.0) red = 1.0;
\}

\textcolor{comment}{// just need to notify that glview has changed so it can render}
\textcolor{keyword}{static} Eina\_Bool
\_anim(\textcolor{keywordtype}{void} *data)
\{
   elm\_glview\_changed\_set(data);
   \textcolor{keywordflow}{return} EINA\_TRUE;
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_on\_done(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keywordtype}{void} *event\_info)
\{
   evas\_object\_del((Evas\_Object*)data);
   elm_exit();
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_del(\textcolor{keywordtype}{void} *data, Evas *evas, Evas\_Object *obj, \textcolor{keywordtype}{void} *event\_info)
\{
   Ecore\_Animator *ani = evas\_object\_data\_get(obj, \textcolor{stringliteral}{"ani"});
   ecore\_animator\_del(ani);
\}

EAPI\_MAIN \textcolor{keywordtype}{int}
elm\_main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
   Evas\_Object *win, *bx, *bt, *gl;
   Ecore\_Animator *ani;
   GLData *gld = NULL;

   \textcolor{keywordflow}{if} (!(gld = calloc(1, \textcolor{keyword}{sizeof}(GLData)))) \textcolor{keywordflow}{return} 1;

   elm_policy_set(ELM\_POLICY\_QUIT, ELM\_POLICY\_QUIT\_LAST\_WINDOW\_CLOSED);

   win = elm_win_util_standard_add(\textcolor{stringliteral}{"glview simple"}, \textcolor{stringliteral}{"GLView Simple"});
   elm\_win\_autodel\_set(win, EINA\_TRUE);

   bx = elm_box_add(win);
   evas\_object\_size\_hint\_weight\_set(bx, EVAS\_HINT\_EXPAND, EVAS\_HINT\_EXPAND);
   elm\_win\_resize\_object\_add(win, bx);
   evas\_object\_show(bx);

   \textcolor{comment}{//-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)}
   \textcolor{comment}{//-//}
   \textcolor{comment}{// create a new glview object}
   gl = elm_glview_add(win);
   gld->glapi = elm\_glview\_gl\_api\_get(gl);
   evas\_object\_size\_hint\_align\_set(gl, EVAS\_HINT\_FILL, EVAS\_HINT\_FILL);
   evas\_object\_size\_hint\_weight\_set(gl, EVAS\_HINT\_EXPAND, EVAS\_HINT\_EXPAND);
   \textcolor{comment}{// mode is simply for supporting alpha, depth buffering, and stencil}
   \textcolor{comment}{// buffering.}
   elm\_glview\_mode\_set(gl, ELM_GLVIEW_ALPHA | ELM_GLVIEW_DEPTH);
   \textcolor{comment}{// resize policy tells glview what to do with the surface when it}
   \textcolor{comment}{// resizes.  ELM\_GLVIEW\_RESIZE\_POLICY\_RECREATE will tell it to}
   \textcolor{comment}{// destroy the current surface and recreate it to the new size}
   elm\_glview\_resize\_policy\_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
   \textcolor{comment}{// render policy tells glview how it would like glview to render}
   \textcolor{comment}{// gl code. ELM\_GLVIEW\_RENDER\_POLICY\_ON\_DEMAND will have the gl}
   \textcolor{comment}{// calls called in the pixel\_get callback, which only gets called}
   \textcolor{comment}{// if the object is visible, hence ON\_DEMAND.  ALWAYS mode renders}
   \textcolor{comment}{// it despite the visibility of the object.}
   elm\_glview\_render\_policy\_set(gl, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND);
   \textcolor{comment}{// initialize callback function gets registered here}
   elm\_glview\_init\_func\_set(gl, \_init\_gl);
   \textcolor{comment}{// delete callback function gets registered here}
   elm\_glview\_del\_func\_set(gl, \_del\_gl);
   elm\_glview\_resize\_func\_set(gl, \_resize\_gl);
   elm\_glview\_render\_func\_set(gl, \_draw\_gl);
   \textcolor{comment}{//-//}
   \textcolor{comment}{//-//-//-// END GL INIT BLOB}

   elm\_box\_pack\_end(bx, gl);
   evas\_object\_show(gl);

   elm_object_focus_set(gl, EINA\_TRUE);

   \textcolor{comment}{// animating - just a demo. as long as you trigger an update on the image}
   \textcolor{comment}{// object via elm\_glview\_changed\_set() it will be updated.}
   \textcolor{comment}{//}
   \textcolor{comment}{// NOTE: if you delete gl, this animator will keep running trying to access}
   \textcolor{comment}{// gl so you'd better delete this animator with ecore\_animator\_del().}
   ani = ecore\_animator\_add(\_anim, gl);

   evas\_object\_data\_set(gl, \textcolor{stringliteral}{"ani"}, ani);
   evas\_object\_data\_set(gl, \textcolor{stringliteral}{"gld"}, gld);
   evas\_object\_event\_callback\_add(gl, EVAS\_CALLBACK\_DEL, \_del, gl);

   \textcolor{comment}{// add an 'OK' button to end the program}
   bt = elm_button_add(win);
   elm\_object\_text\_set(bt, \textcolor{stringliteral}{"OK"});
   evas\_object\_size\_hint\_align\_set(bt, EVAS\_HINT\_FILL, EVAS\_HINT\_FILL);
   evas\_object\_size\_hint\_weight\_set(bt, EVAS\_HINT\_EXPAND, 0.0);
   elm\_box\_pack\_end(bx, bt);
   evas\_object\_show(bt);
   evas\_object\_smart\_callback\_add(bt, \textcolor{stringliteral}{"clicked"}, \_on\_done, win);

   evas\_object\_resize(win, 320, 480);
   evas\_object\_show(win);

   \textcolor{comment}{// run the mainloop and process events and callbacks}
   elm_run();

   \textcolor{keywordflow}{return} 0;
\}
ELM_MAIN()
\end{DoxyCodeInclude}
 