/* =========================================================================== Copyright (C) 2019 Gian 'myT' Schellenbaum This file is part of Challenge Quake 3 (CNQ3). Challenge Quake 3 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Challenge Quake 3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Challenge Quake 3. If not, see . =========================================================================== */ // shared OpenGL client code for printing debug context output #include "client.h" #include "../renderer/tr_local.h" #if defined(_WIN32) && defined(_DEBUG) #include #endif #include "GL/glew.h" static const char* GL_DebugSourceString( GLenum source ) { switch (source) { case GL_DEBUG_SOURCE_API: return "API"; case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "window system"; case GL_DEBUG_SOURCE_SHADER_COMPILER: return "shader compiler"; case GL_DEBUG_SOURCE_THIRD_PARTY: return "third-party"; case GL_DEBUG_SOURCE_APPLICATION: return "application"; case GL_DEBUG_SOURCE_OTHER: return "other"; default: return "?"; } } static const char* GL_DebugTypeString( GLenum type ) { switch (type) { case GL_DEBUG_TYPE_ERROR: return "^1error"; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "^1deprecated behavior"; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "^1undefined behavior"; case GL_DEBUG_TYPE_PORTABILITY: return "portability"; case GL_DEBUG_TYPE_PERFORMANCE: return "^3performance"; case GL_DEBUG_TYPE_MARKER: return "marker"; case GL_DEBUG_TYPE_PUSH_GROUP: return "push group"; case GL_DEBUG_TYPE_POP_GROUP: return "pop group"; case GL_DEBUG_TYPE_OTHER: return "other"; default: return "?"; } } static const char* GL_DebugSeverityString( GLenum severity ) { switch (severity) { case GL_DEBUG_SEVERITY_LOW: return "low-severity"; case GL_DEBUG_SEVERITY_MEDIUM: return "medium-severity"; case GL_DEBUG_SEVERITY_HIGH: return "^3high-severity"; case GL_DEBUG_SEVERITY_NOTIFICATION: return "notification"; default: return "?"; } } static void GLAPIENTRY GL_DebugCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam ) { const char* msg = va( "^5GL Debug: ^7%s^7/%s^7/%s^7: %s\n", GL_DebugSeverityString(severity), GL_DebugSourceString(source), GL_DebugTypeString(type), message); Com_Printf(msg); #if defined(_WIN32) && defined(_DEBUG) OutputDebugStringA(msg); #endif } qbool CL_GL_WantDebug() { #if defined(_DEBUG) return r_khr_debug->integer != 0; #else return r_khr_debug->integer == 1; #endif } void CL_GL_Init() { const qbool enableDebug = CL_GL_WantDebug() && (GLEW_KHR_debug || GLEW_VERSION_4_3); if (!enableDebug) return; glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); // bad performance but can get access to the call stack... glDebugMessageCallback(&GL_DebugCallback, NULL); ri.Printf(PRINT_ALL, "OpenGL debug output is now active\n"); }