Java tutorial
/* * Copyright LWJGL. All rights reserved. * License terms: https://www.lwjgl.org/license */ package org.lwjgl.opengl; import org.lwjgl.system.*; import javax.annotation.*; import java.io.*; import static org.lwjgl.opengl.AMDDebugOutput.*; import static org.lwjgl.opengl.ARBDebugOutput.*; import static org.lwjgl.opengl.GL43C.*; import static org.lwjgl.system.APIUtil.*; import static org.lwjgl.system.MemoryUtil.*; /** OpenGL utilities. */ public final class GLUtil { private GLUtil() { } /** * Detects the best debug output functionality to use and creates a callback that prints information to {@link APIUtil#DEBUG_STREAM}. The callback * function is returned as a {@link Callback}, that should be {@link Callback#free freed} when no longer needed. */ @Nullable public static Callback setupDebugMessageCallback() { return setupDebugMessageCallback(APIUtil.DEBUG_STREAM); } /** * Detects the best debug output functionality to use and creates a callback that prints information to the specified {@link PrintStream}. The callback * function is returned as a {@link Callback}, that should be {@link Callback#free freed} when no longer needed. * * @param stream the output {@link PrintStream} */ @Nullable public static Callback setupDebugMessageCallback(PrintStream stream) { GLCapabilities caps = GL.getCapabilities(); if (caps.OpenGL43) { apiLog("[GL] Using OpenGL 4.3 for error logging."); GLDebugMessageCallback proc = GLDebugMessageCallback .create((source, type, id, severity, length, message, userParam) -> { stream.println("[LWJGL] OpenGL debug message"); printDetail(stream, "ID", String.format("0x%X", id)); printDetail(stream, "Source", getDebugSource(source)); printDetail(stream, "Type", getDebugType(type)); printDetail(stream, "Severity", getDebugSeverity(severity)); printDetail(stream, "Message", GLDebugMessageCallback.getMessage(length, message)); }); glDebugMessageCallback(proc, NULL); if ((glGetInteger(GL_CONTEXT_FLAGS) & GL_CONTEXT_FLAG_DEBUG_BIT) == 0) { apiLog("[GL] Warning: A non-debug context may not produce any debug output."); glEnable(GL_DEBUG_OUTPUT); } return proc; } if (caps.GL_KHR_debug) { apiLog("[GL] Using KHR_debug for error logging."); GLDebugMessageCallback proc = GLDebugMessageCallback .create((source, type, id, severity, length, message, userParam) -> { stream.println("[LWJGL] OpenGL debug message"); printDetail(stream, "ID", String.format("0x%X", id)); printDetail(stream, "Source", getDebugSource(source)); printDetail(stream, "Type", getDebugType(type)); printDetail(stream, "Severity", getDebugSeverity(severity)); printDetail(stream, "Message", GLDebugMessageCallback.getMessage(length, message)); }); KHRDebug.glDebugMessageCallback(proc, NULL); if (caps.OpenGL30 && (glGetInteger(GL_CONTEXT_FLAGS) & GL_CONTEXT_FLAG_DEBUG_BIT) == 0) { apiLog("[GL] Warning: A non-debug context may not produce any debug output."); glEnable(GL_DEBUG_OUTPUT); } return proc; } if (caps.GL_ARB_debug_output) { apiLog("[GL] Using ARB_debug_output for error logging."); GLDebugMessageARBCallback proc = GLDebugMessageARBCallback .create((source, type, id, severity, length, message, userParam) -> { stream.println("[LWJGL] ARB_debug_output message"); printDetail(stream, "ID", String.format("0x%X", id)); printDetail(stream, "Source", getSourceARB(source)); printDetail(stream, "Type", getTypeARB(type)); printDetail(stream, "Severity", getSeverityARB(severity)); printDetail(stream, "Message", GLDebugMessageARBCallback.getMessage(length, message)); }); glDebugMessageCallbackARB(proc, NULL); return proc; } if (caps.GL_AMD_debug_output) { apiLog("[GL] Using AMD_debug_output for error logging."); GLDebugMessageAMDCallback proc = GLDebugMessageAMDCallback .create((id, category, severity, length, message, userParam) -> { stream.println("[LWJGL] AMD_debug_output message"); printDetail(stream, "ID", String.format("0x%X", id)); printDetail(stream, "Category", getCategoryAMD(category)); printDetail(stream, "Severity", getSeverityAMD(severity)); printDetail(stream, "Message", GLDebugMessageAMDCallback.getMessage(length, message)); }); glDebugMessageCallbackAMD(proc, NULL); return proc; } apiLog("[GL] No debug output implementation is available."); return null; } private static void printDetail(PrintStream stream, String type, String message) { stream.printf("\t%s: %s\n", type, message); } private static String getDebugSource(int 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 apiUnknownToken(source); } } private static String getDebugType(int type) { switch (type) { case GL_DEBUG_TYPE_ERROR: return "ERROR"; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "DEPRECATED BEHAVIOR"; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "UNDEFINED BEHAVIOR"; case GL_DEBUG_TYPE_PORTABILITY: return "PORTABILITY"; case GL_DEBUG_TYPE_PERFORMANCE: return "PERFORMANCE"; case GL_DEBUG_TYPE_OTHER: return "OTHER"; case GL_DEBUG_TYPE_MARKER: return "MARKER"; default: return apiUnknownToken(type); } } private static String getDebugSeverity(int severity) { switch (severity) { case GL_DEBUG_SEVERITY_HIGH: return "HIGH"; case GL_DEBUG_SEVERITY_MEDIUM: return "MEDIUM"; case GL_DEBUG_SEVERITY_LOW: return "LOW"; case GL_DEBUG_SEVERITY_NOTIFICATION: return "NOTIFICATION"; default: return apiUnknownToken(severity); } } private static String getSourceARB(int source) { switch (source) { case GL_DEBUG_SOURCE_API_ARB: return "API"; case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "WINDOW SYSTEM"; case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "SHADER COMPILER"; case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "THIRD PARTY"; case GL_DEBUG_SOURCE_APPLICATION_ARB: return "APPLICATION"; case GL_DEBUG_SOURCE_OTHER_ARB: return "OTHER"; default: return apiUnknownToken(source); } } private static String getTypeARB(int type) { switch (type) { case GL_DEBUG_TYPE_ERROR_ARB: return "ERROR"; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "DEPRECATED BEHAVIOR"; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "UNDEFINED BEHAVIOR"; case GL_DEBUG_TYPE_PORTABILITY_ARB: return "PORTABILITY"; case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "PERFORMANCE"; case GL_DEBUG_TYPE_OTHER_ARB: return "OTHER"; default: return apiUnknownToken(type); } } private static String getSeverityARB(int severity) { switch (severity) { case GL_DEBUG_SEVERITY_HIGH_ARB: return "HIGH"; case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "MEDIUM"; case GL_DEBUG_SEVERITY_LOW_ARB: return "LOW"; default: return apiUnknownToken(severity); } } private static String getCategoryAMD(int category) { switch (category) { case GL_DEBUG_CATEGORY_API_ERROR_AMD: return "API ERROR"; case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: return "WINDOW SYSTEM"; case GL_DEBUG_CATEGORY_DEPRECATION_AMD: return "DEPRECATION"; case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: return "UNDEFINED BEHAVIOR"; case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: return "PERFORMANCE"; case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: return "SHADER COMPILER"; case GL_DEBUG_CATEGORY_APPLICATION_AMD: return "APPLICATION"; case GL_DEBUG_CATEGORY_OTHER_AMD: return "OTHER"; default: return apiUnknownToken(category); } } private static String getSeverityAMD(int severity) { switch (severity) { case GL_DEBUG_SEVERITY_HIGH_AMD: return "HIGH"; case GL_DEBUG_SEVERITY_MEDIUM_AMD: return "MEDIUM"; case GL_DEBUG_SEVERITY_LOW_AMD: return "LOW"; default: return apiUnknownToken(severity); } } }