开发者

OpenGL debug or verbose information to console

Is there some sort of debug mode that OpenGL can be run in where it outputs information to a console? I have an app the work fine on many machines, but it fails miserably on the one machine that really matters. I don't have direct开发者_开发技巧 access to that machine, so I am trying to figure out how it is failing. Currently I see no output in the console. Note that the application was originally a windows app without a console and I switched it to console via the project properties. Also if it matters some objects don't display and another is stuck and doesn't animate - which doesn't make any sense to me.


Not, not really. You would have to write a hook for OpenGL and record all calls it does (which is what tools like gDEBugger do) if you really want some verbose output, but that requires quite a bit of work (you can use something like GLIntercept for that.) From personal experience: The easiest will be probably to get access to the machine in question and run gDEBugger there ... or get an equivalent machine so you can reproduce the error with a graphics debugger attached.

Alternatively, you can try to use the ARB_debug_output extension which -- in theory -- should provide you with some more output. In practice, all you get is a glGetError call after each OpenGL API call, which might be good enough for your use case (i.e. you just do something which breaks the GL state.) In order to use the debug output extension, you must modify your application to create a debug context.


Here is an approach with C++/GLEW/GLFW and Visual Studio 2019 on Windows 10, just the relevant parts:

/** Necessary includes */

#include <map>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

/** Debug callback prototype */

void GLAPIENTRY GLDebugMessageCallback(GLenum Source,
    GLenum Type,
    GLuint Id,
    GLenum Severity,
    GLsizei Length,
    const GLchar* Message,
    const void* UserParam);

/** Create the window and set the OpenGL context */

int main(void)
{
    if (glfwInit() != GLFW_TRUE)
    {
        printf("Unable to initialize GLFW\n");
        return EXIT_FAILURE;
    }

    /** Set the OpenGL Debug Context hint */

    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    GLFWwindow* Window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);

    if (!Window)
    {
        glfwTerminate();
        printf("Unable to create a GLFW window\n");
        return EXIT_FAILURE;
    }

    glfwMakeContextCurrent(Window);

    if (glewInit() != GLEW_OK)
    {
        printf("Unable to initialize GLEW\n");
        return EXIT_FAILURE;
    }

    /** Check whether debug context is enabled and set the debug callback */

    GLint ContextFlags;
    glGetIntegerv(GL_CONTEXT_FLAGS, &ContextFlags);

    if (ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)
    {
        printf("OpenGL : Debug Context Is Enabled");

        glEnable(GL_DEBUG_OUTPUT);
        glDebugMessageCallback(GLDebugMessageCallback, 0);
    }

    while (!glfwWindowShouldClose(Window))
    {
        glfwPollEvents();

        // Edit here...

        glfwSwapBuffers(Window);
    }

    glfwDestroyWindow(Window);
    glfwTerminate();

    return EXIT_SUCCESS;
}

/** Debug callback definition */

void GLAPIENTRY GLDebugMessageCallback(GLenum Source,
    GLenum Type,
    GLuint Id,
    GLenum Severity,
    GLsizei Length,
    const GLchar* Message,
    const void* UserParam)
{
    static std::map<GLenum, const GLchar*> Sources =
    {
        {GL_DEBUG_SOURCE_API, "API"},
        {GL_DEBUG_SOURCE_WINDOW_SYSTEM, "WINDOW_SYSTEM"},
        {GL_DEBUG_SOURCE_SHADER_COMPILER, "SHADER_COMPILER"},
        {GL_DEBUG_SOURCE_THIRD_PARTY, "THIRD_PARTY"},
        {GL_DEBUG_SOURCE_APPLICATION, "APPLICATION"},
        {GL_DEBUG_SOURCE_OTHER, "OTHER"}
    };

    static std::map<GLenum, const GLchar*> Severities =
    {
        {GL_DEBUG_SEVERITY_HIGH, "HIGH"},
        {GL_DEBUG_SEVERITY_MEDIUM, "MEDIUM"},
        {GL_DEBUG_SEVERITY_LOW, "LOW"},
        {GL_DEBUG_SEVERITY_NOTIFICATION, "NOTIFICATION"}
    };

    static std::map<GLenum, const GLchar*> Types =
    {
        {GL_DEBUG_TYPE_ERROR, "ERROR"},
        {GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "DEPRECATED_BEHAVIOR"},
        {GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, "UNDEFINED_BEHAVIOR"},
        {GL_DEBUG_TYPE_PORTABILITY, "PORTABILITY"},
        {GL_DEBUG_TYPE_PERFORMANCE, "PERFORMANCE"},
        {GL_DEBUG_TYPE_MARKER, "MARKER"},
        {GL_DEBUG_TYPE_PUSH_GROUP, "PUSH_GROUP"},
        {GL_DEBUG_TYPE_POP_GROUP, "POP_GROUP"},
        {GL_DEBUG_TYPE_OTHER, "OTHER"}
    };

    printf("[OpenGL %s] - SEVERITY: %s, SOURCE: %s, ID: %d: %s\n", Types[Type], Severities[Severity], Sources[Source], Id, Message);
}

Sample output

[OpenGL ERROR] - SEVERITY: HIGH, SOURCE: API, ID: 1282: GL_INVALID_OPERATION error generated. Function glColor4fv is deprecated and not available in preview contexts.
[OpenGL ERROR] - SEVERITY: HIGH, SOURCE: API, ID: 1282: GL_INVALID_OPERATION error generated. Array object is not active.
[OpenGL OTHER] - SEVERITY: NOTIFICATION, SOURCE: API, ID: 131185: Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_DYNAMIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
[OpenGL OTHER] - SEVERITY: NOTIFICATION, SOURCE: API, ID: 131185: Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_DYNAMIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).

Tested with

OpenGL 4.6
GLSL 4.60 NVIDIA
Renderer: GeForce RTX 2070 with Max-Q Design/PCIe/SSE2
Vendor: NVIDIA Corporation

Printing to the Visual Studio Output window

#include <windows.h> // For OutputDebugStringA 

Replace the printf at the end of the debug callback definition by the following:

char ErrorString[512];
sprintf_s(ErrorString, "[OpenGL %s] - SEVERITY: %s, SOURCE: %s, ID: %d: %s\n", Types[Type], Severities[Severity], Sources[Source], Id, Message);
OutputDebugStringA(ErrorString);

Notice about the Debug Context

In a nutshell, when OpenGL context is created in debug context mode, additional layers are activated in the path between the application, the drivers and to the GPU. These additional layers perform error checking, parameter analysis, and so on, and report it back as well formed messages via the debug message callback.

Enabling the OpenGL Debug Context is platform specific so GLFW is helpful in this sense as it provides a way to configure the OpenGL context via glfwWindowHint, which should be configured before creating the GLFW window.

From the OpenGL Wiki - Enabling Debug Output:

Unless debug output is enabled, no messages will be generated, retrieved, or logged. It is enabled by using glEnable with the GL_DEBUG_OUTPUT enumerator.

In Debug Contexts, debug output starts enabled. In non-debug contexts, the OpenGL implementation may not generate messages even if debug output is enabled.

I verified that on Windows 10, some output is in fact generated just by enabling debug output and setting the callback, without a debug context active.

Details on the glDebugMessageCallback found at docs.GL and OpenGL Wiki and the OpenGL Superbible 7th ed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