2024-08-12 21:40:28 -04:00
|
|
|
#include "DebugCallback.h"
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
void RegisterDebugCallback()
|
|
|
|
{
|
|
|
|
#if _DEBUG
|
|
|
|
if (glDebugMessageCallback)
|
|
|
|
{
|
|
|
|
std::cout << "Register OpenGL debug callback " << std::endl;
|
|
|
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
|
|
|
glDebugMessageCallback(openglCallbackFunction, nullptr);
|
|
|
|
GLuint unusedIds = 0;
|
|
|
|
glDebugMessageControl(GL_DONT_CARE,
|
|
|
|
GL_DONT_CARE,
|
|
|
|
GL_DONT_CARE,
|
|
|
|
0,
|
|
|
|
&unusedIds,
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cout << "glDebugMessageCallback not available" << std::endl;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
2024-08-12 21:55:08 -04:00
|
|
|
#include <windows.h>
|
2024-08-12 21:40:28 -04:00
|
|
|
/* Only run this code on WindowsAPI systems, otherwise use cout */
|
|
|
|
|
|
|
|
// C-based callback implementation
|
|
|
|
|
|
|
|
/* Reverse of SetConsoleTextAttribute */
|
|
|
|
WORD GetConsoleTextAttribute(HANDLE hConsoleOutput)
|
|
|
|
{
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
|
|
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
|
|
|
|
return csbi.wAttributes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Basic colors */
|
|
|
|
#define FMT_BLACK 0
|
|
|
|
#define FMT_BLUE FOREGROUND_BLUE|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_RED FOREGROUND_RED|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_MAROON FOREGROUND_RED
|
|
|
|
#define FMT_GREEN FOREGROUND_BLUE|FOREGROUND_INTENSITY
|
|
|
|
/* Combination colors */
|
|
|
|
#define FMT_MAGENTA FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_CYAN FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_YELLOW FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_GOLD FOREGROUND_RED|FOREGROUND_GREEN
|
|
|
|
#define FMT_WHITE FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY
|
|
|
|
#define FMT_GRAY FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE
|
|
|
|
|
|
|
|
/* Simplified windows API for color console printing */
|
|
|
|
#define WriteConsoleColorA(hConsoleOutput, lpBuffer, numberOfCharsToWrite, color) \
|
|
|
|
SetConsoleTextAttribute(hConsoleOutput, color), \
|
|
|
|
WriteConsoleA(hConsoleOutput, lpBuffer, numberOfCharsToWrite, NULL, NULL)
|
|
|
|
|
|
|
|
/* This macro makes it less verbose */
|
|
|
|
#define WriteConsoleNewlineA() WriteConsoleA(hStdOut, "\r\n", 2, NULL, NULL)
|
|
|
|
|
|
|
|
void APIENTRY openglCallbackFunction(GLenum source,
|
|
|
|
GLenum type,
|
|
|
|
GLuint id,
|
|
|
|
GLenum severity,
|
|
|
|
GLsizei length,
|
|
|
|
const GLchar* message,
|
|
|
|
const GLvoid* userParam)
|
|
|
|
{
|
|
|
|
if (id == 0x8dc) return;
|
|
|
|
|
|
|
|
static const char format[][58] = {
|
|
|
|
"---------------------OpenGL-callback-start------------\n",
|
|
|
|
"Message: ",
|
|
|
|
"Type: ",
|
|
|
|
"Id: ",
|
|
|
|
"Severity: ",
|
|
|
|
"---------------------OpenGL-callback-end--------------\n" };
|
|
|
|
static const char eTypes[][24] = { "ERROR", "DEPRECATED_BEHAVIOR",
|
|
|
|
"UNDEFINED_BEHAVIOR", "PORTABILITY", "PERFORMANCE", "OTHER" };
|
|
|
|
static const unsigned short eTypesC[] = { FMT_RED, FMT_GRAY,
|
|
|
|
FMT_MAROON, FMT_GOLD, FMT_GREEN, FMT_MAGENTA };
|
|
|
|
static const char eSeverities[][16] = { "HIGH",
|
|
|
|
"MEDIUM", "LOW", };
|
|
|
|
static const unsigned short eSeveritiesC[] = { FMT_RED,
|
|
|
|
FMT_GOLD, FMT_GREEN };
|
|
|
|
|
|
|
|
unsigned char eTypeIdx, eSeverityIdx;
|
|
|
|
HANDLE hStdOut;
|
|
|
|
WORD hStdOutAttr;
|
|
|
|
char buffer[8];
|
|
|
|
|
|
|
|
eTypeIdx = type - GL_DEBUG_TYPE_ERROR;
|
|
|
|
eSeverityIdx = severity - GL_DEBUG_SEVERITY_HIGH;
|
|
|
|
|
|
|
|
/* Do not close this handle with CloseHandle, it's process-wide */
|
|
|
|
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
/* Save previous colors/attributes to not distrub existing colors */
|
|
|
|
hStdOutAttr = GetConsoleTextAttribute(hStdOut);
|
|
|
|
|
|
|
|
WriteConsoleColorA(hStdOut, format[0], sizeof(*format), FMT_YELLOW);
|
|
|
|
|
|
|
|
/* Message: <String> */
|
|
|
|
WriteConsoleColorA(hStdOut, format[1], sizeof(*format), FMT_YELLOW);
|
|
|
|
WriteConsoleColorA(hStdOut, message, strlen(message), FMT_CYAN);
|
|
|
|
WriteConsoleNewlineA();
|
|
|
|
|
|
|
|
/* Type: <Enum> */
|
|
|
|
WriteConsoleColorA(hStdOut, format[2], sizeof(*format), FMT_YELLOW);
|
|
|
|
WriteConsoleColorA(hStdOut, eTypes[eTypeIdx],
|
|
|
|
sizeof(*eTypes), eTypesC[eTypeIdx]);
|
|
|
|
WriteConsoleNewlineA();
|
|
|
|
|
|
|
|
/* Id: <Hexadecimal Int> */
|
|
|
|
WriteConsoleColorA(hStdOut, format[3], sizeof(*format), FMT_YELLOW);
|
|
|
|
buffer[0] = '0', buffer[1] = 'x';
|
|
|
|
itoa(id, buffer + 2, 16);
|
|
|
|
WriteConsoleColorA(hStdOut, buffer, strlen(buffer), FMT_CYAN);
|
|
|
|
WriteConsoleNewlineA();
|
|
|
|
|
|
|
|
/* Severity: <Enum>*/
|
|
|
|
WriteConsoleColorA(hStdOut, format[4], sizeof(*format), FMT_YELLOW);
|
|
|
|
if (eSeverityIdx < sizeof(eSeverities)/sizeof(eSeverities[0])) {
|
|
|
|
WriteConsoleColorA(hStdOut, eSeverities[eSeverityIdx],
|
|
|
|
sizeof(*eSeverities), eSeveritiesC[eSeverityIdx]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
WriteConsoleColorA(hStdOut, "N/A", 3, FMT_MAGENTA);
|
|
|
|
}
|
|
|
|
WriteConsoleNewlineA();
|
|
|
|
|
|
|
|
WriteConsoleColorA(hStdOut, format[5], sizeof(*format), FMT_YELLOW);
|
|
|
|
|
|
|
|
/* Restore previous colors so other functions can continue printing */
|
|
|
|
SetConsoleTextAttribute(hStdOut, hStdOutAttr);
|
|
|
|
|
|
|
|
if(severity == GL_DEBUG_SEVERITY_HIGH ||
|
|
|
|
type == GL_DEBUG_TYPE_ERROR)
|
|
|
|
{
|
|
|
|
static bool previous_break = false;
|
|
|
|
if (previous_break == false)
|
|
|
|
{
|
|
|
|
DebugBreak(); //Check text console for error messages
|
|
|
|
previous_break = true; //This allows execution to continue after the break. Breaks won't happen for subsequent errors
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef WriteConsoleColorA
|
|
|
|
#undef WriteConsoleNewlineA
|
|
|
|
|
|
|
|
#else /* WIN32 */
|
|
|
|
|
|
|
|
void APIENTRY openglCallbackFunction(GLenum source,
|
|
|
|
GLenum type,
|
|
|
|
GLuint id,
|
|
|
|
GLenum severity,
|
|
|
|
GLsizei length,
|
|
|
|
const GLchar* message,
|
|
|
|
GLvoid* userParam)
|
|
|
|
{
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
cout << "---------------------opengl-callback-start------------" << endl;
|
|
|
|
cout << "message: " << message << endl;
|
|
|
|
cout << "type: ";
|
|
|
|
switch (type) {
|
|
|
|
case GL_DEBUG_TYPE_ERROR:
|
|
|
|
cout << "ERROR";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
|
|
|
|
cout << "DEPRECATED_BEHAVIOR";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
|
|
|
|
cout << "UNDEFINED_BEHAVIOR";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_TYPE_PORTABILITY:
|
|
|
|
cout << "PORTABILITY";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_TYPE_PERFORMANCE:
|
|
|
|
cout << "PERFORMANCE";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_TYPE_OTHER:
|
|
|
|
cout << "OTHER";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cout << endl;
|
|
|
|
|
|
|
|
cout << "id: " << id << endl;
|
|
|
|
cout << "severity: ";
|
|
|
|
switch (severity) {
|
|
|
|
case GL_DEBUG_SEVERITY_LOW:
|
|
|
|
cout << "LOW";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_SEVERITY_MEDIUM:
|
|
|
|
cout << "MEDIUM";
|
|
|
|
break;
|
|
|
|
case GL_DEBUG_SEVERITY_HIGH:
|
|
|
|
cout << "HIGH";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cout << endl;
|
|
|
|
cout << "---------------------opengl-callback-end--------------" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WIN32 */
|