From e94acf86f8125edfb6534a45c86493be298fea68 Mon Sep 17 00:00:00 2001
From: raysan5 <raysan5@gmail.com>
Date: Tue, 3 May 2016 17:54:50 +0200
Subject: [PATCH 1/4] Reorganized internal funcs

---
 src/text.c | 98 +++++++++++++++++++++++-------------------------------
 1 file changed, 41 insertions(+), 57 deletions(-)

diff --git a/src/text.c b/src/text.c
index f89d5e4ea..7bb06f442 100644
--- a/src/text.c
+++ b/src/text.c
@@ -69,8 +69,7 @@ static SpriteFont defaultFont;        // Default font provided by raylib
 //----------------------------------------------------------------------------------
 // Module specific Functions Declaration
 //----------------------------------------------------------------------------------
-static bool PixelIsMagenta(Color p);                // Check if a pixel is magenta
-static int ParseImageData(Image image, int **charValues, Rectangle **charSet);    // Parse image pixel data to obtain characters data
+static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
 static SpriteFont LoadRBMF(const char *fileName);   // Load a rBMF font file (raylib BitMap Font)
 static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
 static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required)
@@ -210,7 +209,7 @@ extern void LoadDefaultFont(void)
         if (testPosX >= defaultFont.texture.width)
         {
             currentLine++;
-            currentPosX = 2 * charsDivisor + charsWidth[i];
+            currentPosX = 2*charsDivisor + charsWidth[i];
             testPosX = currentPosX;
 
             defaultFont.charRecs[i].x = charsDivisor;
@@ -246,7 +245,7 @@ SpriteFont GetDefaultFont()
 // Load a SpriteFont image into GPU memory
 SpriteFont LoadSpriteFont(const char *fileName)
 {
-    SpriteFont spriteFont;
+    SpriteFont spriteFont = { 0 };
 
     // Check file extension
     if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
@@ -255,36 +254,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
     else
     {
         Image image = LoadImage(fileName);
-        
-        if (image.data != NULL)
-        {     
-            // Process bitmap font pixel data to get characters measures
-            // spriteFont chars data is filled inside the function and memory is allocated!
-            int numChars = ParseImageData(image, &spriteFont.charValues, &spriteFont.charRecs);
-
-            TraceLog(DEBUG, "[%s] SpriteFont data parsed correctly", fileName);
-            TraceLog(DEBUG, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
-
-            spriteFont.numChars = numChars;
-            spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
-            spriteFont.size = spriteFont.charRecs[0].height;
-            
-            spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2));
-            spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int));
-            
-            for (int i = 0; i < spriteFont.numChars; i++)
-            {
-                // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
-                spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f };
-                spriteFont.charAdvanceX[i] = 0;
-            }
-        }
-        else
-        {
-            TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName);
-            spriteFont = GetDefaultFont();
-        }
-
+        if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, 32);
         UnloadImage(image);
     }
     
@@ -309,7 +279,7 @@ void UnloadSpriteFont(SpriteFont spriteFont)
         free(spriteFont.charOffsets);
         free(spriteFont.charAdvanceX);
 
-        TraceLog(INFO, "Unloaded sprite font data");
+        TraceLog(DEBUG, "Unloaded sprite font data");
     }
 }
 
@@ -517,15 +487,11 @@ void DrawFPS(int posX, int posY)
 // Module specific Functions Definition
 //----------------------------------------------------------------------------------
 
