我们的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)