Egl像素图表面不起作用

时间:2017-09-06 23:15:43

标签: opengl xlib egl

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

我使用OpenGL用蓝色清洁背景。这就是我得到的东西:

Trash

以下是演示问题的最小示例(绘制此垃圾)。

更新:我添加了错误检查,并发现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");
    }
}

1 个答案:

答案 0 :(得分:0)

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

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

所以我不接受这个作为答案,因为设置OpenGL作为渲染API的实际原因打破了代码仍然是未知的。