Bläddra i källkod

WARNING: REDESIGNED: rlLoadExtensions() #1295

Added config flag: SUPPORT_GL_DETAILS_INFO
Ray 4 år sedan
förälder
incheckning
d4ccca81db
3 ändrade filer med 305 tillägg och 195 borttagningar
  1. 3 0
      src/config.h
  2. 5 6
      src/core.c
  3. 297 189
      src/rlgl.h

+ 3 - 0
src/config.h

@@ -80,6 +80,9 @@
 //------------------------------------------------------------------------------------
 // Module: rlgl - Configuration values
 //------------------------------------------------------------------------------------
+// Show OpenGL extensions and capabilities detailed logs on init
+//#define SUPPORT_GL_DETAILS_INFO        1
+
 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
     #define DEFAULT_BATCH_BUFFER_ELEMENTS   8192    // Default internal render batch limits
 #elif defined(GRAPHICS_API_OPENGL_ES2)

+ 5 - 6
src/core.c

@@ -3770,12 +3770,6 @@ static bool InitGraphicsDevice(int width, int height)
     glfwSwapInterval(0);        // No V-Sync by default
 #endif
 
-#if defined(PLATFORM_DESKTOP)
-    // Load OpenGL 3.3 extensions
-    // NOTE: GLFW loader function is passed as parameter
-    rlLoadExtensions(glfwGetProcAddress);
-#endif
-
     // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
     // NOTE: V-Sync can be enabled by graphic driver configuration
     if (CORE.Window.flags & FLAG_VSYNC_HINT)
@@ -4357,6 +4351,11 @@ static bool InitGraphicsDevice(int width, int height)
     }
 #endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP
 
+    // Load OpenGL extensions
+    // NOTE: GLFW loader function is required by GLAD but only used for OpenGL 2.1 and 3.3,
+    // OpenGL ES 2.0 extensions (and entry points) are loaded manually using eglGetProcAddress()
+    rlLoadExtensions(glfwGetProcAddress);
+
     // Initialize OpenGL context (states and resources)
     // NOTE: CORE.Window.screen.width and CORE.Window.screen.height not used, just stored as globals in rlgl
     rlglInit(CORE.Window.screen.width, CORE.Window.screen.height);

+ 297 - 189
src/rlgl.h

@@ -28,6 +28,8 @@
 *   #define RLGL_STANDALONE
 *       Use rlgl as standalone library (no raylib dependency)
 *
+*   #define SUPPORT_GL_DETAILS_INFO
+*       Show OpenGL extensions and capabilities detailed logs on init
 *
 *   DEPENDENCIES:
 *       raymath     - 3D math functionality (Vector3, Matrix, Quaternion)
@@ -837,7 +839,7 @@ typedef struct rlglData {
         bool texMirrorClamp;                // Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp)
         bool texAnisoFilter;                // Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic)
 
-        float maxAnisotropicLevel;          // Maximum anisotropy level supported (minimum is 2.0f)
+        float maxAnisotropyLevel;          // Maximum anisotropy level supported (minimum is 2.0f)
         int maxDepthBits;                   // Maximum bits for depth component
 
     } ExtSupported;     // Extensions supported flags
@@ -869,6 +871,9 @@ static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL;
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
 static void rlLoadShaderDefault(void);      // Load default shader (RLGL.State.defaultShader)
 static void rlUnloadShaderDefault(void);    // Unload default shader (RLGL.State.defaultShader)
+#if defined(SUPPORT_GL_DETAILS_INFO)
+static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
+#endif  // SUPPORT_GL_DETAILS_INFO
 #endif  // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
 #if defined(GRAPHICS_API_OPENGL_11)
 static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight);   // Generate mipmaps data on CPU side
