Как сделать автоматическую проверку ошибок OpenGL с помощью GLEW? - PullRequest
0 голосов
/ 23 февраля 2019

Недавно я пытался реализовать автоматическую проверку ошибок после каждого вызова функции OpenGL.Я подумал об обёртывании каждой функции OpenGL в вызывающей стороне следующим образом:

CheckForErrors(glCreateBuffers(1, &VBO));

Но я увидел, что GLEW уже использует свою собственную оболочку функции:

#define GLEW_GET_FUN(x) x

Поэтому я решил отредактировать её вместопишу свой собственный упаковщик функций:

    #ifndef GLEW_GET_FUN
    #ifdef DEBUG
        #define GLEW_GET_FUN(x) while (glGetError() != GL_NO_ERROR);\
                x; {\
                GLenum error = glGetError();\
                if (error != GL_NO_ERROR) {\
                    printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", #x, __FILE__, __LINE__);\
                    do printf(" %d", error); while (error = glGetError());\
                    printf("\n");\
                    __debugbreak();\
                }
    #else
        #define GLEW_GET_FUN(x) x
    #endif
    #endif

К сожалению, это не компилируется.Например, вызов этой функции:

GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);

Получает от препроцессора значение, измененное на это:

    GLuint vertexShaderID = while (glGetError() != GL_NO_ERROR); __glewCreateShader; { GLenum error = glGetError(); if (error != 0) { printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", "__glewCreateShader", "main.cpp", 51); do printf(" %d", error); while (error = glGetError()); printf("\n"); __debugbreak(); }(GL_VERTEX_SHADER);

Здесь есть 2 проблемы:

  1. Оператор начинаетсяс циклом while, поэтому он не может вернуть значение.
  2. Скобки с параметрами функции ставятся после всего, а не сразу после вызова функции.

Я незнаю, как преодолеть эти проблемы, и я буду признателен за помощь.

Примечания

  • Мне известна функция glDebugMessageCallback(), но она доступна только в OpenGL 4.3+, которая являетсядовольно новая и частично неподдерживаемая, но версия.
  • Я не могу удалить цикл while в начале, потому что мне нужно очистить все ошибки перед вызовом функции (если нет другого способа сделать это).
  • Я пытаюсь сделать что-то вроде this , но без использования отдельной функции-оболочки.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Как сказал Ник Болас, невозможно сделать это так, как я хотел, но я опишу, почему это так и что можно сделать вместо этого.

Проблема

GLEW оборачивает только имя функции с помощью GLEW_GET_FUN (), поэтому параметры функции всегда будут помещаться после конца определения, поскольку они не включены в него:

//In code:    
glGenBuffers(1, &VBO);
//After preprocessing:
{stuff generated by GLEW_GET_FUN}(1, &VBO);

Предварительная обработкане очень умный, поэтому он просто поставит параметры функции в конце.

Другие решения

  1. Как описано в вопросе, можно использовать glDebugMessageCallback(), если доступно.
  2. Оберните каждую функцию пользовательской оберткой.Совсем не автоматический, но если кому-то интересно, здесь - отличное руководство по его созданию.
0 голосов
/ 24 февраля 2019

Я не знаю, как преодолеть эти проблемы

Вы не можете.То, что вы хотите сделать, просто не жизнеспособно так, как вы хотите это сделать.Вы не можете превратить выражение (которое является вызовом функции) в оператор (или, скорее, в серию операторов), и заставить его работать везде.Он будет работать только в тех случаях, когда выражение используется в качестве оператора.

Если вы не хотите просто регулярно вставлять код проверки ошибок в свое приложение и не можете использовать современный API отладочных сообщений, тогда стандартныйРешение заключается в использовании внешнего инструмента для поиска и сообщения об ошибках.Например, RenderDoc может обнаруживать ошибки OpenGL.Он позволяет вам регистрировать каждый вызов OpenGL и может сообщать об ошибках в любое время, когда они происходят.

...