Почему я не могу создать безголовый контекст OpenGl с EGL? - PullRequest
0 голосов
/ 02 ноября 2018

В настоящее время я работаю над программой, для которой мне нужен безголовый контекст opengl. В идеале в Linux можно будет работать без X-сервера. Мое исследование говорит мне, что EGL - единственный способ сделать это (пожалуйста, скажите, есть ли другой способ, так как я настоятельно предпочитаю C ++ API, а не C apis, как EGL). Глядя на этот учебник и справочник по 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.). Я попытался найти кого-то еще с той же ошибкой в ​​моем любимом поисковике, но ничего полезного не получилось. Что не так с моим кодом?

Я использую эту рад конфигурации. Я использую Arch Linux, полностью обновлен. У меня Gtx 1070 с последними драйверами от Nvidia. Приведенный выше код завершается ошибкой при запуске с доступным X-сервером. Я не проверял это в безголовой среде.

1 Ответ

0 голосов
/ 02 ноября 2018
Совет

@ G.M. сработал, добавив вызов eglMakeCurrent до того, как существующая функция createOpenGlContext решила проблему.

...