Enable OpenGL’s debug output when the LOVE_GRAPHICS_DEBUG environment variable is ‘1’. Resolves issue #607.

This commit is contained in:
Alex Szpakowski
2014-01-27 23:30:16 -04:00
parent a2a8b14cfd
commit d70023e350
5 changed files with 157 additions and 0 deletions
+64
View File
@@ -210,6 +210,18 @@ bool Graphics::setMode(int width, int height)
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &matrixLimit);
matrixLimit -= 5;
bool enabledebug = false;
if (GLEE_VERSION_3_0)
{
// Enable OpenGL's debug output if a debug context has been created.
GLint flags = 0;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
enabledebug = (flags & GL_CONTEXT_FLAG_DEBUG_BIT) != 0;
}
setDebug(enabledebug);
return true;
}
@@ -226,6 +238,58 @@ void Graphics::unSetMode()
gl.deInitContext();
}
static void APIENTRY debugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /*len*/, const GLchar *msg, GLvoid* /*usr*/)
{
// Human-readable strings for the debug info.
const char *sourceStr = OpenGL::debugSourceString(source);
const char *typeStr = OpenGL::debugTypeString(type);
const char *severityStr = OpenGL::debugSeverityString(severity);
const char *fmt = "OpenGL: %s [source=%s, type=%s, severity=%s, id=%d]\n";
printf(fmt, msg, sourceStr, typeStr, severityStr, id);
}
void Graphics::setDebug(bool enable)
{
// Make sure debug output is supported. The AMD ext. is a bit different
// so we don't make use of it, since AMD drivers now support KHR_debug.
if (!(GLEE_VERSION_4_3 || GLEE_KHR_debug || GLEE_ARB_debug_output))
return;
// Ugly hack to reduce code duplication.
if (GLEE_ARB_debug_output && !(GLEE_VERSION_4_3 || GLEE_KHR_debug))
{
glDebugMessageCallback = (GLEEPFNGLDEBUGMESSAGECALLBACKPROC) glDebugMessageCallbackARB;
glDebugMessageControl = (GLEEPFNGLDEBUGMESSAGECONTROLPROC) glDebugMessageControlARB;
}
if (!enable)
{
// Disable the debug callback function.
glDebugMessageCallback(nullptr, nullptr);
// We can disable debug output entirely with KHR_debug.
if (GLEE_VERSION_4_3 || GLEE_KHR_debug)
glDisable(GL_DEBUG_OUTPUT);
return;
}
// We don't want asynchronous debug output.
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(debugCB, nullptr);
// Initially, enable everything.
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
// Disable messages about deprecated OpenGL functionality.
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, GL_DONT_CARE, 0, 0, GL_FALSE);
glDebugMessageControl(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, GL_DONT_CARE, 0, 0, GL_FALSE);
::printf("OpenGL debug output enabled (LOVE_GRAPHICS_DEBUG=1)");
}
void Graphics::reset()
{
DisplayState s;
+2
View File
@@ -115,6 +115,8 @@ public:
virtual bool setMode(int width, int height);
virtual void unSetMode();
void setDebug(bool enable);
/**
* Resets the current color, background color,
* line style, and so forth. (This will be called
+61
View File
@@ -601,6 +601,67 @@ OpenGL::Vendor OpenGL::getVendor() const
return vendor;
}
const char *OpenGL::debugSeverityString(GLenum severity)
{
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH:
return "high";
case GL_DEBUG_SEVERITY_MEDIUM:
return "medium";
case GL_DEBUG_SEVERITY_LOW:
return "low";
default:
break;
}
return "unknown";
}
const char *OpenGL::debugSourceString(GLenum source)
{
switch (source)
{
case GL_DEBUG_SOURCE_API:
return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
return "window";
case GL_DEBUG_SOURCE_SHADER_COMPILER:
return "shader";
case GL_DEBUG_SOURCE_THIRD_PARTY:
return "external";
case GL_DEBUG_SOURCE_APPLICATION:
return "LOVE";
case GL_DEBUG_SOURCE_OTHER:
return "other";
default:
break;
}
return "unknown";
}
const char *OpenGL::debugTypeString(GLenum type)
{
switch (type)
{
case GL_DEBUG_TYPE_ERROR:
return "error";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
return "deprecated behavior";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
return "undefined behavior";
case GL_DEBUG_TYPE_PERFORMANCE:
return "performance";
case GL_DEBUG_TYPE_PORTABILITY:
return "portability";
case GL_DEBUG_TYPE_OTHER:
return "other";
default:
break;
}
return "unknown";
}
// OpenGL class instance singleton.
OpenGL gl;
+5
View File
@@ -230,6 +230,11 @@ public:
**/
Vendor getVendor() const;
// Get human-readable strings for debug info.
static const char *debugSeverityString(GLenum severity);
static const char *debugSourceString(GLenum source);
static const char *debugTypeString(GLenum type);
private:
void initVendor();
+25
View File
@@ -250,6 +250,18 @@ bool Window::setContext(int fsaa, bool vsync)
context = SDL_GL_CreateContext(window);
}
if (!context)
{
int flags = 0;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &flags);
if (flags & SDL_GL_CONTEXT_DEBUG_FLAG)
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
context = SDL_GL_CreateContext(window);
}
}
if (!context)
{
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
@@ -291,6 +303,19 @@ void Window::setWindowGLAttributes(int fsaa) const
// FSAA.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
// Do we want a debug context?
const char *debugenv = SDL_GetHint("LOVE_GRAPHICS_DEBUG");
if (debugenv && *debugenv == '1')
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
}
else
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
}
}
void Window::updateSettings(const WindowSettings &newsettings)