-// Check if a pixel is magenta
-static bool PixelIsMagenta(Color p)
-{
-    return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255));
-}
-
-// Parse image pixel data to obtain characters data (measures)
-static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
+// Load a Image font file (XNA style)
+static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
 {
+    #define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
+    
     int charSpacing = 0;
     int lineSpacing = 0;
 
@@ -539,13 +505,14 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
     
     Color *pixels = GetImageData(image);
 
+    // Parse image data to get charSpacing and lineSpacing
     for(y = 0; y < image.height; y++)
     {
         for(x = 0; x < image.width; x++)
         {
-            if (!PixelIsMagenta(pixels[y*image.width + x])) break;
+            if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
         }
-        if (!PixelIsMagenta(pixels[y*image.width + x])) break;
+        if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
     }
 
     charSpacing = x;
@@ -554,7 +521,7 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
     int charHeight = 0;
     int j = 0;
 
-    while(!PixelIsMagenta(pixels[(lineSpacing + j)*image.width + charSpacing])) j++;
+    while(!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++;
 
     charHeight = j;
 
@@ -563,12 +530,13 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
     int lineToRead = 0;
     int xPosToRead = charSpacing;
 
+    // Parse image data to get rectangle sizes
     while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height)
     {
         while((xPosToRead < image.width) &&
-              !PixelIsMagenta((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead])))
+              !COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key))
         {
-            tempCharValues[index] = FONT_FIRST_CHAR + index;
+            tempCharValues[index] = firstChar + index;
             
             tempCharRecs[index].x = xPosToRead;
             tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
@@ -576,7 +544,7 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
 
             int charWidth = 0;
 
-            while(!PixelIsMagenta(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth])) charWidth++;
+            while(!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++;
 
             tempCharRecs[index].width = charWidth;
 
@@ -590,20 +558,35 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs)
     }
     
     free(pixels);
+    
+    TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
+    
+    // Create spritefont with all data parsed from image
+    SpriteFont spriteFont = { 0 };
+    
+    spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
+    spriteFont.numChars = index;
 
     // We got tempCharValues and tempCharsRecs populated with chars data
-    // Now we move temp data to sized charValues and charRecs arrays (passed as parameter to the function)
-    // NOTE: This memory should be freed!
-    (*charRecs) = (Rectangle *)malloc(index*sizeof(Rectangle));
-    (*charValues) = (int *)malloc(index*sizeof(int));
+    // Now we move temp data to sized charValues and charRecs arrays
+    spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle));
+    spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int));
+    spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2));
+    spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int));
 
-    for (int i = 0; i < index; i++)
+    for (int i = 0; i < spriteFont.numChars; i++)
     {
-        (*charValues)[i] = tempCharValues[i];
-        (*charRecs)[i] = tempCharRecs[i];
+        spriteFont.charValues[i] = tempCharValues[i];
+        spriteFont.charRecs[i] = tempCharRecs[i];
+        
+        // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
+        spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f };
+        spriteFont.charAdvanceX[i] = 0;
     }
+    
+    spriteFont.size = spriteFont.charRecs[0].height;
 
-    return index;
+    return spriteFont;
 }
 
 // Load a rBMF font file (raylib BitMap Font)
@@ -687,6 +670,7 @@ static SpriteFont LoadRBMF(const char *fileName)
 
         TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
 
+        // Create spritefont with all data read from rbmf file
         spriteFont.texture = LoadTextureFromImage(image);
         UnloadImage(image);     // Unload image data
 

From 5f73850fa675530d6933d85a6d80684106beff69 Mon Sep 17 00:00:00 2001
From: raysan5 <raysan5@gmail.com>
Date: Tue, 3 May 2016 18:04:21 +0200
Subject: [PATCH 2/4] Renamed functions for consistency

---
 src/audio.c  | 4 ++--
 src/audio.h  | 4 ++--
 src/raylib.h | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/audio.c b/src/audio.c
index 39d1ee8b0..09c917854 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -585,7 +585,7 @@ void StopSound(Sound sound)
 }
 
 // Check if a sound is playing
-bool SoundIsPlaying(Sound sound)
+bool IsSoundPlaying(Sound sound)
 {
     bool playing = false;
     ALint state;
@@ -764,7 +764,7 @@ void ResumeMusicStream(void)
 }
 
 // Check if music is playing
