opengl es-我们可以用Open GL GLES20 API渲染图像并在Android上的小部件中显示结果吗



我们的Android应用程序使用Open GL呈现美丽的图像。现在,我们想制作一个桌面应用程序小部件,重用相同的代码库。我们不需要实时。静态图片可以。

不幸的是,无法将Open GL图形直接呈现到窗口小部件。Widget API受远程视图组件的限制。

但是,如果我们能将Open GL图形渲染到屏幕外缓冲区,然后将其导出为图像就好了。然后我们可以创建一个ImageView并将图像添加到小部件中。

我知道,可以创建一个Open GL曲面,同时手头有一个View。但在Android Widget的情况下,没有View。这是死胡同吗?

有没有一种方法可以在没有View的情况下创建屏幕外Open GL曲面?我们可以用Open GL渲染图像并在Android上的小部件中显示结果吗?

[更新]我们的应用程序完全使用GLES20 API呈现内容。有一个解决方案适用于旧的GL10 API-egl库。但是它不适合我们的项目。

您可以在几乎所有情况下使用egl来创建Opengl上下文。

编辑(放一个小c例子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() failedn");
      return -1;    
    }
    eglInitialize(dpy, &major, &minor);
    printf("GL Version: %d.%dn", major, minor);
    if (!eglChooseConfig(dpy, attribs, &config, 1, &n))
    {
      printf("eglChooseConfig failedn");
      printf("Error code: %xn", 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: %dn", eglGetError());
        return -1;
    }
    window = android_createDisplaySurface();
    if (window == EGL_NO_SURFACE) {
        printf("Error: android_createDisplaySurface failed: %xn", eglGetError());
        return -1;
    }
    surface = eglCreateWindowSurface(dpy, config, window, NULL);
    if (surface == EGL_NO_SURFACE) {
        printf("Error: eglCreateWindowSurface failed: %dn", eglGetError());
        return -1;
    }
    if (!eglQuerySurface(dpy, surface, EGL_WIDTH, &width) ||
        !eglQuerySurface(dpy, surface, EGL_HEIGHT, &height)) {
        printf("Error: eglQuerySurface failed: %dn", eglGetError());
        return -1;
    }
    printf("PBuffer: %dx%dn", width, height);
    /* connect the context to the surface */
    if (!eglMakeCurrent(dpy, surface, surface, ctx)) {
        printf("Error: eglMakeCurrent() failed: %dn", 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;
}

编译使用:

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

安卓

setEGLContextClientVersion(2);

似乎启用了GLES20。(但我还没有测试过自己)

注意:在linux上,通过cairoapi,我使用FBO进行了屏幕外渲染,(egl-context)

最新更新