2017-08-22 146 views
0

我在写游戏。大部分时间我都使用ArchLinux,但我最近试图在Ubuntu 16.04上运行我的游戏。在Ubuntu 16.04上有一个奇怪的错误:。找到导致错误的原因太困难了,所以我想看看opengl的调试输出,但我没有看到它。我注意到着色器验证过程中的一件事 - 验证似乎是不成功的,但日志为空:Opengl 4调试输出不起作用

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的调试输出。而且,如果可能的话,作为一个额外的问题,为什么在没有日志的情况下着色器验证失败?

+2

我想因为'glewInit()'会导致这个错误(因为它总是这样),并且在那之后注册调试输出。 – BDL

+0

这是我停止使用GLEW的原因之一。这些天我使用GLAD进行扩展争论,但显然必须创建我自己的OpenGL窗口。 – Robinson

+0

@BDL为什么你认为'glewInit()'会导致这个错误?而且我不能在'glewInit()'之前设置调试输出,因为它会因使用未初始化的函数指针而崩溃。 –

回答

1

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

这里有一个鸡蛋问题:在初始化GLEW之前,您不能设置调试回调,但这是您想从中获取调试输出的地方。我建议在glewInit之后立即拨打glGetError()以摆脱您知道来自哪里的一个错误。