-bool MusicIsPlaying(void)
+bool IsMusicPlaying(void)
 {
     bool playing = false;
     ALint state;
diff --git a/src/audio.h b/src/audio.h
index 9c681044b..73f60ab1c 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -96,7 +96,7 @@ void UnloadSound(Sound sound);                                  // Unload sound
 void PlaySound(Sound sound);                                    // Play a sound
 void PauseSound(Sound sound);                                   // Pause a sound
 void StopSound(Sound sound);                                    // Stop playing a sound
-bool SoundIsPlaying(Sound sound);                               // Check if a sound is currently playing
+bool IsSoundPlaying(Sound sound);                               // Check if a sound is currently playing
 void SetSoundVolume(Sound sound, float volume);                 // Set volume for a sound (1.0 is max level)
 void SetSoundPitch(Sound sound, float pitch);                   // Set pitch for a sound (1.0 is base level)
 
@@ -105,7 +105,7 @@ void UpdateMusicStream(void);                                   // Updates buffe
 void StopMusicStream(void);                                     // Stop music playing (close stream)
 void PauseMusicStream(void);                                    // Pause music playing
 void ResumeMusicStream(void);                                   // Resume playing paused music
-bool MusicIsPlaying(void);                                      // Check if music is playing
+bool IsMusicPlaying(void);                                      // Check if music is playing
 void SetMusicVolume(float volume);                              // Set volume for music (1.0 is max level)
 float GetMusicTimeLength(void);                                 // Get music time length (in seconds)
 float GetMusicTimePlayed(void);                                 // Get current music time played (in seconds)
diff --git a/src/raylib.h b/src/raylib.h
index 337b98134..bc98181b2 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -882,7 +882,7 @@ void UnloadSound(Sound sound);                                  // Unload sound
 void PlaySound(Sound sound);                                    // Play a sound
 void PauseSound(Sound sound);                                   // Pause a sound
 void StopSound(Sound sound);                                    // Stop playing a sound
-bool SoundIsPlaying(Sound sound);                               // Check if a sound is currently playing
+bool IsSoundPlaying(Sound sound);                               // Check if a sound is currently playing
 void SetSoundVolume(Sound sound, float volume);                 // Set volume for a sound (1.0 is max level)
 void SetSoundPitch(Sound sound, float pitch);                   // Set pitch for a sound (1.0 is base level)
 
@@ -891,7 +891,7 @@ void UpdateMusicStream(void);                                   // Updates buffe
 void StopMusicStream(void);                                     // Stop music playing (close stream)
 void PauseMusicStream(void);                                    // Pause music playing
 void ResumeMusicStream(void);                                   // Resume playing paused music
-bool MusicIsPlaying(void);                                      // Check if music is playing
+bool IsMusicPlaying(void);                                      // Check if music is playing
 void SetMusicVolume(float volume);                              // Set volume for music (1.0 is max level)
 float GetMusicTimeLength(void);                                 // Get current music time length (in seconds)
 float GetMusicTimePlayed(void);                                 // Get current music time played (in seconds)

From 8301980ba8f917dd445b346332c48ec3b2447511 Mon Sep 17 00:00:00 2001
From: raysan5 <raysan5@gmail.com>
Date: Tue, 3 May 2016 19:20:25 +0200
Subject: [PATCH 3/4] Clean up and consistency review

- Renamed some functions for consistency (default buffers)
- Removed mystrdup() function (implemented inline)
- Renamed TextFileRead() to ReadTextFile()
---
 src/rlgl.c | 299 +++++++++++++++++++++++++++--------------------------
 src/rlgl.h |  16 +--
 2 files changed, 158 insertions(+), 157 deletions(-)

diff --git a/src/rlgl.c b/src/rlgl.c
index e021e7260..9112e47e2 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -196,23 +196,20 @@ static DrawMode currentDrawMode;
 
 static float currentDepth = -1.0f;
 
-// Vertex arrays for lines, triangles and quads
+// Default vertex buffers for lines, triangles and quads
 static VertexPositionColorBuffer lines;         // No texture support
 static VertexPositionColorBuffer triangles;     // No texture support
 static VertexPositionColorTextureIndexBuffer quads;
 
-// Shader Programs
-static Shader defaultShader;
-static Shader currentShader;                    // By default, defaultShader
-
-// Vertex Array Objects (VAO)
+// Default vertex buffers VAOs (if supported)
 static GLuint vaoLines, vaoTriangles, vaoQuads;
 
-// Vertex Buffer Objects (VBO)
-static GLuint linesBuffer[2];
-static GLuint trianglesBuffer[2];
-static GLuint quadsBuffer[4];
+// Default vertex buffers VBOs
+static GLuint linesBuffer[2];           // Lines buffers (position, color)
+static GLuint trianglesBuffer[2];       // Triangles buffers (position, color)
+static GLuint quadsBuffer[4];           // Quads buffers (position, texcoord, color, index)
 
+// Default buffers draw calls
 static DrawCall *draws;
 static int drawsCounter;
 
@@ -221,11 +218,14 @@ static Vector3 *tempBuffer;
 static int tempBufferCount = 0;
 static bool useTempBuffer = false;
 
+// Shader Programs
+static Shader defaultShader;
+static Shader currentShader;            // By default, defaultShader
+
 // Flags for supported extensions
 static bool vaoSupported = false;   // VAO support (OpenGL ES2 could not support VAO extension)
 
 // Compressed textures support flags
-//static bool texCompDXTSupported = false;     // DDS texture compression support
 static bool texCompETC1Supported = false;    // ETC1 texture compression support
 static bool texCompETC2Supported = false;    // ETC2/EAC texture compression support
 static bool texCompPVRTSupported = false;    // PVR texture compression support
@@ -233,8 +233,8 @@ static bool texCompASTCSupported = false;    // ASTC texture compression support
 #endif
 
 // Compressed textures support flags
-static bool texCompDXTSupported = false;   // DDS texture compression support
-static bool npotSupported = false;         // NPOT textures full support
+static bool texCompDXTSupported = false;     // DDS texture compression support
+static bool npotSupported = false;           // NPOT textures full support
 
 #if defined(GRAPHICS_API_OPENGL_ES2)
 // NOTE: VAO functionality is exposed through extensions (OES)
@@ -254,14 +254,17 @@ unsigned int whiteTexture;
 // Module specific Functions Declaration
 //----------------------------------------------------------------------------------
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat);
+
 static Shader LoadDefaultShader(void);
 static void LoadDefaultShaderLocations(Shader *shader);
-static void InitializeBuffers(void);
-static void InitializeBuffersGPU(void);
-static void UpdateBuffers(void);
-static char *TextFileRead(char *fn);
+static void UnloadDefaultShader(void);
 
-static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat);
+static void LoadDefaultBuffers(void);
+static void UpdateDefaultBuffers(void);
+static void UnloadDefaultBuffers(void);
+
+static char *ReadTextFile(const char *fileName);
 #endif
 
 #if defined(GRAPHICS_API_OPENGL_11)
@@ -274,20 +277,6 @@ static void TraceLog(int msgType, const char *text, ...);
 float *MatrixToFloat(Matrix mat);   // Converts Matrix to float array
 #endif
 
-#if defined(GRAPHICS_API_OPENGL_ES2)
-// NOTE: strdup() functions replacement (not C99, POSIX function, not available on emscripten)
-// Duplicates a string, returning an identical malloc'd string
-char *mystrdup(const char *str)
-{
-  size_t len = strlen(str) + 1;
-  void *newstr = malloc(len);
-
-  if (newstr == NULL) return NULL;
-
-  return (char *)memcpy(newstr, str, len);
-}
-#endif
-
 //----------------------------------------------------------------------------------
 // Module Functions Definition - Matrix operations
 //----------------------------------------------------------------------------------
@@ -919,13 +908,18 @@ void rlglInit(void)
     
     // NOTE: We have to duplicate string because glGetString() returns a const value
     // If not duplicated, it fails in some systems (Raspberry Pi)
-    char *extensionsDup = mystrdup(extensions);
+    // Equivalent to function: char *strdup(const char *str)
+    char *extensionsDup;
+    size_t len = strlen(extensions) + 1;
+    void *newstr = malloc(len);
+    if (newstr == NULL) extensionsDup = NULL;
+    extensionsDup = (char *)memcpy(newstr, extensions, len);
     
     // NOTE: String could be splitted using strtok() function (string.h)
     // NOTE: strtok() modifies the received string, it can not be const
     
     char *extList[512];     // Allocate 512 strings pointers (2 KB)
-
+    
     extList[numExt] = strtok(extensionsDup, " ");
 
     while (extList[numExt] != NULL)
@@ -1024,12 +1018,9 @@ void rlglInit(void)
 
     // Init default Shader (customized for GL 3.3 and ES2)
     defaultShader = LoadDefaultShader();
-    //customShader = LoadShader("custom.vs", "custom.fs");     // Works ok
-    
     currentShader = defaultShader;
 
-    InitializeBuffers();        // Init vertex arrays
-    InitializeBuffersGPU();     // Init VBO and VAO
+    LoadDefaultBuffers();        // Initialize default vertex arrays buffers (lines, triangles, quads)
 
     // Init temp vertex buffer, used when transformation required (translate, rotate, scale)
     tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE);
@@ -1054,54 +1045,10 @@ void rlglInit(void)
 void rlglClose(void)
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    // Unbind everything
-    if (vaoSupported) glBindVertexArray(0);
-    glDisableVertexAttribArray(0);
-    glDisableVertexAttribArray(1);
-    glDisableVertexAttribArray(2);
-    glDisableVertexAttribArray(3);
-    glBindBuffer(GL_ARRAY_BUFFER, 0);
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-    glUseProgram(0);
-
-    // Delete VBOs
-    glDeleteBuffers(1, &linesBuffer[0]);
-    glDeleteBuffers(1, &linesBuffer[1]);
-    glDeleteBuffers(1, &trianglesBuffer[0]);
-    glDeleteBuffers(1, &trianglesBuffer[1]);
-    glDeleteBuffers(1, &quadsBuffer[0]);
-    glDeleteBuffers(1, &quadsBuffer[1]);
-    glDeleteBuffers(1, &quadsBuffer[2]);
-    glDeleteBuffers(1, &quadsBuffer[3]);
-
-    if (vaoSupported)
-    {
-        // Delete VAOs
-        glDeleteVertexArrays(1, &vaoLines);
-        glDeleteVertexArrays(1, &vaoTriangles);
-        glDeleteVertexArrays(1, &vaoQuads);
-    }
-
-    //glDetachShader(defaultShaderProgram, vertexShader);
-    //glDetachShader(defaultShaderProgram, fragmentShader);
-    //glDeleteShader(vertexShader);     // Already deleted on shader compilation
-    //glDeleteShader(fragmentShader);   // Already deleted on sahder compilation
-    glDeleteProgram(defaultShader.id);
-
-    // Free vertex arrays memory
-    free(lines.vertices);
-    free(lines.colors);
-
-    free(triangles.vertices);
-    free(triangles.colors);
-
-    free(quads.vertices);
-    free(quads.texcoords);
-    free(quads.colors);
-    free(quads.indices);
-
-    // Free GPU texture
+    UnloadDefaultShader();
+    UnloadDefaultBuffers();
+    
+    // Delete default white texture
     glDeleteTextures(1, &whiteTexture);
     TraceLog(INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", whiteTexture);
 
@@ -1113,7 +1060,7 @@ void rlglClose(void)
 void rlglDraw(void)
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    UpdateBuffers();
+    UpdateDefaultBuffers();
 
     if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0))
     {
@@ -1846,7 +1793,9 @@ void rlglGenerateMipmaps(Texture2D texture)
         // NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
         free(data);
         
-#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+#endif
+
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
         glGenerateMipmap(GL_TEXTURE_2D);    // Generate mipmaps automatically
         TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture.id);
 
@@ -2116,8 +2065,8 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
 
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     // Shaders loading from external text file
-    char *vShaderStr = TextFileRead(vsFileName);
-    char *fShaderStr = TextFileRead(fsFileName);
+    char *vShaderStr = ReadTextFile(vsFileName);
+    char *fShaderStr = ReadTextFile(fsFileName);
     
     if ((vShaderStr != NULL) && (fShaderStr != NULL))
     {
@@ -2418,7 +2367,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in
     }
 }
 
-// Load Shader (Vertex and Fragment)
+// Load default shader (Vertex and Fragment)
 // NOTE: This shader program is used for batch buffers (lines, triangles, quads)
 static Shader LoadDefaultShader(void)
 {
@@ -2503,43 +2452,24 @@ static void LoadDefaultShaderLocations(Shader *shader)
     shader->mapSpecularLoc = glGetUniformLocation(shader->id, "texture2");
 }
 
-// Read text file
-// NOTE: text chars array should be freed manually
-static char *TextFileRead(char *fileName)
+// Unload default shader 
+static void UnloadDefaultShader(void)
 {
-    FILE *textFile;
-    char *text = NULL;
-
-    int count = 0;
-
-    if (fileName != NULL)
-    {
-        textFile = fopen(fileName,"rt");
-
-        if (textFile != NULL)
-        {
-            fseek(textFile, 0, SEEK_END);
-            count = ftell(textFile);
-            rewind(textFile);
-
-            if (count > 0)
-            {
-                text = (char *)malloc(sizeof(char)*(count + 1));
-                count = fread(text, sizeof(char), count, textFile);
-                text[count] = '\0';
-            }
-
-            fclose(textFile);
-        }
-        else TraceLog(WARNING, "[%s] Text file could not be opened", fileName);
-    }
+    glUseProgram(0);
 
-    return text;
+    //glDetachShader(defaultShaderProgram, vertexShader);
+    //glDetachShader(defaultShaderProgram, fragmentShader);
+    //glDeleteShader(vertexShader);     // Already deleted on shader compilation
+    //glDeleteShader(fragmentShader);   // Already deleted on sahder compilation
+    glDeleteProgram(defaultShader.id);
 }
 
-// Allocate and initialize float array buffers to store vertex data (lines, triangles, quads)
-static void InitializeBuffers(void)
+// Load default internal buffers (lines, triangles, quads)
+static void LoadDefaultBuffers(void)
 {
+    // [CPU] Allocate and initialize float array buffers to store vertex data (lines, triangles, quads)
+    //--------------------------------------------------------------------------------------------
+    
     // Initialize lines arrays (vertex position and color data)
     lines.vertices = (float *)malloc(sizeof(float)*3*2*MAX_LINES_BATCH);        // 3 float by vertex, 2 vertex by line
     lines.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*2*MAX_LINES_BATCH);  // 4 float by color, 2 colors by line
@@ -2593,13 +2523,14 @@ static void InitializeBuffers(void)
     quads.tcCounter = 0;
     quads.cCounter = 0;
 
-    TraceLog(INFO, "CPU buffers (lines, triangles, quads) initialized successfully");
-}
-
-// Initialize Vertex Array Objects (Contain VBO)
-// NOTE: lines, triangles and quads buffers use currentShader
-static void InitializeBuffersGPU(void)
-{
+    TraceLog(INFO, "Default buffers initialized successfully in CPU (lines, triangles, quads)");
+    //--------------------------------------------------------------------------------------------
+    
+    // [GPU] Upload vertex data and initialize VAOs/VBOs (lines, triangles, quads)
+    // NOTE: Default buffers are linked to use currentShader (defaultShader)
+    //--------------------------------------------------------------------------------------------
+    
+    // Upload and link lines vertex buffers
     if (vaoSupported)
     {
         // Initialize Lines VAO
@@ -2622,10 +2553,10 @@ static void InitializeBuffersGPU(void)
     glEnableVertexAttribArray(currentShader.colorLoc);
     glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
 
-    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Lines VAO initialized successfully", vaoLines);
-    else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Lines VBOs initialized successfully", linesBuffer[0], linesBuffer[1]);
-    //--------------------------------------------------------------
+    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (lines) VAO initialized successfully", vaoLines);
+    else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers (lines) VBOs initialized successfully", linesBuffer[0], linesBuffer[1]);
 
+    // Upload and link triangles vertex buffers
     if (vaoSupported)
     {
         // Initialize Triangles VAO
@@ -2647,10 +2578,10 @@ static void InitializeBuffersGPU(void)
     glEnableVertexAttribArray(currentShader.colorLoc);
     glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
 
-    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Triangles VAO initialized successfully", vaoTriangles);
-    else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Triangles VBOs initialized successfully", trianglesBuffer[0], trianglesBuffer[1]);
-    //--------------------------------------------------------------
+    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (triangles) VAO initialized successfully", vaoTriangles);
+    else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers (triangles) VBOs initialized successfully", trianglesBuffer[0], trianglesBuffer[1]);
 
+    // Upload and link quads vertex buffers
     if (vaoSupported)
     {
         // Initialize Quads VAO
@@ -2685,18 +2616,20 @@ static void InitializeBuffersGPU(void)
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short)*6*MAX_QUADS_BATCH, quads.indices, GL_STATIC_DRAW);
 #endif
 
-    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Quads VAO initialized successfully", vaoQuads);
-    else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i][VBO ID %i] Quads VBOs initialized successfully", quadsBuffer[0], quadsBuffer[1], quadsBuffer[2], quadsBuffer[3]);
+    if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (quads) VAO initialized successfully", vaoQuads);
+    else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i][VBO ID %i] Default buffers (quads) VBOs initialized successfully", quadsBuffer[0], quadsBuffer[1], quadsBuffer[2], quadsBuffer[3]);
 
     // Unbind the current VAO
     if (vaoSupported) glBindVertexArray(0);
