【问题标题】:Why can't I create a headless OpenGl context with EGL?为什么我不能使用 EGL 创建无头 OpenGL 上下文?
【发布时间】:2019-04-06 10:51:18
【问题描述】:

我目前正在开发一个需要无头 opengl 上下文的程序。理想情况下,在 Linux 上无需 X 服务器即可运行。我的研究告诉我,EGL 是做到这一点的唯一方法(请告诉我是否有其他方法,因为我强烈更喜欢 C++ API 而不是像 EGL 这样的 C api)。查看 this 教程和 EGL 参考,我想出了这段代码,以最小和完整示例的形式:

#include <EGL/egl.h>
#include <glad/glad.h>
#include <iostream>
#include <exception>

class GlException : public std::exception{
public:
    GlException(const std::string &message) : m_message(message) {}
    const char *what() const noexcept override  { return m_message.c_str(); }
private:
    std::string m_message;
};

void createOpenGlContext() {
    constexpr EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
        EGL_NONE
    };

    constexpr EGLint pbufferAttribs[] = {
        EGL_WIDTH, 1600,
        EGL_HEIGHT, 900,
        EGL_NONE,
    };

    EGLDisplay m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    EGLBoolean result = eglInitialize(m_display, nullptr, nullptr);
    if(result != EGL_TRUE){
        switch(eglGetError()){
            case EGL_BAD_DISPLAY:
                throw GlException("Failed to initialize EGL Display: EGL_BAD_DISPLAY");
            case EGL_NOT_INITIALIZED:
                throw GlException("Failed to initialize EGL Display: EGL_NOT_INITIALIZED");
            default:
                throw GlException("Failed to initialize EGL Display: unknown error");
        }
    }

    EGLint numConfigs;
    EGLConfig eglConfig;
    result = eglChooseConfig(m_display, configAttribs, &eglConfig, 1, &numConfigs);
    if(result != EGL_TRUE){
        switch(eglGetError()){
            case EGL_BAD_DISPLAY:
                throw GlException("Failed to configure EGL Display: EGL_BAD_DISPLAY");
            case EGL_BAD_ATTRIBUTE:
                throw GlException("Failed to configure EGL Display: EGL_BAD_ATTRIBUTE");
            case EGL_NOT_INITIALIZED:
                throw GlException("Failed to configure EGL Display: EGL_NOT_INITIALIZED");
            case EGL_BAD_PARAMETER:
                throw GlException("Failed to configure EGL Display: EGL_BAD_PARAMETER");
            default:
                throw GlException("Failed to configure EGL Display: unknown error");
        }
    }

    EGLSurface surface = eglCreatePbufferSurface(m_display, eglConfig, pbufferAttribs);

    eglBindAPI(EGL_OPENGL_API);

    EGLContext context = eglCreateContext(m_display, eglConfig, EGL_NO_CONTEXT, nullptr);
}

int main(){
    createOpenGlContext();
    if(!gladLoadGL()){
        std::cerr << "Failed to load OpenGl function pointers" << std::endl;
        return -1;
    }
    return 0;
}

当我在该代码中调用 gladLoadGl 时,它会失败,这可以通过它的返回值来确定,这表明尚未创建上下文,尽管几乎完全使用了 Nvidia 博客中的代码(大概 Nvidia 知道它们是什么)用OpenGL做。)。我试图用我喜欢的搜索引擎找到其他有同样错误的人,但没有找到任何有用的东西。我的代码有什么问题?

我正在使用this高兴的配置。我正在使用 Arch Linux,完全更新。我有一个 Gtx 1070,带有来自 Nvidia 的最新驱动程序。当使用可用的 X 服务器运行时,上面的代码会失败。我没有在无头环境中测试过。

【问题讨论】:

标签: c++ linux opengl egl


【解决方案1】:

@G.M. 的建议奏效了,在现有 createOpenGlContext 函数解决问题之前添加对 eglMakeCurrent 的调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    相关资源
    最近更新 更多