Search code examples
c++openglegl

EGL crashes at first opengl function call


I am using nvidia 1060 gtx card on arch linux with newest drivers. But ELG does not work at all, actually it crashes at first call to an openglfunction eg glGenBuffers(). Everything works well when using GLFW for creating a context. But there is a need here to not depend on x-server presence.

The following code was compiled using : gcc testegl.cpp -lGLEW -lGL -lEGL_nvidia -lEGL -lstdc++ -o testegl

Output is:

  • Starting...
  • Segmentation fault (core dumped)

testegl.cpp:

#include <EGL/egl.h>
#include <GL/glew.h>
#include <exception>
#include <string>
#include <iostream>

class GLEGLContext {
private:
    EGLDisplay mDisplay;
    EGLSurface mSurface;
    EGLContext mContext;

public:
    GLEGLContext ();
    ~GLEGLContext ();
    GLEGLContext (const GLEGLContext& ) = delete;
    GLEGLContext& operator = (const GLEGLContext&) = delete;

public:
    virtual void makeCurrent ();
    virtual void releaseCurrent ();
};

GLEGLContext::GLEGLContext () {
    const EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_BLUE_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_DEPTH_SIZE, 0,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
        EGL_NONE
    };    

    const EGLint pbufferAttribs[] = {
        EGL_WIDTH, 1920,
        EGL_HEIGHT, 1080,
        EGL_NONE,
    };

    mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (mDisplay == EGL_NO_DISPLAY)
        throw StdException(__PRETTY_FUNCTION__, "eglGetDisplay() failed");

    EGLint major, minor;
    if (!eglInitialize(mDisplay, &major, &minor))
        throw StdException(__PRETTY_FUNCTION__, "eglInitialize() failed");

    EGLint numConfigs;
    EGLConfig eglCfg;
    if (!eglChooseConfig(mDisplay, configAttribs, &eglCfg, 1, &numConfigs))
        throw StdException(__PRETTY_FUNCTION__, "eglChooseConfig() failed");

    mSurface = eglCreatePbufferSurface(mDisplay, eglCfg, pbufferAttribs);
    if (mSurface == EGL_NO_SURFACE)
        throw StdException(__PRETTY_FUNCTION__, "eglCreatePbufferSurface() failed");

    if (!eglBindAPI(EGL_OPENGL_API))
        throw StdException(__PRETTY_FUNCTION__, "eglBindAPI() failed");

    mContext = eglCreateContext(mDisplay, eglCfg, EGL_NO_CONTEXT, NULL);
    if (mContext == EGL_NO_CONTEXT)
        throw StdException(__PRETTY_FUNCTION__, "eglCreateContext() failed");

    makeCurrent();
}

GLEGLContext::~GLEGLContext () {
    eglTerminate(mDisplay);
}

void GLEGLContext::makeCurrent () {
    if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext))
        throw StdException(__PRETTY_FUNCTION__, "eglMakeCurrent() create failed");
}

void GLEGLContext::releaseCurrent () {
    if (!eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
        throw StdException(__PRETTY_FUNCTION__, "eglMakeCurrent() release failed");
}

int main(int argc, char** argv) {
    GLEGLContext ctx;
    ctx.makeCurrent();
    std::cout << "Starting..." << std::endl;
    GLuint vertexBuffer = 0;
    glGenBuffers(1, &vertexBuffer);
    std::cout << "done" << std::endl;
    ctx.releaseCurrent();

    return 0;
}

Solution

  • You have to initialize GLEW. Call glewInit right after you created the OpenGL context:

    if ( glewInit() != GLEW_OK )
        return;
    

    Note, that glewInit returns GLEW_OK if succeeded. glewInit initializes the function pointers for the OpenGL functions. If you try to call function via an uninitialized function pointer, a segmentation fault occurs.

    see also the answer to Undefined reference when using glew and mingw?