+    //--------------------------------------------------------------------------------------------
 }
 
-// Update VBOs with vertex array data
+// Update default buffers (VAOs/VBOs) with vertex array data
 // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
-// TODO: If no data changed on the CPU arrays --> No need to update GPU arrays (change flag required)
-static void UpdateBuffers(void)
+// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required)
+static void UpdateDefaultBuffers(void)
 {
+    // Update lines vertex buffers
     if (lines.vCounter > 0)
     {
         // Activate Lines VAO
@@ -2712,8 +2645,8 @@ static void UpdateBuffers(void)
         //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW);
         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*lines.cCounter, lines.colors);
     }
-    //--------------------------------------------------------------
 
+    // Update triangles vertex buffers
     if (triangles.vCounter > 0)
     {
         // Activate Triangles VAO
@@ -2729,8 +2662,8 @@ static void UpdateBuffers(void)
         //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*triangles.cCounter, triangles.colors);
     }
-    //--------------------------------------------------------------
 
+    // Update quads vertex buffers
     if (quads.vCounter > 0)
     {
         // Activate Quads VAO
@@ -2752,7 +2685,7 @@ static void UpdateBuffers(void)
         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*quads.vCounter, quads.colors);
 
         // Another option would be using buffer mapping...
-        //triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
+        //quads.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
         // Now we can modify vertices
         //glUnmapBuffer(GL_ARRAY_BUFFER);
     }
@@ -2761,6 +2694,83 @@ static void UpdateBuffers(void)
     // Unbind the current VAO
     if (vaoSupported) glBindVertexArray(0);
 }
+
+// Unload default buffers vertex data from CPU and GPU
+static void UnloadDefaultBuffers(void)
+{
+    // Unbind everything
+    if (vaoSupported) glBindVertexArray(0);
+    glDisableVertexAttribArray(0);
+    glDisableVertexAttribArray(1);
+    glDisableVertexAttribArray(2);
+    glDisableVertexAttribArray(3);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    // Delete VBOs from GPU (VRAM)
+    glDeleteBuffers(1, &linesBuffer[0]);
+    glDeleteBuffers(1, &linesBuffer[1]);
+    glDeleteBuffers(1, &trianglesBuffer[0]);
+    glDeleteBuffers(1, &trianglesBuffer[1]);
+    glDeleteBuffers(1, &quadsBuffer[0]);
+    glDeleteBuffers(1, &quadsBuffer[1]);
+    glDeleteBuffers(1, &quadsBuffer[2]);
+    glDeleteBuffers(1, &quadsBuffer[3]);
+
+    if (vaoSupported)
+    {
+        // Delete VAOs from GPU (VRAM)
+        glDeleteVertexArrays(1, &vaoLines);
+        glDeleteVertexArrays(1, &vaoTriangles);
+        glDeleteVertexArrays(1, &vaoQuads);
+    }
+
+    // Free vertex arrays memory from CPU (RAM)
+    free(lines.vertices);
+    free(lines.colors);
+
+    free(triangles.vertices);
+    free(triangles.colors);
+
+    free(quads.vertices);
+    free(quads.texcoords);
+    free(quads.colors);
+    free(quads.indices);
+}
+
+// Read text data from file
+// NOTE: text chars array should be freed manually
+static char *ReadTextFile(const char *fileName)
+{
+    FILE *textFile;
+    char *text = NULL;
+
+    int count = 0;
+
+    if (fileName != NULL)
+    {
+        textFile = fopen(fileName,"rt");
+
+        if (textFile != NULL)
+        {
+            fseek(textFile, 0, SEEK_END);
+            count = ftell(textFile);
+            rewind(textFile);
+
+            if (count > 0)
+            {
+                text = (char *)malloc(sizeof(char)*(count + 1));
+                count = fread(text, sizeof(char), count, textFile);
+                text[count] = '\0';
+            }
+
+            fclose(textFile);
+        }
+        else TraceLog(WARNING, "[%s] Text file could not be opened", fileName);
+    }
+
+    return text;
+}
 #endif //defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
 
 #if defined(GRAPHICS_API_OPENGL_11)
@@ -2891,7 +2901,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
 #endif
 
 #if defined(RLGL_STANDALONE)
