【发布时间】: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 服务器运行时,上面的代码会失败。我没有在无头环境中测试过。
【问题讨论】:
-
不应该在某处拨打
eglMakeCurrent之类的电话吗?