2017-08-08 134 views
-1

我在這裏有一個catch-22。我無法調試我的C++ OpenGL程序,因爲激活調試消息會導致段錯誤。glDebugMessageCallback導致段錯誤

我有一個調試回調函數我註冊:

static void APIENTRY openglCallbackFunction(
    GLenum source, 
    GLenum type, 
    GLuint id, 
    GLenum severity, 
    GLsizei length, 
    const GLchar* message, 
    const void* userParam) { 
    (void)source; (void)type; (void)id; 
    (void)severity; (void)length; (void)userParam; 
    fprintf(stderr, "%s\n", message); 
    if (severity==GL_DEBUG_SEVERITY_HIGH) { 
    fprintf(stderr, "Aborting...\n"); 
    abort(); 
    } 
} 

我開始在下面的代碼的調試上下文:

this->window = glfwCreateWindow(this->winx, this->winy, "Cortex Stretcher", NULL, NULL); 
    if(this->window == NULL) { 
    fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); 
    glfwTerminate(); 
    return -1; 
    } 
    glfwMakeContextCurrent(this->window); 

    GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags); 
    if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) 
    { 
    cout << "Debug output enabled!" << endl; 
    glEnable(GL_DEBUG_OUTPUT); 
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 
    glDebugMessageCallback(openglCallbackFunction, nullptr); 
    // glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); 
    } 

如果我只是註釋掉glDebugMessageCallback(openglCallbackFunction, nullptr);然後我的代碼運行沒有任何錯誤(除了我的模型渲染不正確,這就是爲什麼我要調試)。

但是,如果我嘗試註冊回調,那麼我的代碼segfaults(在註冊)。任何想法爲什麼?這基本上只是複製粘貼的代碼。

注:glGetString(GL_VERSION)回報4.5.0 NVIDIA 375.39

+2

'glDebugMessageCallback'僅在OpenGL> 4.3中可用。你的錯誤信息讓我認爲你使用的是OpenGL 3.3或2.1,它們都不支持。 – BDL

+0

情況並非如此。如果我打印出'glGetString(GL_VERSION);'我得到4.5.0 NVIDIA 375.39。我正在使用Titan X. –

回答

2

您正在使用什麼樣的GL加載機制?你的代碼確實創建了一個上下文並使其成爲當前的,但是你永遠不會加載任何GL函數指針。典型的gl.h標題將只包含GL功能,直到GL 1.1,這些也是唯一可以依靠OpenGL庫以平臺無關的方式導出的。事實上,你的編譯器(和鏈接器)不會抱怨glDebugMessageCallback表明你使用一些GL loader,比如glew,glad或者其他。這些通常是通過爲每個GL函數聲明一個函數指針來實現的,這些函數初始化爲NULL,並在調用某個初始化函數後加載。由於在嘗試設置調試回調之前您沒有這樣做,所以您只需調用NULL指針。

+1

啊,我的確在使用glew。我明白現在正在做什麼,但是當時我沒有發佈這個問題,而且你完全正確,我的調試設置在我初始化glew之前調用!謝謝! –