Главная Статьи Ссылки Скачать Скриншоты Юмор Почитать Tools Проекты Обо мне Гостевая Форум |
Традиционным для OpenGL способом получения информации об ошибках является функция glGetError. В идеальном случае после каждого вызова какой-либо команды OpenGL следует вызвать glGetError, чтобы узнать не возникла ли какая-нибудь ошибка.
Вошедшее в состав OpenGL 4.1 расширение ARB_debug_output предлагает новые способы получения информации об ошибках. Основным из них является регистрация callback-функции, которая будет вызываться каждый раз когда возникает какая-либо ошибка.
Следующий листинг приводит пример такой callback-функции, просто выводящей на печать всю переданную ей информацию.
void CALLBACK errorCallback ( GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length, const GLchar * message, GLvoid * userParam )
{
printf ( "-----------------------------------------------------------------------------------\n" );
printf ( "Error:\n\tSource: %s\n\tType: %s\n\tId: %d\n\tSeverity: %s\n\tMessage: %s\n",
stringForSource ( source ), stringForType ( type ), id, stringForSeverity ( severity ), message );
}
Обратите внимание, что обычно такая возможность поддерживается только для debug-контекстов. Допустимые значения для параметров source, type и severity перечислены в таблицах 1-3.
Таблица 1. Допустимые значения параметра source.
Константа | Комментарий |
---|---|
GL_DEBUG_SOURCE_API_ARB | OpenGL |
GL_DEBUG_SOURCE_SHADER_COMPILER_ARB | Компилятор GLSL |
GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB | Оконная система (WGL или GLX) |
GL_DEBUG_SOURCE_THIRD_PARTY_ARB | Внешние отладчики или библиотеки |
GL_DEBUG_SOURCE_APPLICATION_ARB | Само приложение |
GL_DEBUG_SOURCE_OTHER_ARB | Источник не относящийся ни к одной из вышеприведенных категорий |
Таблица 2. Допустимые значения параметра type.
Константа | Комментарий |
---|---|
GL_DEBUG_TYPE_ERROR_ARB | Ошибка |
GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB | Устаревшее поведение |
GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB | Поведение, неопределенное по стандарту |
GL_DEBUG_TYPE_PERFORMANCE_ARB | Предупреждения о производительности |
GL_DEBUG_TYPE_PORTABILITY_ARB | Использование расширений или шейдеров привязанное к определенному производителю |
GL_DEBUG_TYPE_OTHER_ARB | Тип не относящийся ни к одной из вышеприведенных категорий |
Таблица 3. Допустимые значения параметра severity.
Константа | Комментарий |
---|---|
GL_DEBUG_SEVERITY_HIGH_ARB | Любая ошибка OpenGL, опасное неопределенное поведение, ошибка компиляции или линковки шейдеров |
GL_ DEBUG_SEVERITY_MEDIUM_ARB | Важные предупреждения о производительности, ошибки компиляции и линковки шейдеров, использование deprecated функционала |
GL_DEBUG_SEVERITY_LOW_ARB | Сообщения о производительности из-за избыточных переключений состояния, неопределенное поведение |
Для установки заданной функции в качестве callback'а служит команда glDebugMessageCallbackARB. Ниже приводится фрагмент кода, регистрирующий callback и осуществляющий вызов нескольких команд OpenGL, в результате чего возникают ошибки.
glDebugMessageCallbackARB ( errorCallback, NULL );
glPolygonMode ( GL_FRONT, GL_BACK ); // Error: not supported in core profile
glBindTexture ( 0, 0 ); // Error: illegal enum
glEnable ( -1 ); // Error: invalid enum
// insert custom message
glDebugMessageInsertARB ( GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_ERROR_ARB, 1,
GL_DEBUG_SEVERITY_HIGH_ARB, -1, "Custom message" );
Обратите внимание, что внутри самого callback'а нельзя вызывать ни команды OpenGL ни функции оконной системы - это может привести к непредсказуемым последствиям и падению программы.
Вызов callback-функции может происходить как в синхронном так и в асинхронном режиме. В случае синхронного режима callback вызывается до окончания работы той команды, которая и вызвала данную ошибку. В асинхронном случае драйвер сам решает когда ему вызвать callback. Для включения синхронного режима служит следующая команда:
glEnable ( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB );
Помимо callback'а существует и второй способ получения информации об ошибках - в этом случае вся информация об ошибках записывается во внутренний буфер, представляющий из себя очередь ограниченного размера.
При помощи команды glGetDebugMessageLogARB одно или несколько сообщений извлекаются из этой очереди и передаются приложению. Ниже приводится пример функции, печатающей (и удаляющей из лога) имеющиеся в нем сообщения.
GLuint glGetDebugMessageLogARB ( GLuint count,
GLsizei bufSize,
GLenum * sources,
GLenum * types,
GLenum * ids,
GLenum * severities,
GLsizei * lengths,
GLchar * messageLog );
Также существует команда, позволяющая добавлять пользовательские сообщение в лог (или вызывать для них callback).
void glDebugMessageInsertARB ( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLint length,
const GLchar * buf );
Обратите внимание, что при вызове данной команды параметр source может принимать только следующие два значения - GL_DEBUG_SOURCE_APPLICATION_ARB и GL_DEBUG_SOURCE_THIRD_PARTY_ARB.
Также данное расширение предоставляет возможность при помощи команды glDebugMessageControlARB управлять тем о каких ошибках нужно сообщать и о каких - не нужно.
void glDebugMessageControlARB ( GLenum source,
GLenum type,
GLenum severity,
GLsizei count,
const GLuint * ids,
GLboolean enabled );
Если параметр enabled равен GL_TRUE, то остальные параметры задают фильтр для выдачи информации о заданном типе ошибки. В противном случае (GL_FALSE) они задают ошибки которые нужно игнорировать. Параметры source, type и severity задают условия на соответствующие параметры ошибки. Также они могут принимать значение GL_DONT_CARE, говорящее о том, что любое значение соответствующего параметра удовлетворяет условиям.
Также можно задать набор идентификаторов ошибки при помощи параметров count и ids. Обратите внимание что поскольку ошибка уникально идентифицируется параметрами type, source и ID, то при явном задании идентификаторов параметр severity должен быть равен GL_DONT_CARE и параметры type и source не должны одновременно равняться GL_DONT_CARE.
По этой ссылке можно скачать весь исходный код к этой статье. Также доступны для скачивания откомпилированные версии для M$ Windows и Linux.