std::vector<debug_log> debug_logs(GLuint count) { auto max_message_size = 0; glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &max_message_size); std::vector<GLenum> sources (count); std::vector<GLenum> types (count); std::vector<GLuint> ids (count); std::vector<GLenum> severities (count); std::vector<GLsizei> message_sizes(count); std::vector<GLchar> message_data (count * max_message_size); auto real_count = glGetDebugMessageLog(count, static_cast<GLsizei>(message_data.size()), &sources[0], &types[0], &ids[0], &severities[0], &message_sizes[0], &message_data[0]); sources .resize(real_count); types .resize(real_count); ids .resize(real_count); severities .resize(real_count); message_sizes.resize(real_count); std::vector<std::string> messages(real_count); auto current_message = message_data.begin(); for (size_t i = 0; i < message_sizes.size(); ++i) { messages[i] = std::string(current_message, current_message + message_sizes[i] - 1); current_message = current_message + message_sizes[i]; } std::vector<debug_log> debug_logs(real_count); for (unsigned i = 0; i < real_count; i++) debug_logs[i] = debug_log{sources[i], types[i], ids[i], severities[i], messages[i], nullptr}; return debug_logs; }
JNIEXPORT jint JNICALL Java_org_lwjgl_opengles_GLES32_nglGetDebugMessageLog__IIJJJJJJ(JNIEnv *__env, jclass clazz, jint count, jint bufsize, jlong sourcesAddress, jlong typesAddress, jlong idsAddress, jlong severitiesAddress, jlong lengthsAddress, jlong messageLogAddress) { glGetDebugMessageLogPROC glGetDebugMessageLog = (glGetDebugMessageLogPROC)tlsGetFunction(319); intptr_t sources = (intptr_t)sourcesAddress; intptr_t types = (intptr_t)typesAddress; intptr_t ids = (intptr_t)idsAddress; intptr_t severities = (intptr_t)severitiesAddress; intptr_t lengths = (intptr_t)lengthsAddress; intptr_t messageLog = (intptr_t)messageLogAddress; UNUSED_PARAM(clazz) return (jint)glGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog); }
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_GL43_nglGetDebugMessageLog(JNIEnv *env, jclass clazz, jint count, jint bufsize, jlong sources, jlong types, jlong ids, jlong severities, jlong lengths, jlong messageLog, jlong function_pointer) { GLenum *sources_address = (GLenum *)(intptr_t)sources; GLenum *types_address = (GLenum *)(intptr_t)types; GLuint *ids_address = (GLuint *)(intptr_t)ids; GLenum *severities_address = (GLenum *)(intptr_t)severities; GLsizei *lengths_address = (GLsizei *)(intptr_t)lengths; GLchar *messageLog_address = (GLchar *)(intptr_t)messageLog; glGetDebugMessageLogPROC glGetDebugMessageLog = (glGetDebugMessageLogPROC)((intptr_t)function_pointer); GLuint __result = glGetDebugMessageLog(count, bufsize, sources_address, types_address, ids_address, severities_address, lengths_address, messageLog_address); return __result; }
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_GL43_nglGetDebugMessageLog(JNIEnv *__env, jclass clazz, jint count, jint bufsize, jlong sourcesAddress, jlong typesAddress, jlong idsAddress, jlong severitiesAddress, jlong lengthsAddress, jlong messageLogAddress, jlong __functionAddress) { GLenum *sources = (GLenum *)(intptr_t)sourcesAddress; GLenum *types = (GLenum *)(intptr_t)typesAddress; GLuint *ids = (GLuint *)(intptr_t)idsAddress; GLenum *severities = (GLenum *)(intptr_t)severitiesAddress; GLsizei *lengths = (GLsizei *)(intptr_t)lengthsAddress; GLchar *messageLog = (GLchar *)(intptr_t)messageLogAddress; glGetDebugMessageLogPROC glGetDebugMessageLog = (glGetDebugMessageLogPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) return (jint)glGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog); }
static inline void opengl_post_hook(const char* name, void* fptr, int len_args, ...) { /* Shader errors */ const char* shdr_err = 0; if (fptr == glCompileShader || fptr == glLinkProgram) { GLuint s; va_list l; va_start(l, len_args); s = va_arg(l, GLuint); va_end(l); if (fptr == glCompileShader) shdr_err = gl_check_last_compile_error(s); else if (fptr == glLinkProgram) shdr_err = gl_check_last_link_error(s); } GLenum code = REAL_GL_FUNC(glGetError)(); if (code != GL_NO_ERROR || shdr_err) { /* Header */ size_t sz = 0; char* buf = 0; const char* header_fmt = "PANIC!\nOpenGL error in %s():\n"; sz += snprintf(0, 0, header_fmt, name) + 1; buf = realloc(buf, sz); snprintf(buf, sz, header_fmt, name); /* Shader errors */ if (shdr_err) { sz += strlen(shdr_err); buf = realloc(buf, sz); strcat(buf, shdr_err); free((void*)shdr_err); shdr_err = 0; } /* Messages */ for (;;) { GLint next_log_len = 0; glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &next_log_len); if (!next_log_len) break; char* msg_buf = calloc(1, next_log_len); GLsizei length; GLenum source, type, id, severity; glGetDebugMessageLog(1, next_log_len, &source, &type, &id, &severity, &length, (GLchar*)msg_buf); if (type == GL_DEBUG_TYPE_ERROR) { const char* msg = construct_opengl_debug_msg(source, type, id, severity, length, (const char*)msg_buf); sz += strlen(msg); buf = realloc(buf, sz); strcat(buf, msg); free((void*)msg); } free(msg_buf); } /* Backtrace */ #ifdef __GLIBC__ const char* bt = btrace(); sz += strlen(bt); buf = realloc(buf, sz); strcat(buf, bt); free((void*)bt); #endif /* Show */ showerr_cb(showerr_ud, buf); free(buf); } }