nigels-com / glew

The OpenGL Extension Wrangler Library
Other
2.66k stars 621 forks source link

glewInit() failed with OSMesa #419

Open Petingo opened 2 months ago

Petingo commented 2 months ago

Hello everyone,

I'm trying to set up a docker for CI using OSMesa on a headless machine, but I couldn't make it work. Currently, I'm testing on a regular machine running Ubuntu 20.04.

Despite I've already set up the OpenGL context with OSMesaMakeCurrent() and enabled glewExperimental = GL_TRUE, glewInit() fails with the error Missing GL version.

I'm using GLEW 2.2 compiled with

make SYSTEM=linux-osmesa

My OSMesa is installed using apt-get.

The code I'm testing:

#include <iostream>

// OpenGL headers
#include <GL/glew.h>

#define GLAPI
#include <GL/osmesa.h>
#undef GLAPI

OSMesaContext ctx;
GLubyte* glBuffer;
const int windowWidth{800}, windowHeight{600};

// main program
int main(int argc, char** argv, char** arge)
{
    // OSmesa initialization
    std::cout << "OSmesa major version: " << OSMESA_MAJOR_VERSION << std::endl;
    std::cout << "OSmesa minor version: " << OSMESA_MINOR_VERSION << std::endl;

    ctx = OSMesaCreateContext(OSMESA_RGBA, nullptr);

    if (!ctx) {
        std::cerr << "OSMesaCreateContext failed!" << std::endl;
        abort();
    }

    /* Allocate the image buffer */
    glBuffer = (GLubyte*)malloc(windowWidth * windowHeight * 4 * sizeof(GLubyte));
    if (!glBuffer) {
        std::cerr << "Alloc image buffer failed!" << std::endl;
        abort();
    }

    /* Bind the buffer to the context and make it current */
    if (OSMesaMakeCurrent(ctx, glBuffer, GL_UNSIGNED_BYTE, windowWidth, windowHeight) != GL_TRUE) {
        std::cerr << "OSMesaMakeCurrent failed!" << std::endl;
        abort();
    }

    // get general OpenGL infos
    std::cout << "---" << std::endl;
    std::cout << "GL Implementation Vendor: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "GL Renderer: " << glGetString(GL_RENDERER) << std::endl;
    std::cout << "GL Version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "Shading Laguage Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
    std::cout << "---" << std::endl;

    // GLEW initialization
    glewExperimental = GL_TRUE;
    const auto glewError = glewInit();
    if (glewError != GLEW_OK) {
        std::cerr << glewGetErrorString(glewError) << '\n';
        abort();
    }
}

The CMakeLists.txt for building it:

cmake_minimum_required(VERSION 3.22)
project(osmesa_test)

set(CMAKE_CXX_STANDARD 17)

find_package(OpenGL REQUIRED)
find_package(glfw3 3.4 REQUIRED)
find_package(GLEW REQUIRED)

add_executable(osmesa_test osmesa_test.cpp)
target_link_libraries(osmesa_test
        GLEW::GLEW
        OSMesa
        GL
        GLU
)

Running the above code will print:

OSmesa major version: 11
OSmesa minor version: 2
---
GL Implementation Vendor: Mesa/X.org
GL Renderer: llvmpipe (LLVM 12.0.0, 256 bits)
GL Version: 3.1 Mesa 21.2.6
Shading Laguage Version: 1.40
---
Missing GL version

I tried two machine and both output a similar result. I've attached both files in a zip, as well as the glewinfo output. One thing I noticed in the glewinfo output is that all GL_MESA_xxx is MISSING. Is this a problem? How do I approach this issue?

glewinfo.txt osmesa_test.zip

Petingo commented 2 months ago

After some try & error, I figured it out. Now the GLEW can initialize successfully. Here's what I did:

  1. Edit /etc/ld.so.conf and append another line include /usr/lib/x86_64-linux-gnu, where libOSMesa.so is installed to.
  2. Run ldconfig
  3. Instead of compiling GLEW using make SYSTEM=linux-osmesa, go to build/, run cmake ./cmake -DGLEW_OSMESA=Y, and run make install afterward. I've cross-validated and it seems that only the CMake version works, so I guess there might be some problem with the Makefile in the root folder.

I'll do some more tests and try to make it work in the following days.