@@ -1346,10 +1351,10 @@ void rlTextureParameters(unsigned int id, int param, int value)
         case RL_TEXTURE_FILTER_ANISOTROPIC:
         {
 #if !defined(GRAPHICS_API_OPENGL_11)
-            if (value <= RLGL.ExtSupported.maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
-            else if (RLGL.ExtSupported.maxAnisotropicLevel > 0.0f)
+            if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
+            else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f)
             {
-                TRACELOG(LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, RLGL.ExtSupported.maxAnisotropicLevel);
+                TRACELOG(LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, RLGL.ExtSupported.maxAnisotropyLevel);
                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
             }
             else TRACELOG(LOG_WARNING, "GL: Anisotropic filtering not supported");
@@ -1577,72 +1582,141 @@ void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
 // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states
 void rlglInit(int width, int height)
 {
-    // Check OpenGL information and capabilities
-    //------------------------------------------------------------------------------
-    // Print current OpenGL and GLSL version
-    TRACELOG(LOG_INFO, "GL: OpenGL device information:");
-    TRACELOG(LOG_INFO, "    > Vendor:   %s", glGetString(GL_VENDOR));
-    TRACELOG(LOG_INFO, "    > Renderer: %s", glGetString(GL_RENDERER));
-    TRACELOG(LOG_INFO, "    > Version:  %s", glGetString(GL_VERSION));
-    TRACELOG(LOG_INFO, "    > GLSL:     %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+    // Init default white texture
+    unsigned char pixels[4] = { 255, 255, 255, 255 };   // 1 pixel RGBA (4 bytes)
+    RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
 
-    // NOTE: We can get a bunch of extra information about GPU capabilities (glGet*)
-    //int maxTexSize;
-    //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
-    //TRACELOG(LOG_INFO, "GL: Maximum texture size: %i", maxTexSize);
+    if (RLGL.State.defaultTextureId != 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId);
+    else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load default texture");
 
-    //GL_MAX_TEXTURE_IMAGE_UNITS
-    //GL_MAX_VIEWPORT_DIMS
+    // Init default Shader (customized for GL 3.3 and ES2)
+    rlLoadShaderDefault(); // RLGL.State.defaultShader
+    RLGL.State.currentShader = RLGL.State.defaultShader;
 
-    //int numAuxBuffers;
-    //glGetIntegerv(GL_AUX_BUFFERS, &numAuxBuffers);
-    //TRACELOG(LOG_INFO, "GL: Number of aixiliar buffers: %i", numAuxBuffers);
+    // Init default vertex arrays buffers
+    RLGL.defaultBatch = rlLoadRenderBatch(DEFAULT_BATCH_BUFFERS, DEFAULT_BATCH_BUFFER_ELEMENTS);
+    RLGL.currentBatch = &RLGL.defaultBatch;
 
-    //GLint numComp = 0;
-    //GLint format[32] = { 0 };
-    //glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp);
-    //glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format);
-    //for (int i = 0; i < numComp; i++) TRACELOG(LOG_INFO, "GL: Supported compressed format: 0x%x", format[i]);
+    // Init stack matrices (emulating OpenGL 1.1)
+    for (int i = 0; i < MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = MatrixIdentity();
 
-    // NOTE: We don't need that much data on screen... right now...
+    // Init internal matrices
+    RLGL.State.transform = MatrixIdentity();
+    RLGL.State.projection = MatrixIdentity();
+    RLGL.State.modelview = MatrixIdentity();
+    RLGL.State.currentMatrix = &RLGL.State.modelview;
+#endif      // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
 
-    // TODO: Automatize extensions loading using rlLoadExtensions() and GLAD
-    // Actually, when rlglInit() is called in InitWindow() in core.c,
-    // OpenGL context has already been created and required extensions loaded
+    // Initialize OpenGL default states
+    //----------------------------------------------------------
+    // Init state: Depth test
+    glDepthFunc(GL_LEQUAL);                                 // Type of depth testing to apply
+    glDisable(GL_DEPTH_TEST);                               // Disable depth testing for 2D (only used for 3D)
+
+    // Init state: Blending mode
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);      // Color blending function (how colors are mixed)
+    glEnable(GL_BLEND);                                     // Enable color blending (required to work with transparencies)
+
+    // Init state: Culling
+    // NOTE: All shapes/models triangles are drawn CCW
+    glCullFace(GL_BACK);                                    // Cull the back face (default)
+    glFrontFace(GL_CCW);                                    // Front face are defined counter clockwise (default)
+    glEnable(GL_CULL_FACE);                                 // Enable backface culling
+
+    // Init state: Cubemap seamless
+#if defined(GRAPHICS_API_OPENGL_33)
+    glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);                 // Seamless cubemaps (not supported on OpenGL ES 2.0)
+#endif
+
+#if defined(GRAPHICS_API_OPENGL_11)
+    // Init state: Color hints (deprecated in OpenGL 3.0+)
+    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);      // Improve quality of color and texture coordinate interpolation
+    glShadeModel(GL_SMOOTH);                                // Smooth shading between vertex (vertex colors interpolation)
+#endif
 
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    // Get supported extensions list
+    // Store screen size into global variables
+    RLGL.State.framebufferWidth = width;
+    RLGL.State.framebufferHeight = height;
+
+    TRACELOG(LOG_INFO, "RLGL: Default OpenGL state initialized successfully");
+    //----------------------------------------------------------
+#endif
+
+    // Init state: Color/Depth buffers clear
+    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                   // Set clear color (black)
+    glClearDepth(1.0f);                                     // Set clear depth value (default)
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear color and depth buffers (depth buffer required for 3D)
+}
+
+// Vertex Buffer Object deinitialization (memory free)
+void rlglClose(void)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+    rlUnloadRenderBatch(RLGL.defaultBatch);
+
+    rlUnloadShaderDefault();          // Unload default shader
+
+    glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
+    TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId);
+#endif
+}
+
+// Load OpenGL extensions
+// NOTE: External loader function could be passed as a pointer
+void rlLoadExtensions(void *loader)
+{
+#if defined(GRAPHICS_API_OPENGL_33)     // Also defined for GRAPHICS_API_OPENGL_21
+    // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
+    #if !defined(__APPLE__)
+        if (!gladLoadGLLoader((GLADloadproc)loader)) TRACELOG(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
+        else TRACELOG(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
+    #endif
+
+    // Get number of supported extensions
     GLint numExt = 0;
+    glGetIntegerv(GL_NUM_EXTENSIONS, &numExt);
+    TRACELOG(LOG_INFO, "GL: Supported extensions count: %i", numExt);
 
-#if defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_21)
+#if defined(SUPPORT_GL_DETAILS_INFO)
+    // Get supported extensions list
+    // WARNING: glGetStringi() not available on OpenGL 2.1
+    char **extList = RL_MALLOC(sizeof(char *)*numExt);
+    TRACELOG(LOG_INFO, "GL: OpenGL extensions:");
+    for (int i = 0; i < numExt; i++) 
+    {
+        extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i);
+        TRACELOG(LOG_INFO, "    %s", extList[i]);
+    }
+    RL_FREE(extList);       // Free extensions pointers
+#endif
+
+    // Register supported extensions flags
     // OpenGL 3.3 extensions supported by default (core)
     RLGL.ExtSupported.vao = true;
     RLGL.ExtSupported.instancing = true;
     RLGL.ExtSupported.texNPOT = true;
     RLGL.ExtSupported.texFloat32 = true;
     RLGL.ExtSupported.texDepth = true;
+    RLGL.ExtSupported.maxDepthBits = 32;
+    RLGL.ExtSupported.texAnisoFilter = true;
+    RLGL.ExtSupported.texMirrorClamp = true;
+    // NOTE: With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
+    if (GLAD_GL_EXT_texture_compression_s3tc) RLGL.ExtSupported.texCompDXT = true;  // Texture compression: DXT
+    if (GLAD_GL_ARB_ES3_compatibility) RLGL.ExtSupported.texCompETC2 = true;        // Texture compression: ETC2/EAC
+#endif  // GRAPHICS_API_OPENGL_33
 
-    // We get a list of available extensions and we check for some of them (compressed textures)
-    // NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that)
-    glGetIntegerv(GL_NUM_EXTENSIONS, &numExt);
-
-    // Allocate numExt strings pointers
-    char **extList = RL_MALLOC(sizeof(char *)*numExt);
-
-    // Get extensions strings
-    for (int i = 0; i < numExt; i++) extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i);
-#endif
-#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    // Allocate 512 strings pointers (2 KB)
-    const char **extList = RL_MALLOC(512*sizeof(const char *));
-
+#if defined(GRAPHICS_API_OPENGL_ES2)
+    // Get supported extensions list
+    GLint numExt = 0;
+    const char **extList = RL_MALLOC(512*sizeof(const char *)); // Allocate 512 strings pointers (2 KB)
     const char *extensions = (const char *)glGetString(GL_EXTENSIONS);  // One big const string
 
     // NOTE: We have to duplicate string because glGetString() returns a const string
     int len = strlen(extensions) + 1;
     char *extensionsDup = (char *)RL_CALLOC(len, sizeof(char));
     strcpy(extensionsDup, extensions);
-
     extList[numExt] = extensionsDup;
 
     for (int i = 0; i < len; i++)
@@ -1650,24 +1724,21 @@ void rlglInit(int width, int height)
         if (extensionsDup[i] == ' ')
         {
             extensionsDup[i] = '\0';
-
             numExt++;
             extList[numExt] = &extensionsDup[i + 1];
         }
     }
