繁体   English   中英

为什么 egl 像素图表面适用于 opengl es 而不适用于 opengl?

[英]Why egl pixmap surface works with opengl es but not with opengl?

我将 EGL 与 Xlib 和 OpenGL 一起使用。 当我直接在窗户上画画时,一切都很好。 现在我试图使用像素图作为 EGL 表面,但 OpenGL 根本没有改变它。

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

垃圾

这是证明问题的最小示例(绘制这个垃圾)。

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

更新:我在带有 Ubuntu Gnome 的笔记本电脑上运行它。 它有两个显卡:Intel HD Graphics 5500(driver=i915) 和 Nvidia GeForce 920m(driver=nvidia)。 es2_info 输出的主线( 完整版):

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");
    }
}

结果eglBindApi(EGL_OPENGL_API)是问题的根源。 当您删除一个时,您会按预期获得蓝色方块。

默认情况下,EGL 使用 OpenGL ES 作为渲染 API,它根本不适用于 OpenGL 渲染 API。 我找不到将 EGL 与 OpenGL 渲染 API 一起使用的单个代码示例,但我找到了这个答案。 这让我认为 EGL 不应该与 OpenGL 一起使用,即使eglBindApi(EGL_OPENGL_API)不返回EGL_BAD_PARAMETER必须根据文档返回“如果 EGL 实现不支持指定的客户端 API”。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM