Programing

OpenGL을 디버깅하는 가장 좋은 방법은 무엇입니까?

lottogame 2020. 12. 2. 07:44
반응형

OpenGL을 디버깅하는 가장 좋은 방법은 무엇입니까?


나는 많은 시간 동안 OpenGL은 아무것도 그리지 않아 실패한 것을 보여줄 것입니다. 변환 매트릭스 스택 등을 검사하여 OpenGL 프로그램을 디버깅하는 방법을 찾으려고합니다. OpenGL을 디버깅하는 가장 좋은 방법은 무엇입니까? 코드가 꼭지점이 올바른 위치에있는 것처럼 보이고 느껴진다면 어떻게 확인할 수 있습니까?


정답은 없습니다. 그것은 모두 당신이 이해하려는 것에 달려 있습니다. OpenGL은 상태 기계이기 때문에 필요한 상태가 설정되지 않았거나 이와 같은 일이 발생하여 예상 한대로 작동하지 않는 경우가 있습니다.

일반적으로 glTrace / glIntercept (OpenGL 호출 추적보기), gDebugger (텍스처, 셰이더, OGL 상태 등을 시각화하기 위해) 및 종이 / 연필과 같은 도구를 사용합니다. 때로는 카메라를 어떻게 설정했는지, 어디에 있는지, 무엇이 잘리는 지 등을 이해하는 데 도움이됩니다. 저는 개인적으로 이전의 두 가지 접근 방식보다 마지막에 더 많이 의존했습니다. 그러나 깊이가 잘못되었다고 주장 할 수있을 때 추적을 보는 것이 도움이됩니다. gDebugger는 OpenGL 앱의 프로파일 링 및 최적화에 효과적으로 사용할 수있는 유일한 도구 이기도 합니다 .

이 도구를 제외하고는 대부분의 경우 사람들이 잘못 이해하는 것은 수학이며 어떤 도구로도 이해할 수 없습니다. OpenGL.org 뉴스 그룹에 코드 별 의견을 게시하면 결코 실망하지 않을 것입니다.


GLIntercept 가 최선의 방법입니다. 웹 페이지에서 :

  • 개별 프레임을 기록하는 옵션을 사용하여 모든 OpenGL 함수 호출을 텍스트 또는 XML 형식으로 저장합니다.
  • 무료 카메라. 그래픽 카드로 전송 된 지오메트리 주변을 비행하고 와이어 프레임 / 백 페이스 컬링 / 뷰 프러스 텀 렌더를 활성화 / 비활성화합니다.
  • 디스플레이 목록을 저장하고 추적합니다. OpenGL 프레임 버퍼 (색상 / 깊이 / 스텐실) 사전 및 사후 렌더링 호출 저장. 사전 및 사후 이미지의 "차이"를 저장하는 기능도 사용할 수 있습니다.

Apitrace는 Valve의 일부 사용자로부터 비교적 새로운 도구이지만 훌륭하게 작동합니다! 시도해보세요 : https://github.com/apitrace/apitrace


나는 glGetError당신이 용의자가 틀릴 모든 코드 줄을 사용하여 확인할 수 있다는 것을 알았 습니다.하지만 그렇게 한 후에 코드는 깨끗하지 않지만 작동합니다.


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_STATUS하고 GL_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);

If debug output isn't available and you just want to use glGetError(), then you're of course free to do so.

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

Since a numeric error code isn't that helpful, we could make it a bit more human readable by mapping the numeric error codes to a message.

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";
    }
}

Then checking it like this:

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

That still isn't very helpful or better said intuitive, as if you have sprinkled a few glGetError() here and there. Then locating which one logged an error can be troublesome.

Again macros come to the rescue.

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));
}

Now simply define a macro like this:

#define glCheckErrors() _glCheckErrors(__FILE__, __LINE__)

and voila now you can call glCheckErrors() after everything you want, and in case of errors it will tell you the exact file and line it was detected at.


For those on Mac, the buit in OpenGL debugger is great as well. It lets you inspect buffers, states, and helps in finding performance issues.


The gDebugger is an excellent free tool, but no longer supported. However, AMD has picked up its development, and this debugger is now known as CodeXL. It is available both as a standalone application or as a Visual Studio plugin - works both for native C++ applications, or Java/Python applications using OpenGL bindings, both on NVidia and AMD GPUs. It's one hell of a tool.


There is also the free glslDevil: http://www.vis.uni-stuttgart.de/glsldevil/

It allows you to debug glsl shaders extensively. It also shows failed OpenGL calls.

However it's missing features to inspect textures and off screen buffers.


Nsight is good debugging tool if you have an NVidia card.


Updating the window title dynamically is convenient for me.

Example (use GLFW, C++11):

glfwSetWindowTitle(window, ("Now Time is " + to_string(glfwGetTime())).c_str());

참고URL : https://stackoverflow.com/questions/518063/what-is-the-best-way-to-debug-opengl

반응형