-
-    // NOTE: Duplicated string (extensionsDup) must be deallocated
-#endif
-
+    
     TRACELOG(LOG_INFO, "GL: Supported extensions count: %i", numExt);
 
-    // Show supported extensions
-    //for (int i = 0; i < numExt; i++)  TRACELOG(LOG_INFO, "Supported extension: %s", extList[i]);
+#if defined(SUPPORT_GL_DETAILS_INFO)
+    TRACELOG(LOG_INFO, "GL: OpenGL extensions:");
+    for (int i = 0; i < numExt; i++) TRACELOG(LOG_INFO, "    %s", extList[i]);
+#endif
 
     // Check required extensions
     for (int i = 0; i < numExt; i++)
     {
-#if defined(GRAPHICS_API_OPENGL_ES2)
         // Check VAO support
         // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature
         if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0)
@@ -1717,162 +1788,98 @@ void rlglInit(int width, int height)
 
         if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24;
         if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32;
-#endif
-        // DDS texture compression support
+
+        // Check texture compression support: DXT
         if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
             (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) ||
             (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true;
 
-        // ETC1 texture compression support
+        // Check texture compression support: ETC1
         if ((strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) ||
             (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_etc1") == 0)) RLGL.ExtSupported.texCompETC1 = true;
 
-        // ETC2/EAC texture compression support
+        // Check texture compression support: ETC2/EAC
         if (strcmp(extList[i], (const char *)"GL_ARB_ES3_compatibility") == 0) RLGL.ExtSupported.texCompETC2 = true;
 
-        // PVR texture compression support
+        // Check texture compression support: PVR
         if (strcmp(extList[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) RLGL.ExtSupported.texCompPVRT = true;
 
-        // ASTC texture compression support
+        // Check texture compression support: ASTC
         if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) RLGL.ExtSupported.texCompASTC = true;
 
-        // Anisotropic texture filter support
-        if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0)
-        {
-            RLGL.ExtSupported.texAnisoFilter = true;
-            glGetFloatv(0x84FF, &RLGL.ExtSupported.maxAnisotropicLevel);   // GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
-        }
+        // Check anisotropic texture filter support
+        if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0) RLGL.ExtSupported.texAnisoFilter = true;
 
-        // Clamp mirror wrap mode supported
+        // Check clamp mirror wrap mode support
         if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true;
     }
 
     // Free extensions pointers
     RL_FREE(extList);
-
-#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
     RL_FREE(extensionsDup);    // Duplicated string must be deallocated
-#endif
+#endif  // GRAPHICS_API_OPENGL_ES2
 
-#if defined(GRAPHICS_API_OPENGL_ES2)
-    if (RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "GL: VAO extension detected, VAO functions initialized successfully");
+    // Check OpenGL information and capabilities
+    //------------------------------------------------------------------------------
+    // Show current OpenGL and GLSL version
+    TRACELOG(LOG_INFO, "GL: OpenGL device information:");
+    TRACELOG(LOG_INFO, "    > Vendor:   %s", glGetString(GL_VENDOR));
+    TRACELOG(LOG_INFO, "    > Renderer: %s", glGetString(GL_RENDERER));
+    TRACELOG(LOG_INFO, "    > Version:  %s", glGetString(GL_VERSION));
+    TRACELOG(LOG_INFO, "    > GLSL:     %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
+    
+    // NOTE: Anisotropy levels capability is an extension
+    #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
+        #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+    #endif
+    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel);
+
+#if defined(SUPPORT_GL_DETAILS_INFO)
+    // Show some OpenGL GPU capabilities
+    TRACELOG(LOG_INFO, "GL: OpenGL capabilities:");
+    GLint capability = 0;
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_TEXTURE_SIZE: %i", capability);
+    glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_CUBE_MAP_TEXTURE_SIZE: %i", capability);
+    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_TEXTURE_IMAGE_UNITS: %i", capability);
+    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_VERTEX_ATTRIBS: %i", capability);
+    #if !defined(GRAPHICS_API_OPENGL_ES2)
+    glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_UNIFORM_BLOCK_SIZE: %i", capability);
+    glGetIntegerv(GL_MAX_DRAW_BUFFERS, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_DRAW_BUFFERS: %i", capability);
+    if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "    GL_MAX_TEXTURE_MAX_ANISOTROPY: %.0f", RLGL.ExtSupported.maxAnisotropyLevel);
+    #endif
+    glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &capability);
+    TRACELOG(LOG_INFO, "    GL_NUM_COMPRESSED_TEXTURE_FORMATS: %i", capability);
+    GLint format[32] = { 0 };
+    glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format);
+    for (int i = 0; i < capability; i++) TRACELOG(LOG_INFO, "        %s", rlGetCompressedFormatName(format[i]));
+
+    /*
+    // Following capabilities are only supported by OpenGL 4.3 or greater
+    glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability);
+    glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &capability);
+    TRACELOG(LOG_INFO, "    GL_MAX_UNIFORM_LOCATIONS: %i", capability);
+    */
+#else   // SUPPORT_GL_DETAILS_INFO
+
+    // Show some basic info about GL supported features
+    #if defined(GRAPHICS_API_OPENGL_ES2)
+    if (RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully");
     else TRACELOG(LOG_WARNING, "GL: VAO extension not found, VAO not supported");
-
     if (RLGL.ExtSupported.texNPOT) TRACELOG(LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
     else TRACELOG(LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
-#endif
-
+    #endif
     if (RLGL.ExtSupported.texCompDXT) TRACELOG(LOG_INFO, "GL: DXT compressed textures supported");
     if (RLGL.ExtSupported.texCompETC1) TRACELOG(LOG_INFO, "GL: ETC1 compressed textures supported");
     if (RLGL.ExtSupported.texCompETC2) TRACELOG(LOG_INFO, "GL: ETC2/EAC compressed textures supported");
     if (RLGL.ExtSupported.texCompPVRT) TRACELOG(LOG_INFO, "GL: PVRT compressed textures supported");
     if (RLGL.ExtSupported.texCompASTC) TRACELOG(LOG_INFO, "GL: ASTC compressed textures supported");
-
-    if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "GL: Anisotropic textures filtering supported (max: %.0fX)", RLGL.ExtSupported.maxAnisotropicLevel);
-    if (RLGL.ExtSupported.texMirrorClamp) TRACELOG(LOG_INFO, "GL: Mirror clamp wrap texture mode supported");
-
-    // Initialize buffers, default shaders and default textures
-    //----------------------------------------------------------
-    // Init default white texture
-    unsigned char pixels[4] = { 255, 255, 255, 255 };   // 1 pixel RGBA (4 bytes)
-    RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
-
-    if (RLGL.State.defaultTextureId != 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId);
-    else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load default texture");
-
-    // Init default Shader (customized for GL 3.3 and ES2)
-    rlLoadShaderDefault(); // RLGL.State.defaultShader
-    RLGL.State.currentShader = RLGL.State.defaultShader;
-
-    // Init default vertex arrays buffers
-    RLGL.defaultBatch = rlLoadRenderBatch(DEFAULT_BATCH_BUFFERS, DEFAULT_BATCH_BUFFER_ELEMENTS);
-    RLGL.currentBatch = &RLGL.defaultBatch;
-
-    // Init stack matrices (emulating OpenGL 1.1)
-    for (int i = 0; i < MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = MatrixIdentity();
-
-    // Init internal matrices
-    RLGL.State.transform = MatrixIdentity();
-    RLGL.State.projection = MatrixIdentity();
-    RLGL.State.modelview = MatrixIdentity();
-    RLGL.State.currentMatrix = &RLGL.State.modelview;
-
-#endif      // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
-
-    // Initialize OpenGL default states
-    //----------------------------------------------------------
-    // Init state: Depth test
-    glDepthFunc(GL_LEQUAL);                                 // Type of depth testing to apply
-    glDisable(GL_DEPTH_TEST);                               // Disable depth testing for 2D (only used for 3D)
-
-    // Init state: Blending mode
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);      // Color blending function (how colors are mixed)
-    glEnable(GL_BLEND);                                     // Enable color blending (required to work with transparencies)
-
-    // Init state: Culling
-    // NOTE: All shapes/models triangles are drawn CCW
-    glCullFace(GL_BACK);                                    // Cull the back face (default)
-    glFrontFace(GL_CCW);                                    // Front face are defined counter clockwise (default)
-    glEnable(GL_CULL_FACE);                                 // Enable backface culling
-
-    // Init state: Cubemap seamless
-#if defined(GRAPHICS_API_OPENGL_33)
-    glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);                 // Seamless cubemaps (not supported on OpenGL ES 2.0)
-#endif
-
-#if defined(GRAPHICS_API_OPENGL_11)
-    // Init state: Color hints (deprecated in OpenGL 3.0+)
-    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);      // Improve quality of color and texture coordinate interpolation
-    glShadeModel(GL_SMOOTH);                                // Smooth shading between vertex (vertex colors interpolation)
-#endif
-
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    // Store screen size into global variables
-    RLGL.State.framebufferWidth = width;
-    RLGL.State.framebufferHeight = height;
-
-    TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully");
-#endif
-
-    // Init state: Color/Depth buffers clear
-    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                   // Set clear color (black)
-    glClearDepth(1.0f);                                     // Set clear depth value (default)
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear color and depth buffers (depth buffer required for 3D)
-}
-
-// Vertex Buffer Object deinitialization (memory free)
-void rlglClose(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    rlUnloadRenderBatch(RLGL.defaultBatch);
-
-    rlUnloadShaderDefault();          // Unload default shader
-    glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
-
-    TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded default texture data from VRAM (GPU)", RLGL.State.defaultTextureId);
-#endif
-}
-
-// Load OpenGL extensions
-// NOTE: External loader function could be passed as a pointer
-void rlLoadExtensions(void *loader)
-{
-#if defined(GRAPHICS_API_OPENGL_33)
-    // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
-    #if !defined(__APPLE__)
-        if (!gladLoadGLLoader((GLADloadproc)loader)) TRACELOG(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
-        else TRACELOG(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
-
-        #if defined(GRAPHICS_API_OPENGL_21)
-        if (GLAD_GL_VERSION_2_1) TRACELOG(LOG_INFO, "GL: OpenGL 2.1 profile supported");
-        #else
-        if (GLAD_GL_VERSION_3_3) TRACELOG(LOG_INFO, "GL: OpenGL 3.3 Core profile supported");
-        else TRACELOG(LOG_ERROR, "GL: OpenGL 3.3 Core profile not supported");
-        #endif
-    #endif
-
-    // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
-    //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object
 #endif
 }
 
@@ -1991,7 +1998,7 @@ RenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
         batch.vertexBuffer[i].cCounter = 0;
     }
 
-    TRACELOG(LOG_INFO, "RLGL: Internal vertex buffers initialized successfully in RAM (CPU)");
+    TRACELOG(LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)");
     //--------------------------------------------------------------------------------------------
 
     // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs
@@ -2038,7 +2045,7 @@ RenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
 #endif
     }
 
-    TRACELOG(LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully");
+    TRACELOG(LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)");
 
     // Unbind the current VAO
     if (RLGL.ExtSupported.vao) glBindVertexArray(0);
@@ -2480,7 +2487,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
     // Unbind current texture
     glBindTexture(GL_TEXTURE_2D, 0);
 
-    if (id > 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Texture created successfully (%ix%i - %i mipmaps)", id, width, height, mipmapCount);
+    if (id > 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Texture loaded successfully (%ix%i - %i mipmaps)", id, width, height, mipmapCount);
     else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load texture");
 
     return id;
@@ -2611,7 +2618,7 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
     glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
 #endif
 
-    if (id > 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Cubemap texture created successfully (%ix%i)", id, size, size);
+    if (id > 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Cubemap texture loaded successfully (%ix%i)", id, size, size);
     else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load cubemap texture");
 
     return id;
@@ -3245,7 +3252,14 @@ unsigned int rlCompileShader(const char *shaderCode, int type)
 
     if (success == GL_FALSE)
     {
-        TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to compile shader code", shader);
+        switch (type)
+        {
+            case GL_VERTEX_SHADER: TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break;
+            case GL_FRAGMENT_SHADER: TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break;
+            //case GL_GEOMETRY_SHADER:
+            //case GL_COMPUTE_SHADER:
+            default: break;
+        }
 
         int maxLength = 0;
         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
@@ -3259,7 +3273,17 @@ unsigned int rlCompileShader(const char *shaderCode, int type)
             RL_FREE(log);
         }
     }
-    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Compiled successfully", shader);
+    else
+    {
+        switch (type)
+        {
+            case GL_VERTEX_SHADER: TRACELOG(LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break;
+            case GL_FRAGMENT_SHADER: TRACELOG(LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break;
+            //case GL_GEOMETRY_SHADER:
+            //case GL_COMPUTE_SHADER:
+            default: break;
+        }
+    }
 #endif
 
     return shader;
@@ -3313,7 +3337,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
 
         program = 0;
     }
-    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Program loaded successfully", program);
+    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program);
 #endif
     return program;
 }
@@ -3777,7 +3801,91 @@ static void rlUnloadShaderDefault(void)
     glDeleteProgram(RLGL.State.defaultShader.id);
 
     RL_FREE(RLGL.State.defaultShader.locs);
+    
+    TRACELOG(LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShader.id);
 }
+
+#if defined(SUPPORT_GL_DETAILS_INFO)
+// Get compressed format official GL identifier name
+static char *rlGetCompressedFormatName(int format)
+{
+    static char compName[64] = { 0 };
+    memset(compName, 0, 64);
+    
+    switch (format)
+    {
+        // GL_EXT_texture_compression_s3tc
+        case 0x83F0: strcpy(compName, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"); break;
+        case 0x83F1: strcpy(compName, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"); break;
+        case 0x83F2: strcpy(compName, "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"); break;
+        case 0x83F3: strcpy(compName, "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"); break;
+        // GL_3DFX_texture_compression_FXT1
+        case 0x86B0: strcpy(compName, "GL_COMPRESSED_RGB_FXT1_3DFX"); break;
+        case 0x86B1: strcpy(compName, "GL_COMPRESSED_RGBA_FXT1_3DFX"); break;
+        // GL_IMG_texture_compression_pvrtc
+        case 0x8C00: strcpy(compName, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"); break;
+        case 0x8C01: strcpy(compName, "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"); break;
+        case 0x8C02: strcpy(compName, "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"); break;
+        case 0x8C03: strcpy(compName, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"); break;
+        // GL_OES_compressed_ETC1_RGB8_texture
+        case 0x8D64: strcpy(compName, "GL_ETC1_RGB8_OES"); break;
+        // GL_ARB_texture_compression_rgtc
+        case 0x8DBB: strcpy(compName, "GL_COMPRESSED_RED_RGTC1"); break;
+        case 0x8DBC: strcpy(compName, "GL_COMPRESSED_SIGNED_RED_RGTC1"); break;
+        case 0x8DBD: strcpy(compName, "GL_COMPRESSED_RG_RGTC2"); break;
+        case 0x8DBE: strcpy(compName, "GL_COMPRESSED_SIGNED_RG_RGTC2"); break;
+        // GL_ARB_texture_compression_bptc
+        case 0x8E8C: strcpy(compName, "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"); break;
+        case 0x8E8D: strcpy(compName, "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"); break;
+        case 0x8E8E: strcpy(compName, "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"); break;
+        case 0x8E8F: strcpy(compName, "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"); break;
+        // GL_ARB_ES3_compatibility
+        case 0x9274: strcpy(compName, "GL_COMPRESSED_RGB8_ETC2"); break;
+        case 0x9275: strcpy(compName, "GL_COMPRESSED_SRGB8_ETC2"); break;
+        case 0x9276: strcpy(compName, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"); break;
+        case 0x9277: strcpy(compName, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"); break;
+        case 0x9278: strcpy(compName, "GL_COMPRESSED_RGBA8_ETC2_EAC"); break;
+        case 0x9279: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"); break;
+        case 0x9270: strcpy(compName, "GL_COMPRESSED_R11_EAC"); break;
+        case 0x9271: strcpy(compName, "GL_COMPRESSED_SIGNED_R11_EAC"); break;
+        case 0x9272: strcpy(compName, "GL_COMPRESSED_RG11_EAC"); break;
+        case 0x9273: strcpy(compName, "GL_COMPRESSED_SIGNED_RG11_EAC"); break;
+        // GL_KHR_texture_compression_astc_hdr
+        case 0x93B0: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"); break;  
+        case 0x93B1: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"); break;  
+        case 0x93B2: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"); break;  
+        case 0x93B3: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"); break;  
+        case 0x93B4: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"); break;  
+        case 0x93B5: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"); break;  
+        case 0x93B6: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"); break;  
+        case 0x93B7: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"); break;  
+        case 0x93B8: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"); break;
+        case 0x93B9: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"); break;
+        case 0x93BA: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"); break;
+        case 0x93BB: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"); break;
+        case 0x93BC: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"); break;
+        case 0x93BD: strcpy(compName, "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"); break;
+        case 0x93D0: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"); break;  
+        case 0x93D1: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"); break;  
+        case 0x93D2: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"); break;  
+        case 0x93D3: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"); break;  
+        case 0x93D4: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"); break;  
+        case 0x93D5: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"); break;  
+        case 0x93D6: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"); break;  
+        case 0x93D7: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"); break;  
+        case 0x93D8: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"); break;  
+        case 0x93D9: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"); break;  
+        case 0x93DA: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"); break;  
+        case 0x93DB: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"); break;  
+        case 0x93DC: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"); break;  
+        case 0x93DD: strcpy(compName, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"); break;  
+        default: strcpy(compName, "GL_COMPRESSED_UNKNOWN"); break;    
+    }
+    
+    return compName;
+}
+#endif  // SUPPORT_GL_DETAILS_INFO
+
 #endif  // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
 
 #if defined(GRAPHICS_API_OPENGL_11)