Egl pixmap表面不起作用

问题描述:

我使用EGL与Xlib和OpenGL。当我直接在窗户上画画时,一切都很好。现在我试图使用pixmaps作为EGL表面,但OpenGL根本不会改变它。Egl pixmap表面不起作用

我用OpenGL的蓝色清理背景。下面是我得到的,而不是:

Trash

这里的小例子,demonstaiting问题(绘图本垃圾)。

更新:我添加了错误检查,并找出eglCopyBuffers产生EGL_BAD_NATIVE_PIXMAPDocs告诉这可能发生在两种情况下:如果实现不支持本地pixmaps或本地pixmap参数无效。他们似乎不太可能。如果我可以创建没有错误的pixmap表面,我相信实现支持本地pixmaps。如果我可以使用像XFillRectangle这样的本地方法来绘制像素图,我相信pixmap是有效的。

更新:我使用Ubuntu GNOME在笔记本电脑上运行此操作。它有两个显卡:Intel HD Graphics 5500(driver = i915)和Nvidia GeForce 920m(driver = nvidia)。从es2_info输出主线(full version):

EGL_VERSION: 1.4 
EGL_VENDOR: NVIDIA 
EGL_CLIENT_APIS: OpenGL_ES OpenGL 
GL_VERSION: OpenGL ES 3.2 NVIDIA 375.66 
GL_RENDERER: GeForce 920M/PCIe/SSE2 

代码:

// main.c 
// cc main.c -lX11 -lEGL -lGL 
#include <stdio.h> 
#include <stdarg.h> 
#include <stdlib.h> 
#include <GL/gl.h> 
#include <EGL/egl.h> 
#include <X11/Xlib.h> 

void 
die(const char * errstr, ...) { 
    va_list ap; 
    va_start(ap, errstr); 
    vfprintf(stderr, errstr, ap); 
    va_end(ap); 
    exit(1); 
} 

int main() { 
    Display * display = XOpenDisplay(NULL); 
    if (!display) die("Can't create xlib display.\n"); 
    int screen = XDefaultScreen(display); 
    GC gc = XDefaultGC(display, screen); 
    Window root_window = XRootWindow(display, screen); 
    unsigned long black_pixel = XBlackPixel(display, screen); 
    unsigned long white_pixel = XWhitePixel(display, screen); 
    Window window = XCreateSimpleWindow(display, root_window, 0, 0, 640, 480, 
     0, black_pixel, white_pixel); 
    if (!window) die("Can't create window.\n"); 
    int res = XSelectInput(display, window, ExposureMask); 
    if (!res) die("XSelectInput failed.\n"); 
    Pixmap pixmap = XCreatePixmap(display, window, 400, 400, 24); 
    if (!pixmap) die("Can't create pixmap.\n"); 
    EGLDisplay egldisplay = eglGetDisplay(display); 
    if (EGL_NO_DISPLAY == egldisplay) die("Can't cate egl display.\n"); 
    res = eglInitialize(egldisplay, NULL, NULL); 
    if (!res) die("eglInitialize failed.\n"); 
    EGLConfig config; 
    int num_configs; 
    static int attrib_list[] = { 
     EGL_RED_SIZE,   8, 
     EGL_GREEN_SIZE,   8, 
     EGL_BLUE_SIZE,   8, 
     EGL_ALPHA_SIZE,   0, 
     EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 
     EGL_SURFACE_TYPE,  EGL_PIXMAP_BIT, 
     EGL_NONE 
    }; 
    res = eglChooseConfig(egldisplay, attrib_list, &config, 1, &num_configs); 
    if (!res) die("eglChooseConfig failed.\n"); 
    if (0 == num_configs) die("No appropriate egl config found.\n"); 
    EGLSurface surface = 
     eglCreatePixmapSurface(egldisplay, config, pixmap, NULL); 
    if (EGL_NO_SURFACE == surface) die("Can't create egl pixmap surface.\n"); 
    res = eglBindAPI(EGL_OPENGL_API); 
    if (!res) die("eglBindApi failed.\n"); 
    EGLContext context = 
     eglCreateContext(egldisplay, config, EGL_NO_CONTEXT, NULL); 
    if (EGL_NO_CONTEXT == config) die("Can't create egl context.\n"); 
    res = eglMakeCurrent(egldisplay, surface, surface, context); 
    if (!res) die("eglMakeCurrent failed.\n"); 
    res = XMapWindow(display, window); 
    if (!res) die("XMapWindow failed.\n"); 
    while (1) { 
     XEvent event; 
     res = XNextEvent(display, &event); 
     if (Expose != event.type) continue; 
     glClearColor(0, 0, 1, 1); 
     glClear(GL_COLOR_BUFFER_BIT); 
     glFinish(); 
     res = eglWaitGL(); 
     if (!res) die("eglWaitGL failed.\n"); 
     res = XCopyArea(display, pixmap, window, gc, 0, 0, 400, 400, 0, 0); 
     if (!res) die("XCopyArea failed.\n"); 
    } 
} 
+0

您确认'eglCreatePixmapSurface()'没有返回'EGL_NO_SURFACE'吗? 'Cuz就是它在我的Debian Stable机器上返回的东西。 – genpfault

+0

根据[docs](https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreatePixmapSurface.xhtml),'attrib_list'属性对'eglCreatePixmapSurface()'无效。 – genpfault

+0

[This](https://github.com/i-rinat/freshplayerplugin/blob/master/tests/util_egl_pixmap.c)适用于我的系统。 – genpfault

原来eglBindApi(EGL_OPENGL_API)是问题的根源。当你删除一个你会得到预期的蓝色方形。

默认情况下,EGL使用OpenGL ES作为渲染API,并且它根本不适用于OpenGL渲染API。我找不到使用EGL和OpenGL渲染API的代码的单个示例,但我找到了this答案。这让我认为即使eglBindApi(EGL_OPENGL_API)没有返回EGL_BAD_PARAMETER,EGL也不应该与OpenGL一起工作,如果指定的客户端API不被EGL实现支持,则必须返回它,因为它必须返回docs

所以我不接受这个答案,因为为什么把OpenGL设置为渲染API会破坏代码的真实原因仍然未知。