我们的Android应用程序使用Open GL渲染出漂亮的图像。 现在我们想要重新使用相同代码库的桌面应用小部件。 我们不需要实时。 静态图片没问题。
不幸的是,不可能将Open GL图形直接呈现给小部件。 Widget API受限于远程视图组件。
但是,如果我们只能将Open GL图形渲染到屏幕外缓冲区,然后将其导出为图像。然后我们可以创建一个ImageView并将图像添加到小部件。
我知道,可以创建一个Open GL曲面,同时拥有一个View。 但是在Android Widget的情况下没有View。 这是死路一条吗?
有没有办法在没有View的情况下创建一个屏幕外的Open GL曲面? 我们可以使用Open GL渲染图像并在Android上的小部件中显示结果吗?
[UPDATE] 我们的应用程序完全使用GLES20 API呈现内容。 有一个解决方案适用于旧的GL10 API - egl库。但它不适合我们的项目。
答案 0 :(得分:1)
您几乎可以在所有情况下使用egl创建Opengl上下文。
编辑(放一个小例子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;
}
编译:
arm-linux-androideabi-gcc hello.c -o hello -lEGL -lGLESv2 -lui
在Android上
setEGLContextClientVersion(2);
seems启用GLES20。 (但我没有自己测试过)
注意:在linux上,通过cairo api,我用FBO进行了屏幕外渲染,(egl context)