Opengl 4调试输出不起作用

Posted

技术标签:

【中文标题】Opengl 4调试输出不起作用【英文标题】:Opengl 4 debug output does not work 【发布时间】:2017-08-22 11:05:14 【问题描述】:

我正在写一个游戏。我大部分时间都使用 ArchLinux,但最近我尝试在 Ubuntu 16.04 上运行我的游戏。在 Ubuntu 16.04 上有一个奇怪的错误:1280。很难找到导致错误的原因,所以我想查看 opengl 的调试输出,但我也没有看到。我在着色器验证期间注意到一件事 - 验证似乎不成功,但日志为空:

GLint status;
glValidateProgram(program_);
glGetProgramiv(program_, GL_VALIDATE_STATUS, &status);

if (status == GL_TRUE) 
    return;


// Store log and return false
int length = 0;

glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &length);

if (length > 0) 
    GLchar infoLog[512];
    glGetProgramInfoLog(program_, 512, nullptr, infoLog);

    throw std::runtime_error(std::string("Program failed to validate:") + infoLog);
 else 
    throw std::runtime_error(std::string("Program failed to validate. Unknown error"));

这给了我Unknown error。也看不到 opengl 的调试输出,但是,用户消息已成功写入那里。代码如下:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

int contextFlags = 0;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &contextFlags);
contextFlags |= SDL_GL_CONTEXT_DEBUG_FLAG;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, contextFlags);

sdlWindow_ = SDL_CreateWindow(title.c_str(),
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        0,
        0,
        SDL_WINDOW_OPENGL
        | SDL_WINDOW_SHOWN
        | SDL_WINDOW_FULLSCREEN_DESKTOP
        | SDL_WINDOW_INPUT_GRABBED);

if (!sdlWindow_) 
    throw std::runtime_error("Unable to create window");


SDL_Log("Window created");

glContext_ = SDL_GL_CreateContext(sdlWindow_);
if (!glContext_) 
    throw std::runtime_error("Failed to init OpenGL");

SDL_Log("GL context created");


    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (err != GLEW_OK) 
        throw std::runtime_error(std::string("GLEW Error: ") + reinterpret_cast<const char*>(glewGetErrorString(err)));
    


if (glDebugMessageCallbackARB != nullptr) 
    SDL_Log("GL debug is available.\n");
    // Enable the debug callback
    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
    glDebugMessageCallback(_openglDebugCallbackFunction, nullptr);
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
    glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
                         GL_DEBUG_SEVERITY_NOTIFICATION, -1 , "Started debugging");
 else 
    SDL_Log("GL debug is not available.\n");

所以这里的主要问题是为什么我看不到 opengl 的调试输出。而且,如果可能的话,作为一个附加问题,为什么着色器验证会在没有日志的情况下失败?

【问题讨论】:

我猜是因为glewInit() 导致了这个错误(因为它总是这样),然后你正在注册调试输出。 这是我停止使用 GLEW 的原因之一。这些天来,我使用 GLAD 进行扩展争吵,但显然必须创建自己的 OpenGL 窗口才能播放。 @BDL 为什么您认为glewInit() 会导致此错误?而且我无法在glewInit() 之前设置调试输出,因为它会因为使用未初始化的函数指针而崩溃。 @VictorPolevoy:因为在核心配置文件中使用 GLEW 1.x 时会损坏(不过,GLEW 2.x 可以工作)。你有没有想过为什么你甚至设置glewExperimental 因为glewInit() 在加载扩展程序时总是会产生错误(至少在 Windows 上是这样)。是的,你不能在初始化 glew 之前设置调试上下文。但既然你知道错误来自哪里,你可以简单地忽略它。 【参考方案1】:

GLEW 1.x 在核心上下文中使用时存在一些问题(这也是需要glewExperimental=true 的原因)。 glewInit 在加载扩展时总是会产生 OpenGL 错误。您不会通过调试回调收到此错误,因为回调的初始化发生在错误发生点之后。

您在这里遇到了一个先有鸡的问题:您无法在初始化 GLEW 之前设置调试回调,但这是您想要从中获取调试输出的地方。我建议在glewInit 之后立即调用glGetError() 以消除一个你知道它来自哪里的错误。

【讨论】:

以上是关于Opengl 4调试输出不起作用的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL First Cube渲染不起作用

OpenGL - 链接两个纹理不起作用

排毒--调试同步不起作用

OpenGL移动对象不起作用

vTextCoord 值不起作用 - c# OPENTK

为啥我的 OpenGL 纹理不起作用?