当前位置:  开发笔记 > 编程语言 > 正文

调试OpenGL的最佳方法是什么?

如何解决《调试OpenGL的最佳方法是什么?》经验,为你挑选了5个好方法。

我发现很多时候,OpenGL会通过不绘制任何东西来告诉你失败.我正试图通过检查转换矩阵堆栈等来找到调试OpenGL程序的方法.调试OpenGL的最佳方法是什么?如果代码外观和感觉顶点位于正确的位置,您如何确定它们是什么?



1> 小智..:

没有直接的答案.这一切都取决于你想要了解的内容.由于OpenGL是一个状态机,有时它不会按照您所期望的状态执行,因为未设置所需的状态或类似的东西.

通常,使用glTrace/glIntercept(查看OpenGL调用跟踪),gDebugger(可视化纹理,着色器,OGL状态等)和纸/铅笔等工具.有时它有助于理解你如何设置相机以及它在哪里看,被剪裁的内容等等.我个人更多地依赖于前两种方法.但是,当我认为深度是错误的时候,那么查看迹线会有所帮助.gDebugger也能有效的分析和你的OpenGL应用程序的优化使用唯一工具.

除了这个工具,大部分时间都是数学,人们出错了,用任何工具都无法理解.在OpenGL.org新闻组上发布代码特定评论,您将永远不会失望.



2> David Segond..:

GLIntercept是您最好的选择.从他们的网页:

使用选项记录单个帧,将所有OpenGL函数调用保存为文本或XML格式.

免费相机.绕过发送到图形卡的几何体并启用/禁用线框/背面剔除/视锥体渲染

保存并跟踪显示列表.在渲染调用之前和之后保存OpenGL帧缓冲区(颜色/深度/模板).还可以保存前后图像的"差异".



3> Foxor..:

Apitrace是Valve的一些相对较新的工具,但效果很好!尝试一下:https://github.com/apitrace/apitrace



4> Vallentin..:

调试OpenGL的最佳方法是什么?

不考虑额外的和外部的工具(其他答案已经做了).

那么一般的方法就是广泛打电话glGetError().但是,更好的选择是使用调试输出(KHR_debug,ARB_debug_output).这为您提供了为不同严重性级别的消息设置回调的功能.

要使用调试输出,必须使用WGL/GLX_DEBUG_CONTEXT_BIT标志创建上下文.使用GLFW,可以使用GLFW_OPENGL_DEBUG_CONTEXT窗口提示进行设置.

glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

请注意,如果上下文不是调试上下文,则无法保证接收所有或甚至任何消息.

是否有调试上下文可以通过检查来检测GL_CONTEXT_FLAGS:

GLint flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);

if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
    // It's a debug context

然后,您将继续并指定回调:

void debugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
                  const GLchar *message, const void *userParam)
{
    // Print, log, whatever based on the enums and message
}

可在此处查看枚举的每个可能值.特别记得检查严重性,因为某些消息可能只是通知而不是错误.

您现在可以提前并注册回调.

glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(debugMessage, NULL);

glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);

您甚至可以使用注入自己的消息glDebugMessageInsert().

glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0,
                     GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Vary dangerous error");

当涉及着色器和程序时,你总是想要检查GL_COMPILE_STATUS,GL_LINK_STATUSGL_VALIDATE_STATUS.如果他们中的任何一个反映出有问题,那么另外总是检查glGetShaderInfoLog()/ glGetProgramInfoLog().

GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);

if (!linkStatus)
{
    GLchar *infoLog = new GLchar[infoLogLength + 1];
    glGetProgramInfoLog(program, infoLogLength * sizeof(GLchar), NULL, infoLog); 

    ...

    delete[] infoLog;
}

返回的字符串glGetProgramInfoLog()将以null结尾.


您还可以更加极端,并在调试版本中使用一些调试宏.因此,使用glIs*()函数来检查期望的类型是否也是实际类型.

assert(glIsProgram(program) == GL_TRUE);
glUseProgram(program);

如果调试输出不可用而您只是想使用glGetError(),那么您当然可以自由地使用.

GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
    printf("OpenGL Error: %u\n", err);

由于数字错误代码没有用,我们可以通过将数字错误代码映射到消息来使其更具人性化.

const char* glGetErrorString(GLenum error)
{
    switch (error)
    {
    case GL_NO_ERROR:          return "No Error";
    case GL_INVALID_ENUM:      return "Invalid Enum";
    case GL_INVALID_VALUE:     return "Invalid Value";
    case GL_INVALID_OPERATION: return "Invalid Operation";
    case GL_INVALID_FRAMEBUFFER_OPERATION: return "Invalid Framebuffer Operation";
    case GL_OUT_OF_MEMORY:     return "Out of Memory";
    case GL_STACK_UNDERFLOW:   return "Stack Underflow";
    case GL_STACK_OVERFLOW:    return "Stack Overflow";
    case GL_CONTEXT_LOST:      return "Context Lost";
    default:                   return "Unknown Error";
    }
}

然后像这样检查:

printf("OpenGL Error: [%u] %s\n", err, glGetErrorString(err));

这仍然不是很有帮助或更好直观,好像你已经glGetError()在这里和那里撒了几个.然后找出哪一个记录错误可能很麻烦.

再次宏来救援.

void _glCheckErrors(const char *filename, int line)
{
    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR)
        printf("OpenGL Error: %s (%d) [%u] %s\n", filename, line, err, glGetErrorString(err));
}

现在只需定义一个这样的宏:

#define glCheckErrors() _glCheckErrors(__FILE__, __LINE__)

现在你可以glCheckErrors()在你想要的一切之后打电话,如果有错误,它会告诉你确切的文件和检测到的行.



5> Frank Cheng..:

我发现你可以glGetError在每行代码后检查你怀疑是不对的,但是在这之后,代码看起来不是很干净但它有效.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有