-
 // Output a trace log message
 // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
 static void TraceLog(int msgType, const char *text, ...)
diff --git a/src/rlgl.h b/src/rlgl.h
index 714961e11..cd8e6d1db 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -292,11 +292,6 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view);    // Get world
 unsigned char *rlglReadScreenPixels(int width, int height);         // Read screen pixel data (color buffer)
 void *rlglReadTexturePixels(Texture2D texture);                     // Read texture pixel data
 
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-void PrintProjectionMatrix(void);       // DEBUG: Print projection matrix
-void PrintModelviewMatrix(void);        // DEBUG: Print modelview matrix
-#endif
-
 #if defined(RLGL_STANDALONE)
 //------------------------------------------------------------------------------------
 // Shaders System Functions (Module: rlgl)
@@ -309,13 +304,10 @@ void SetCustomShader(Shader shader);                                // Set custo
 void SetDefaultShader(void);                                        // Set default shader to be used in batch draw
 void SetModelShader(Model *model, Shader shader);                   // Link a shader to a model
 
-int GetShaderLocation(Shader shader, const char *uniformName);                          // Get shader uniform location
-void SetShaderValue(Shader shader, int uniformLoc, float *value, int size);             // Set shader uniform value (float)
-void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size);              // Set shader uniform value (int)
-void SetShaderMapDiffuse(Shader *shader, Texture2D texture);                            // Default diffuse shader map texture assignment
-void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture);    // Normal map texture shader assignment
-void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture);  // Specular map texture shader assignment
-void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
+int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location
+void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
+void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size);  // Set shader uniform value (int)
+void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);       // Set shader uniform value (matrix 4x4)
 
 void SetBlendMode(int mode);                                        // Set blending mode (alpha, additive, multiplied)
 #endif

From fd67e31f630476980eb09e49177958703db5b3d3 Mon Sep 17 00:00:00 2001
From: raysan5 <raysan5@gmail.com>
Date: Tue, 3 May 2016 19:27:06 +0200
Subject: [PATCH 4/4] Renamed function for consistency

---
 examples/core_world_screen.c | 2 +-
 src/core.c                   | 4 ++--
 src/raylib.h                 | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/examples/core_world_screen.c b/examples/core_world_screen.c
index d89a296bf..f3798830d 100644
--- a/examples/core_world_screen.c
+++ b/examples/core_world_screen.c
@@ -43,7 +43,7 @@ int main()
         UpdateCamera(&camera);          // Update internal camera and our camera
         
         // Calculate cube screen space position (with a little offset to be in top)
-        cubeScreenPosition = WorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
+        cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
         //----------------------------------------------------------------------------------
 
         // Draw
diff --git a/src/core.c b/src/core.c
index b27712a72..669010f95 100644
--- a/src/core.c
+++ b/src/core.c
@@ -905,7 +905,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
     Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
 
 #else   // OPTION 2: Compute unprojection directly here
-    
+
     // Calculate unproject matrix (multiply projection matrix and view matrix) and invert it
     Matrix matProjView = MatrixMultiply(matProj, matView);
     MatrixInvert(&matProjView);
@@ -935,7 +935,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
 }
 
 // Returns the screen space position from a 3d world space position
-Vector2 WorldToScreen(Vector3 position, Camera camera)
+Vector2 GetWorldToScreen(Vector3 position, Camera camera)
 {    
     // Calculate projection matrix (from perspective instead of frustum
     Matrix matProj = MatrixPerspective(camera.fovy, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
diff --git a/src/raylib.h b/src/raylib.h
index bc98181b2..8af7d2fb8 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -586,7 +586,7 @@ void BeginTextureMode(RenderTexture2D target);              // Initializes rende
 void EndTextureMode(void);                                  // Ends drawing to render texture
 
 Ray GetMouseRay(Vector2 mousePosition, Camera camera);      // Returns a ray trace from mouse position
-Vector2 WorldToScreen(Vector3 position, Camera camera);     // Returns the screen space position from a 3d world space position
+Vector2 GetWorldToScreen(Vector3 position, Camera camera);  // Returns the screen space position from a 3d world space position
 Matrix GetCameraMatrix(Camera camera);                      // Returns camera transform matrix (view matrix)
 
 void SetTargetFPS(int fps);                                 // Set target FPS (maximum)