Announcement

Collapse
No announcement yet.

Any OpenGL ES 2.0 with EGL example on Mesa?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Any OpenGL ES 2.0 with EGL example on Mesa?

    Hi,
    Is there any source code example using EGL and ES 2.0 on top of the (any) open source Linux drivers?

    I got an ES 2.0 book but it's hard to figure out how to bind EGL to X (if you know what I mean) to be able to run the examples from the book.

  • #2
    Originally posted by cl333r View Post
    Is there any source code example using EGL and ES 2.0 on top of the (any) open source Linux drivers? I got an ES 2.0 book but it's hard to figure out how to bind EGL to X (if you know what I mean) to be able to run the examples from the book.
    IIRC Michel made some changes to es2gears so that it built two versions - one for X and one for "DRI without X" which should give some pretty good examples. I wasn't able to find the commit when I took a quick look but will poke around when I have time.

    In theory there are some default options which should make the resulting code pretty portable - once you start specifying windows etc... you start getting tied to a specific window system.

    Comment


    • #3
      Originally posted by bridgman View Post
      IIRC Michel made some changes to es2gears so that it built two versions - one for X and one for "DRI without X" which should give some pretty good examples. I wasn't able to find the commit when I took a quick look but will poke around when I have time.

      In theory there are some default options which should make the resulting code pretty portable - once you start specifying windows etc... you start getting tied to a specific window system.
      Thanks a lot, I did "apt-get source es2gears" and found a few examples! Boy are they sophisticated, one has to do quite some X11 studying, EGL indeed doesn't save you from knowing quite a bit about the underlying system and its event system.

      For those interested, my Makefile:
      PHP Code:
      CC=gcc
      LIBS
      =-lX11 -lEGL -lGLESv2

      app
      es2tri.c
          
      $(CC) -$@ $< $(LIBS
      And the source file itself (es2tri.c) which draws a triangle which you can rotate with the up/down arrow keys:
      PHP Code:
      /**************************************************************************
       *
       * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
       * All Rights Reserved.
       *
       **************************************************************************/

      /*
       * Draw a triangle with X/EGL and OpenGL ES 2.x
       */

      #define USE_FULL_GL 0

      #include <assert.h>
      #include <math.h>
      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
      #include <X11/Xlib.h>
      #include <X11/Xutil.h>
      #include <X11/keysym.h>
      #if USE_FULL_GL
      #include <GL/gl.h>  /* use full OpenGL */
      #else
      #include <GLES2/gl2.h>  /* use OpenGL ES 2.x */
      #endif
      #include <EGL/egl.h>

      #define FLOAT_TO_FIXED(X)   ((X) * 65535.0)
      static GLfloat view_rotx 0.0view_roty 0.0;
      static 
      GLint u_matrix = -1;
      static 
      GLint attr_pos 0attr_color 1;

      static 
      void
      make_z_rot_matrix
      (GLfloat angleGLfloat *m)
      {
         
      float c cos(angle M_PI 180.0);
         
      float s sin(angle M_PI 180.0);
         
      int i;
         for (
      016i++)
            
      m[i] = 0.0;
         
      m[0] = m[5] = m[10] = m[15] = 1.0;

         
      m[0] = c;
         
      m[1] = s;
         
      m[4] = -s;
         
      m[5] = c;
      }

      static 
      void
      make_scale_matrix
      (GLfloat xsGLfloat ysGLfloat zsGLfloat *m)
      {
         
      int i;
         for (
      016i++)
            
      m[i] = 0.0;
         
      m[0] = xs;
         
      m[5] = ys;
         
      m[10] = zs;
         
      m[15] = 1.0;
      }


      static 
      void
      mul_matrix
      (GLfloat *prod, const GLfloat *a, const GLfloat *b)
      {
      #define A(row,col)  a[(col<<2)+row]
      #define B(row,col)  b[(col<<2)+row]
      #define P(row,col)  p[(col<<2)+row]
         
      GLfloat p[16];
         
      GLint i;
         for (
      04i++) {
            const 
      GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
            
      P(i,0) = ai0 B(0,0) + ai1 B(1,0) + ai2 B(2,0) + ai3 B(3,0);
            
      P(i,1) = ai0 B(0,1) + ai1 B(1,1) + ai2 B(2,1) + ai3 B(3,1);
            
      P(i,2) = ai0 B(0,2) + ai1 B(1,2) + ai2 B(2,2) + ai3 B(3,2);
            
      P(i,3) = ai0 B(0,3) + ai1 B(1,3) + ai2 B(2,3) + ai3 B(3,3);
         }
         
      memcpy(prodpsizeof(p));
      #undef A
      #undef B
      #undef PROD
      }


      static 
      void
      draw
      (void)
      {
         static const 
      GLfloat verts[3][2] = {
            { -
      1, -},
            {  
      1, -},
            {  
      0,  }
         };
         static const 
      GLfloat colors[3][3] = {
            { 
      10},
            { 
      01},
            { 
      00}
         };
         
      GLfloat mat[16], rot[16], scale[16];

         
      /* Set modelview/projection matrix */
         
      make_z_rot_matrix(view_rotxrot);
         
      make_scale_matrix(0.50.50.5scale);
         
      mul_matrix(matrotscale);
         
      glUniformMatrix4fv(u_matrix1GL_FALSEmat);

         
      glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);

         {
            
      glVertexAttribPointer(attr_pos2GL_FLOATGL_FALSE0verts);
            
      glVertexAttribPointer(attr_color3GL_FLOATGL_FALSE0colors);
            
      glEnableVertexAttribArray(attr_pos);
            
      glEnableVertexAttribArray(attr_color);

            
      glDrawArrays(GL_TRIANGLES03);

            
      glDisableVertexAttribArray(attr_pos);
            
      glDisableVertexAttribArray(attr_color);
         }
      }


      /* new window size or exposure */
      static void
      reshape
      (int widthint height)
      {
         
      glViewport(00, (GLintwidth, (GLintheight);
      }


      static 
      void
      create_shaders
      (void)
      {
         static const 
      char *fragShaderText =
            
      "varying vec4 v_color;\n"
            "void main() {\n"
            "   gl_FragColor = v_color;\n"
            "}\n"
      ;
         static const 
      char *vertShaderText =
            
      "uniform mat4 modelviewProjection;\n"
            "attribute vec4 pos;\n"
            "attribute vec4 color;\n"
            "varying vec4 v_color;\n"
            "void main() {\n"
            "   gl_Position = modelviewProjection * pos;\n"
            "   v_color = color;\n"
            "}\n"
      ;

         
      GLuint fragShadervertShaderprogram;
         
      GLint stat;

         
      fragShader glCreateShader(GL_FRAGMENT_SHADER);
         
      glShaderSource(fragShader1, (const char **) &fragShaderTextNULL);
         
      glCompileShader(fragShader);
         
      glGetShaderiv(fragShaderGL_COMPILE_STATUS, &stat);
         if (!
      stat) {
            
      printf("Error: fragment shader did not compile!\n");
            exit(
      1);
         }

         
      vertShader glCreateShader(GL_VERTEX_SHADER);
         
      glShaderSource(vertShader1, (const char **) &vertShaderTextNULL);
         
      glCompileShader(vertShader);
         
      glGetShaderiv(vertShaderGL_COMPILE_STATUS, &stat);
         if (!
      stat) {
            
      printf("Error: vertex shader did not compile!\n");
            exit(
      1);
         }

         
      program glCreateProgram();
         
      glAttachShader(programfragShader);
         
      glAttachShader(programvertShader);
         
      glLinkProgram(program);

         
      glGetProgramiv(programGL_LINK_STATUS, &stat);
         if (!
      stat) {
            
      char log[1000];
            
      GLsizei len;
            
      glGetProgramInfoLog(program1000, &lenlog);
            
      printf("Error: linking:\n%s\n"log);
            exit(
      1);
         }

         
      glUseProgram(program);

         if (
      1) {
            
      /* test setting attrib locations */
            
      glBindAttribLocation(programattr_pos"pos");
            
      glBindAttribLocation(programattr_color"color");
            
      glLinkProgram(program);  /* needed to put attribs into effect */
         
      }
         else {
            
      /* test automatic attrib locations */
            
      attr_pos glGetAttribLocation(program"pos");
            
      attr_color glGetAttribLocation(program"color");
         }

         
      u_matrix glGetUniformLocation(program"modelviewProjection");
         
      printf("Uniform modelviewProjection at %d\n"u_matrix);
         
      printf("Attrib pos at %d\n"attr_pos);
         
      printf("Attrib color at %d\n"attr_color);
      }


      static 
      void
      init
      (void)
      {
         
      typedef void (*proc)();

      #if 1 /* test code */
         
      proc p eglGetProcAddress("glMapBufferOES");
         
      assert(p);
      #endif

         
      glClearColor(0.40.40.40.0);

         
      create_shaders();
      }


      /*
       * Create an RGB, double-buffered X window.
       * Return the window and context handles.
       */
      static void
      make_x_window
      (Display *x_dpyEGLDisplay egl_dpy,
                    const 
      char *name,
                    
      int xint yint widthint height,
                    
      Window *winRet,
                    
      EGLContext *ctxRet,
                    
      EGLSurface *surfRet)
      {
         static const 
      EGLint attribs[] = {
            
      EGL_RED_SIZE1,
            
      EGL_GREEN_SIZE1,
            
      EGL_BLUE_SIZE1,
            
      EGL_DEPTH_SIZE1,
            
      EGL_RENDERABLE_TYPEEGL_OPENGL_ES2_BIT,
            
      EGL_NONE
         
      };
         static const 
      EGLint ctx_attribs[] = {
            
      EGL_CONTEXT_CLIENT_VERSION2,
            
      EGL_NONE
         
      };
         
      int scrnum;
         
      XSetWindowAttributes attr;
         
      unsigned long mask;
         
      Window root;
         
      Window win;
         
      XVisualInfo *visInfovisTemplate;
         
      int num_visuals;
         
      EGLContext ctx;
         
      EGLConfig config;
         
      EGLint num_configs;
         
      EGLint vid;

         
      scrnum DefaultScreenx_dpy );
         
      root RootWindowx_dpyscrnum );

         if (!
      eglChooseConfigegl_dpyattribs, &config1, &num_configs)) {
            
      printf("Error: couldn't get an EGL visual config\n");
            exit(
      1);
         }

         
      assert(config);
         
      assert(num_configs 0);

         if (!
      eglGetConfigAttrib(egl_dpyconfigEGL_NATIVE_VISUAL_ID, &vid)) {
            
      printf("Error: eglGetConfigAttrib() failed\n");
            exit(
      1);
         }

         
      /* The X window visual must match the EGL config */
         
      visTemplate.visualid vid;
         
      visInfo XGetVisualInfo(x_dpyVisualIDMask, &visTemplate, &num_visuals);
         if (!
      visInfo) {
            
      printf("Error: couldn't get X visual\n");
            exit(
      1);
         }

         
      /* window attributes */
         
      attr.background_pixel 0;
         
      attr.border_pixel 0;
         
      attr.colormap XCreateColormapx_dpyrootvisInfo->visualAllocNone);
         
      attr.event_mask StructureNotifyMask ExposureMask KeyPressMask;
         
      mask CWBackPixel CWBorderPixel CWColormap CWEventMask;

         
      win XCreateWindowx_dpyroot00widthheight,
                      
      0visInfo->depthInputOutput,
                      
      visInfo->visualmask, &attr );

         
      /* set hints and properties */
         
      {
            
      XSizeHints sizehints;
            
      sizehints.x;
            
      sizehints.y;
            
      sizehints.width  width;
            
      sizehints.height height;
            
      sizehints.flags USSize USPosition;
            
      XSetNormalHints(x_dpywin, &sizehints);
            
      XSetStandardProperties(x_dpywinnamename,
                                    
      None, (char **)NULL0, &sizehints);
         }

      #if USE_FULL_GL /* XXX fix this when eglBindAPI() works */
         
      eglBindAPI(EGL_OPENGL_API);
      #else
         
      eglBindAPI(EGL_OPENGL_ES_API);
      #endif

         
      ctx eglCreateContext(egl_dpyconfigEGL_NO_CONTEXTctx_attribs );
         if (!
      ctx) {
            
      printf("Error: eglCreateContext failed\n");
            exit(
      1);
         }

         
      /* test eglQueryContext() */
         
      {
            
      EGLint val;
            
      eglQueryContext(egl_dpyctxEGL_CONTEXT_CLIENT_VERSION, &val);
            
      assert(val == 2);
         }

         *
      surfRet eglCreateWindowSurface(egl_dpyconfigwinNULL);
         if (!*
      surfRet) {
            
      printf("Error: eglCreateWindowSurface failed\n");
            exit(
      1);
         }

         
      /* sanity checks */
         
      {
            
      EGLint val;
            
      eglQuerySurface(egl_dpy, *surfRetEGL_WIDTH, &val);
            
      assert(val == width);
            
      eglQuerySurface(egl_dpy, *surfRetEGL_HEIGHT, &val);
            
      assert(val == height);
            
      assert(eglGetConfigAttrib(egl_dpyconfigEGL_SURFACE_TYPE, &val));
            
      assert(val EGL_WINDOW_BIT);
         }

         
      XFree(visInfo);

         *
      winRet win;
         *
      ctxRet ctx;
      }


      static 
      void
      event_loop
      (Display *dpyWindow win,
                 
      EGLDisplay egl_dpyEGLSurface egl_surf)
      {
         while (
      1) {
            
      int redraw 0;
            
      XEvent event;

            
      XNextEvent(dpy, &event);

            switch (
      event.type) {
            case 
      Expose:
               
      redraw 1;
               break;
            case 
      ConfigureNotify:
               
      reshape(event.xconfigure.widthevent.xconfigure.height);
               break;
            case 
      KeyPress:
               {
                  
      char buffer[10];
                  
      int rcode;
                  
      code XLookupKeysym(&event.xkey0);
                  if (
      code == XK_Left) {
                     
      view_roty += 5.0;
                  }
                  else if (
      code == XK_Right) {
                     
      view_roty -= 5.0;
                  }
                  else if (
      code == XK_Up) {
                     
      view_rotx += 5.0;
                  }
                  else if (
      code == XK_Down) {
                     
      view_rotx -= 5.0;
                  }
                  else {
                     
      XLookupString(&event.xkeybuffersizeof(buffer),
                                       
      NULLNULL);
                     if (
      buffer[0] == 27) {
                        
      /* escape */
                        
      return;
                     }
                  }
               }
               
      redraw 1;
               break;
            default:
               ; 
      /*no-op*/
            
      }

            if (
      redraw) {
               
      draw();
               
      eglSwapBuffers(egl_dpyegl_surf);
            }
         }
      }


      static 
      void
      usage
      (void)
      {
         
      printf("Usage:\n");
         
      printf("  -display <displayname>  set the display to run on\n");
         
      printf("  -info                   display OpenGL renderer info\n");
      }


      int
      main
      (int argcchar *argv[])
      {
         const 
      int winWidth 300winHeight 300;
         
      Display *x_dpy;
         
      Window win;
         
      EGLSurface egl_surf;
         
      EGLContext egl_ctx;
         
      EGLDisplay egl_dpy;
         
      char *dpyName NULL;
         
      GLboolean printInfo GL_FALSE;
         
      EGLint egl_majoregl_minor;
         
      int i;
         const 
      char *s;

         for (
      1argci++) {
            if (
      strcmp(argv[i], "-display") == 0) {
               
      dpyName argv[i+1];
               
      i++;
            }
            else if (
      strcmp(argv[i], "-info") == 0) {
               
      printInfo GL_TRUE;
            }
            else {
               
      usage();
               return -
      1;
            }
         }

         
      x_dpy XOpenDisplay(dpyName);
         if (!
      x_dpy) {
            
      printf("Error: couldn't open display %s\n",
               
      dpyName dpyName getenv("DISPLAY"));
            return -
      1;
         }

         
      egl_dpy eglGetDisplay(x_dpy);
         if (!
      egl_dpy) {
            
      printf("Error: eglGetDisplay() failed\n");
            return -
      1;
         }

         if (!
      eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
            
      printf("Error: eglInitialize() failed\n");
            return -
      1;
         }

         
      eglQueryString(egl_dpyEGL_VERSION);
         
      printf("EGL_VERSION = %s\n"s);

         
      eglQueryString(egl_dpyEGL_VENDOR);
         
      printf("EGL_VENDOR = %s\n"s);

         
      eglQueryString(egl_dpyEGL_EXTENSIONS);
         
      printf("EGL_EXTENSIONS = %s\n"s);

         
      eglQueryString(egl_dpyEGL_CLIENT_APIS);
         
      printf("EGL_CLIENT_APIS = %s\n"s);

         
      make_x_window(x_dpyegl_dpy,
                       
      "OpenGL ES 2.x tri"00winWidthwinHeight,
                       &
      win, &egl_ctx, &egl_surf);

         
      XMapWindow(x_dpywin);
         if (!
      eglMakeCurrent(egl_dpyegl_surfegl_surfegl_ctx)) {
            
      printf("Error: eglMakeCurrent() failed\n");
            return -
      1;
         }

         if (
      printInfo) {
            
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
            
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
            
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
            
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
         }

         
      init();

         
      /* Set initial projection/viewing transformation.
          * We can't be sure we'll get a ConfigureNotify event when the window
          * first appears.
          */
         
      reshape(winWidthwinHeight);

         
      event_loop(x_dpywinegl_dpyegl_surf);

         
      eglDestroyContext(egl_dpyegl_ctx);
         
      eglDestroySurface(egl_dpyegl_surf);
         
      eglTerminate(egl_dpy);


         
      XDestroyWindow(x_dpywin);
         
      XCloseDisplay(x_dpy);

         return 
      0;

      Comment


      • #4
        Originally posted by cl333r View Post
        Hi,
        Is there any source code example using EGL and ES 2.0 on top of the (any) open source Linux drivers?

        I got an ES 2.0 book but it's hard to figure out how to bind EGL to X (if you know what I mean) to be able to run the examples from the book.
        I do not know much about it... This is really new information for me... And I want to know more on it. Thank you so much in advance.

        Comment


        • #5
          The mesa git repository has some EGL demos in progs/egl and all of their demos uses a small library called eglut, a GLUT-like library for EGL. It only works for X11, but it seems quite easy to use.

          Eglut location in the repository tree.

          Comment

          Working...
          X