diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2a4145c98..015ff635c 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -365,6 +366,7 @@ void OMW::Engine::createWindow(Settings::Manager& settings) checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)); + checkSDLError(SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG)); if (antialiasing > 0) { @@ -425,6 +427,8 @@ void OMW::Engine::createWindow(Settings::Manager& settings) camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, width, height); + mViewer->setRealizeOperation(new EnableGLDebugOperation()); + mViewer->realize(); mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index d26a92d44..ec0e511ca 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -86,7 +86,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - constants utf8stream stringops resourcehelpers rng messageformatparser weakcache + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache gldebug ) add_component_dir (debug diff --git a/components/misc/gldebug.cpp b/components/misc/gldebug.cpp new file mode 100644 index 000000000..71d75fa73 --- /dev/null +++ b/components/misc/gldebug.cpp @@ -0,0 +1,60 @@ +#include "gldebug.hpp" + +#include + +// OpenGL constants not provided by OSG: +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_TYPE_ERROR 0x824C + +void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +{ + Log(Debug::Error) << message; +} + +void enableGLDebugExtension(unsigned int contextID) +{ + typedef void (GL_APIENTRY *DEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + typedef void (GL_APIENTRY *GLDebugMessageControlFunction)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); + typedef void (GL_APIENTRY *GLDebugMessageCallbackFunction)(DEBUGPROC, const void* userParam); + + GLDebugMessageControlFunction glDebugMessageControl = nullptr; + GLDebugMessageCallbackFunction glDebugMessageCallback = nullptr; + + if (osg::isGLExtensionSupported(contextID, "GL_KHR_debug")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallback"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControl"); + } + else if (osg::isGLExtensionSupported(contextID, "GL_ARB_debug_output")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallbackARB"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControlARB"); + } + else if (osg::isGLExtensionSupported(contextID, "GL_AMD_debug_output")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallbackAMD"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControlAMD"); + } + + if (glDebugMessageCallback && glDebugMessageControl) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, true); + glDebugMessageCallback(debugCallback, nullptr); + + Log(Debug::Info) << "OpenGL debug callback attached."; + } +} + +EnableGLDebugOperation::EnableGLDebugOperation() : osg::GraphicsOperation("EnableGLDebugOperation", false) +{ +} + +void EnableGLDebugOperation::operator()(osg::GraphicsContext* graphicsContext) +{ + OpenThreads::ScopedLock lock(mMutex); + + unsigned int contextID = graphicsContext->getState()->getContextID(); + enableGLDebugExtension(contextID); +} diff --git a/components/misc/gldebug.hpp b/components/misc/gldebug.hpp new file mode 100644 index 000000000..2401a53a4 --- /dev/null +++ b/components/misc/gldebug.hpp @@ -0,0 +1,16 @@ +#ifndef OPENMW_COMPONENTS_MISC_GLDEBUG_H +#define OPENMW_COMPONENTS_MISC_GLDEBUG_H + +#include + +class EnableGLDebugOperation : public osg::GraphicsOperation +{ +public: + EnableGLDebugOperation(); + + virtual void operator()(osg::GraphicsContext* graphicsContext); + +private: + OpenThreads::Mutex mMutex; +}; +#endif