184 lines
7.3 KiB
C++
Executable File
184 lines
7.3 KiB
C++
Executable File
// =====================================================================================================================
|
|
// glw, an open-source library that wraps OpenGL structures into classes.
|
|
// Copyright (C) 2024 Medusa Slockbower
|
|
//
|
|
// This program 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 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
// =====================================================================================================================
|
|
|
|
#ifndef GLW_DEBUG_H
|
|
#define GLW_DEBUG_H
|
|
|
|
#include "common.h"
|
|
|
|
namespace glw::debug
|
|
{
|
|
|
|
/**
|
|
* \brief OpenGL error codes
|
|
*/
|
|
enum error
|
|
{
|
|
error_invalid_enum = GL_INVALID_ENUM
|
|
, error_invalid_value = GL_INVALID_VALUE
|
|
, error_invalid_operation = GL_INVALID_OPERATION
|
|
, error_stack_overflow = GL_STACK_OVERFLOW
|
|
, error_stack_underflow = GL_STACK_UNDERFLOW
|
|
, error_out_of_memory = GL_OUT_OF_MEMORY
|
|
, error_invalid_framebuffer_operation = GL_INVALID_FRAMEBUFFER_OPERATION
|
|
, error_context_lost = GL_CONTEXT_LOST
|
|
, error_table_too_large = GL_TABLE_TOO_LARGE
|
|
};
|
|
|
|
/**
|
|
* \brief Converts an error code into a string representation
|
|
* \param error The error code to translate
|
|
* \return C string containing the string representation
|
|
*/
|
|
inline const char_t* translate_error(enum_t error)
|
|
{
|
|
switch(error)
|
|
{
|
|
case error_invalid_enum: return GLW_STRINGIFY(error_invalid_enum);
|
|
case error_invalid_value: return GLW_STRINGIFY(error_invalid_value);
|
|
case error_invalid_operation: return GLW_STRINGIFY(error_invalid_operation);
|
|
case error_stack_overflow: return GLW_STRINGIFY(error_stack_overflow);
|
|
case error_stack_underflow: return GLW_STRINGIFY(error_stack_underflow);
|
|
case error_out_of_memory: return GLW_STRINGIFY(error_out_of_memory);
|
|
case error_invalid_framebuffer_operation: return GLW_STRINGIFY(error_invalid_framebuffer_operation);
|
|
case error_context_lost: return GLW_STRINGIFY(error_context_lost);
|
|
case error_table_too_large: return GLW_STRINGIFY(error_table_too_large);
|
|
default: return GLW_STRINGIFY(error_unknown);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Get the last error thrown by OpenGL, it is preferable to use the callback handler for performance
|
|
* \return Error code of the last error
|
|
*/
|
|
inline enum_t get_error() { return glGetError(); }
|
|
|
|
/**
|
|
* \brief Source ids of a debug message
|
|
*/
|
|
enum debug_source
|
|
{
|
|
source_api = GL_DEBUG_SOURCE_API
|
|
, source_window_system = GL_DEBUG_SOURCE_WINDOW_SYSTEM
|
|
, source_shader_compiler = GL_DEBUG_SOURCE_SHADER_COMPILER
|
|
, source_third_party = GL_DEBUG_SOURCE_THIRD_PARTY
|
|
, source_application = GL_DEBUG_SOURCE_APPLICATION
|
|
, source_other = GL_DEBUG_SOURCE_OTHER
|
|
};
|
|
|
|
/**
|
|
* \brief Translate a debug message source into a string representation
|
|
* \param source ID of the debug message source
|
|
* \return C string containing the string representation
|
|
*/
|
|
inline const char_t* translate_source(enum_t source)
|
|
{
|
|
switch(source)
|
|
{
|
|
case source_api: return GLW_STRINGIFY(source_api);
|
|
case source_window_system: return GLW_STRINGIFY(source_window_system);
|
|
case source_shader_compiler: return GLW_STRINGIFY(source_shader_compiler);
|
|
case source_third_party: return GLW_STRINGIFY(source_third_party);
|
|
case source_application: return GLW_STRINGIFY(source_application);
|
|
case source_other: return GLW_STRINGIFY(source_other);
|
|
default: return GLW_STRINGIFY(source_unknown);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Types of debug messages
|
|
*/
|
|
enum debug_type
|
|
{
|
|
type_error = GL_DEBUG_TYPE_ERROR
|
|
, type_deprecated_behavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
|
|
, type_undefined_behavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
|
|
, type_portability = GL_DEBUG_TYPE_PORTABILITY
|
|
, type_performance = GL_DEBUG_TYPE_PERFORMANCE
|
|
, type_marker = GL_DEBUG_TYPE_MARKER
|
|
, type_push_group = GL_DEBUG_TYPE_PUSH_GROUP
|
|
, type_pop_group = GL_DEBUG_TYPE_POP_GROUP
|
|
, type_other = GL_DEBUG_TYPE_OTHER
|
|
};
|
|
|
|
inline void push_group(enum_t src, uint_t id, size_t len, const char_t* msg) { glPushDebugGroup(src, id, len, msg); }
|
|
inline void pop_group() { glPopDebugGroup(); }
|
|
|
|
inline void set_label(enum_t id, handle_t name, size_t len, const char_t* label) { glObjectLabel(id, name, len, label); }
|
|
inline void set_label(void* ptr, size_t len, const char_t* label) { glObjectPtrLabel(ptr, len, label); }
|
|
|
|
inline void get_label(enum_t id, handle_t name, size_t buf_size, size_t& length, char_t* buf)
|
|
{ glGetObjectLabel(id, name, buf_size, &length, buf); }
|
|
|
|
inline void get_label(void* ptr, size_t buf_size, size_t& length, char_t* buf)
|
|
{ glGetObjectPtrLabel(ptr, buf_size, &length, buf); }
|
|
|
|
inline const char_t* translate_type(enum_t source)
|
|
{
|
|
switch(source)
|
|
{
|
|
case type_error: return GLW_STRINGIFY(type_error);
|
|
case type_deprecated_behavior: return GLW_STRINGIFY(type_deprecated_behavior);
|
|
case type_undefined_behavior: return GLW_STRINGIFY(type_undefined_behavior);
|
|
case type_portability: return GLW_STRINGIFY(type_portability);
|
|
case type_performance: return GLW_STRINGIFY(type_performance);
|
|
case type_marker: return GLW_STRINGIFY(type_marker);
|
|
case type_push_group: return GLW_STRINGIFY(type_push_group);
|
|
case type_pop_group: return GLW_STRINGIFY(type_pop_group);
|
|
case type_other: return GLW_STRINGIFY(type_other);
|
|
default: return GLW_STRINGIFY(type_unknown);
|
|
}
|
|
}
|
|
|
|
enum debug_severity
|
|
{
|
|
severity_low = GL_DEBUG_SEVERITY_LOW
|
|
, severity_medium = GL_DEBUG_SEVERITY_MEDIUM
|
|
, severity_high = GL_DEBUG_SEVERITY_HIGH
|
|
, severity_notification = GL_DEBUG_SEVERITY_NOTIFICATION
|
|
};
|
|
|
|
inline const char_t* translate_severity(enum_t severity)
|
|
{
|
|
switch(severity)
|
|
{
|
|
case severity_low: return GLW_STRINGIFY(severity_low);
|
|
case severity_medium: return GLW_STRINGIFY(severity_medium);
|
|
case severity_high: return GLW_STRINGIFY(severity_high);
|
|
case severity_notification: return GLW_STRINGIFY(severity_notification);
|
|
default: return GLW_STRINGIFY(severity_unknown);
|
|
}
|
|
}
|
|
|
|
inline void insert_message(enum_t source, enum_t type, uint_t id, enum_t severity, size_t length, const char_t* message)
|
|
{
|
|
glDebugMessageInsert(source, type, id, severity, length, message);
|
|
}
|
|
|
|
using debug_callback = GLDEBUGPROC;
|
|
|
|
inline void set_debug_callback(debug_callback callback, void* user_data)
|
|
{
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
glDebugMessageCallback(callback, user_data);
|
|
}
|
|
|
|
}
|
|
|
|
#endif //DEBUG_H
|