You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.3 KiB
147 lines
4.3 KiB
|
|
// NOTE: get useful debug messages from opengl |
|
// https://www.khronos.org/opengl/wiki/Debug_Output |
|
|
|
#ifndef GL_DEBUG_H |
|
#define GL_DEBUG_H |
|
|
|
#include <GL/glew.h> |
|
|
|
#include "shader.h" |
|
|
|
|
|
void dumpShader(GLuint prog_id); |
|
|
|
const char* glEnumToString(GLenum e); |
|
|
|
void openglDebugCallback(GLenum source, |
|
GLenum type, |
|
GLuint id, |
|
GLenum severity, |
|
GLsizei length, |
|
const GLchar* message, |
|
const void* userParam); |
|
|
|
#endif // GL_DEBUG_H |
|
|
|
|
|
#ifdef GL_DEBUG_IMPLEMENTATION |
|
|
|
const char* |
|
glEnumToString(GLenum e) |
|
{ |
|
switch (e) { |
|
case GL_FLOAT_MAT4: return "GL_FLOAT_MAT4"; |
|
case GL_FLOAT_VEC3: return "GL_FLOAT_VEC3"; |
|
case GL_FLOAT_VEC4: return "GL_FLOAT_VEC4"; |
|
|
|
case GL_BYTE: return "GL_BYTE"; |
|
case GL_UNSIGNED_BYTE: return "GL_UNSIGNED_BYTE"; |
|
case GL_SHORT: return "GL_SHORT"; |
|
case GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT"; |
|
case GL_INT: return "GL_INT"; |
|
case GL_UNSIGNED_INT: return "GL_UNSIGNED_INT"; |
|
case GL_FLOAT: return "GL_FLOAT"; |
|
case GL_DOUBLE: return "GL_DOUBLE"; |
|
|
|
case GL_ARRAY_BUFFER: return "GL_ARRAY_BUFFER"; |
|
case GL_ELEMENT_ARRAY_BUFFER: return "GL_ELEMENT_ARRAY_BUFFER"; |
|
case GL_UNIFORM_BUFFER: return "GL_UNIFORM_BUFFER"; |
|
case GL_TEXTURE_BUFFER: return "GL_TEXTURE_BUFFER"; |
|
|
|
case GL_DEBUG_TYPE_ERROR: return "GL_DEBUG_TYPE_ERROR"; |
|
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: |
|
return "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"; |
|
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: |
|
return "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"; |
|
case GL_DEBUG_TYPE_PORTABILITY: return "GL_DEBUG_TYPE_PORTABILITY"; |
|
case GL_DEBUG_TYPE_PERFORMANCE: return "GL_DEBUG_TYPE_PERFORMANCE"; |
|
case GL_DEBUG_TYPE_MARKER: return "GL_DEBUG_TYPE_MARKER"; |
|
case GL_DEBUG_TYPE_PUSH_GROUP: return "GL_DEBUG_TYPE_PUSH_GROUP"; |
|
case GL_DEBUG_TYPE_POP_GROUP: return "GL_DEBUG_TYPE_POP_GROUP"; |
|
case GL_DEBUG_TYPE_OTHER: return "GL_DEBUG_TYPE_OTHER"; |
|
|
|
case GL_DEBUG_SEVERITY_HIGH: return "GL_DEBUG_SEVERITY_HIGH"; |
|
case GL_DEBUG_SEVERITY_MEDIUM: return "GL_DEBUG_SEVERITY_MEDIUM"; |
|
case GL_DEBUG_SEVERITY_LOW: return "GL_DEBUG_SEVERITY_LOW"; |
|
case GL_DEBUG_SEVERITY_NOTIFICATION: |
|
return "GL_DEBUG_SEVERITY_NOTIFICATION"; |
|
|
|
case GL_NO_ERROR: return "GL_NO_ERROR"; |
|
case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; |
|
case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; |
|
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; |
|
case GL_INVALID_FRAMEBUFFER_OPERATION: |
|
return "GL_INVALID_FRAMEBUFFER_OPERATION"; |
|
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; |
|
|
|
default: return "???"; |
|
} |
|
} |
|
|
|
void |
|
openglDebugCallback(GLenum source, |
|
GLenum type, |
|
GLuint id, |
|
GLenum severity, |
|
GLsizei length, |
|
const GLchar* message, |
|
const void* userParam) |
|
{ |
|
// NOTE: filter out notification about using video memory for buffer object |
|
if (id == 131185) |
|
return; |
|
|
|
std::cout << "message id: " << id << ", " |
|
<< ((type == GL_DEBUG_TYPE_ERROR) ? "Error" : "Debug") |
|
<< (type == GL_DEBUG_TYPE_ERROR ? "** GL Error **" : "") |
|
<< ", type: " << glEnumToString(type) |
|
<< ", severity: " << glEnumToString(severity) |
|
<< ", message: " << message << "\n"; |
|
} |
|
|
|
void |
|
dumpShader(GLuint prog_id) |
|
{ |
|
LOGF(Debug, "------------------------\n"); |
|
LOGF(Debug, "%s(), dumping shader info, program id: %d\n", |
|
__FUNCTION__, prog_id); |
|
|
|
GLint active_uniforms; |
|
GLint active_uniform_blocks; |
|
GLint active_attribs; |
|
|
|
// NOTE: unused uniforms/attributes get optimized away |
|
// https://www.khronos.org/opengl/wiki/Program_Introspection#Attributes |
|
glGetProgramiv(prog_id, GL_ACTIVE_UNIFORMS, &active_uniforms); |
|
glGetProgramiv(prog_id, GL_ACTIVE_UNIFORM_BLOCKS, &active_uniform_blocks); |
|
glGetProgramiv(prog_id, GL_ACTIVE_ATTRIBUTES, &active_attribs); |
|
|
|
LOGF(Debug, "active uniforms: %d\n", active_uniforms); |
|
LOGF(Debug, "active uniform blocks: %d\n", active_uniform_blocks); |
|
LOGF(Debug, "active attributes: %d\n", active_attribs); |
|
|
|
GLchar uni_name[256]; |
|
GLsizei length; |
|
GLint size; |
|
GLenum type; |
|
|
|
for (int i = 0; i < active_uniforms; i++) { |
|
glGetActiveUniform(prog_id, i, sizeof(uni_name), |
|
&length, &size, &type, uni_name); |
|
LOGF(Debug, "uniform idx: %d, type: %s, name: %s \n", |
|
i, glEnumToString(type), uni_name); |
|
} |
|
|
|
for (int i = 0; i < active_attribs; i++) { |
|
glGetActiveAttrib(prog_id, i, sizeof(uni_name), |
|
&length, &size, &type, uni_name); |
|
LOGF(Debug, "attribute idx: %d, type: %s, name: %s \n", |
|
i, glEnumToString(type), uni_name); |
|
} |
|
|
|
LOGF(Debug, "------------------------\n"); |
|
} |
|
|
|
#endif // ifdef GL_DEBUG_IMPLEMENTATION |
|
|
|
|