0

Our Android app renders a beautiful image with Open GL. Now we want to make a desktop app widget reusing the same code base. We don't need real-time. A static picture is ok.

Unfortunately, it is impossible to render Open GL graphics directly to the widgets. Widget API is limited with Remote Views components.

But, if only we could render Open GL graphics to an off-screen buffer and then export it as an image. Then we could just create an ImageView and add the image to the widget.

I know, one can create an Open GL surface while having a View at hand. But in case of Android Widget there is no View. Is it the dead end?

Is there a way to create an offscreen Open GL surface without View? Can we render image with Open GL and display the result inside a widget on Android?

[UPDATE] Our app renders content entirely with GLES20 API. There IS a solution that works for old GL10 API - egl library. But it is not suitable for our project.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Pavel
  • 2,610
  • 3
  • 31
  • 50

1 Answers1

1

You may use egl to create Opengl context in nearly all situations.

Edit (putting a small c example egl + GLES2):

#include <stdio.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>

const EGLint attribs[] = { 
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_BLUE_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_RED_SIZE, 8,
                EGL_NONE
};

static const EGLint context_attribute_list[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,
    EGL_NONE
};

int main(int argc, char** argv) 
{
    EGLDisplay dpy;
    EGLContext ctx;
    EGLConfig config;
    EGLSurface surface;
    EGLint major, minor, n;
    ANativeWindow *window;
    GLint width, height;

    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    if (dpy == EGL_NO_DISPLAY) {
      fprintf(stderr, "eglGetDisplay() failed\n");
      return -1;    
    }

    eglInitialize(dpy, &major, &minor);
    printf("GL Version: %d.%d\n", major, minor);

    if (!eglChooseConfig(dpy, attribs, &config, 1, &n))
    {
      printf("eglChooseConfig failed\n");
      printf("Error code: %x\n", eglGetError());
    }

     /* create an EGL rendering context */
    ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, context_attribute_list);

    if (ctx == EGL_NO_CONTEXT) {
        printf("Error: eglCreateContext failed: %d\n", eglGetError());
        return -1;
    }

    window = android_createDisplaySurface();

    if (window == EGL_NO_SURFACE) {
        printf("Error: android_createDisplaySurface failed: %x\n", eglGetError());
        return -1;
    }

    surface = eglCreateWindowSurface(dpy, config, window, NULL);

    if (surface == EGL_NO_SURFACE) {
        printf("Error: eglCreateWindowSurface failed: %d\n", eglGetError());
        return -1;
    }

    if (!eglQuerySurface(dpy, surface, EGL_WIDTH, &width) ||
        !eglQuerySurface(dpy, surface, EGL_HEIGHT, &height)) {
        printf("Error: eglQuerySurface failed: %d\n", eglGetError());
        return -1;
    }

    printf("PBuffer: %dx%d\n", width, height);

    /* connect the context to the surface */
    if (!eglMakeCurrent(dpy, surface, surface, ctx)) {
        printf("Error: eglMakeCurrent() failed: %d\n", eglGetError());
        return -1;
    }

    glViewport(0, 0, width, height);
    /* clear the color buffer */
    glClearColor(1.0, 0.0, 0.0, 1.0);

    glClear(GL_COLOR_BUFFER_BIT);

    glFlush();

    eglSwapBuffers(dpy, surface);
    usleep(1000000);        

    return 0;
}

compiled with:

arm-linux-androideabi-gcc hello.c -o hello -lEGL -lGLESv2 -lui

On android

setEGLContextClientVersion(2);

seems to enable GLES20. (but i've not tested myself)

note: On linux, thru cairo api, I had offscreen rendering with FBO, (egl context)

Community
  • 1
  • 1
j-p
  • 1,622
  • 10
  • 18
  • Thanks! But, egl is only supportnig old GL10 API. Our app is programmed entirely with GLES20 API calls. Sorry, forgot to mention this. I wonder if there is a similar library that can render with GLES20? – Pavel Apr 16 '14 at 05:24
  • @Pavel: you may bind GLES2 api with [eglBindApi](https://www.khronos.org/registry/egl/sdk/docs/man/html/eglBindAPI.xhtml) (works well on linux) but I may be wrong under android... – j-p Apr 16 '14 at 05:31
  • @Pavel: [this maybe related](http://stackoverflow.com/questions/5926316/android-gles20-called-unimplemented-opengl-es-api) – j-p Apr 16 '14 at 05:36
  • @Pavel: my thought is that `egl` is THE magic layer of DRI and trying to find better, will move you far from the ascendant winds. – j-p Apr 16 '14 at 05:53