瀏覽代碼

Added support for emscripten and more

Added PLATFORM_WEB support (emscripten-webgl)
[audio] Added LoadSoundFromWave()
[textures] Added LoadTextureFromImage() to replace CreateTexture()
Some TraceLogs edited...
raysan5 10 年之前
父節點
當前提交
cfa60ab7e6
共有 9 個文件被更改,包括 199 次插入95 次删除
  1. 54 9
      src/audio.c
  2. 36 19
      src/core.c
  3. 10 9
      src/makefile
  4. 16 3
      src/raylib.h
  5. 11 5
      src/rlgl.c
  6. 1 1
      src/rlgl.h
  7. 4 4
      src/text.c
  8. 65 45
      src/textures.c
  9. 2 0
      src/utils.c

+ 54 - 9
src/audio.c

@@ -69,15 +69,6 @@ typedef struct Music {
 
 } Music;
 
-// Wave file data
-typedef struct Wave {
-    void *data;                 // Buffer data pointer
-    unsigned int dataSize;      // Data size in bytes
-    unsigned int sampleRate;
-    short bitsPerSample;
-    short channels;
-} Wave;
-
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 //----------------------------------------------------------------------------------
@@ -219,6 +210,60 @@ Sound LoadSound(char *fileName)
     return sound;
 }
 
+// Load sound from wave data
+Sound LoadSoundFromWave(Wave wave)
+{
+    Sound sound;
+
+    if (wave.data != NULL)
+    {
+        ALenum format = 0;
+        // The OpenAL format is worked out by looking at the number of channels and the bits per sample
+        if (wave.channels == 1)
+        {
+            if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
+            else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
+        }
+        else if (wave.channels == 2)
+        {
+            if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
+            else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
+        }
+
+        // Create an audio source
+        ALuint source;
+        alGenSources(1, &source);            // Generate pointer to audio source
+
+        alSourcef(source, AL_PITCH, 1);
+        alSourcef(source, AL_GAIN, 1);
+        alSource3f(source, AL_POSITION, 0, 0, 0);
+        alSource3f(source, AL_VELOCITY, 0, 0, 0);
+        alSourcei(source, AL_LOOPING, AL_FALSE);
+
+        // Convert loaded data to OpenAL buffer
+        //----------------------------------------
+        ALuint buffer;
+        alGenBuffers(1, &buffer);            // Generate pointer to buffer
+
+        // Upload sound data to buffer
+        alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
+
+        // Attach sound buffer to source
+        alSourcei(source, AL_BUFFER, buffer);
+
+        // Unallocate WAV data
+        UnloadWave(wave);
+
+        TraceLog(INFO, "[Wave] Sound file loaded successfully");
+        TraceLog(INFO, "[Wave] Sample rate: %i - Channels: %i", wave.sampleRate, wave.channels);
+
+        sound.source = source;
+        sound.buffer = buffer;
+    }
+
+    return sound;
+}
+
 // Load sound to memory from rRES file (raylib Resource)
 Sound LoadSoundFromRES(const char *rresName, int resId)
 {

+ 36 - 19
src/core.c

@@ -8,6 +8,7 @@
 *       PLATFORM_DESKTOP - Windows, Linux, Mac (OSX)
 *       PLATFORM_ANDROID - Only OpenGL ES 2.0 devices
 *       PLATFORM_RPI - Rapsberry Pi (tested on Raspbian)
+*       PLATFORM_WEB - Emscripten, HTML5
 *
 *   On PLATFORM_DESKTOP, the external lib GLFW3 (www.glfw.com) is used to manage graphic
 *   device, OpenGL context and input on multiple operating systems (Windows, Linux, OSX).
@@ -49,7 +50,7 @@
 #include <string.h>         // String function definitions, memset()
 #include <errno.h>          // Macros for reporting and retrieving error conditions through error codes
 
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     #include <GLFW/glfw3.h>     // GLFW3 library: Windows, OpenGL context and Input management
     //#include <GL/gl.h>        // OpenGL functions (GLFW3 already includes gl.h)
     //#define GLFW_DLL          // Using GLFW DLL on Windows -> No, we use static version!
@@ -101,7 +102,7 @@
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 //----------------------------------------------------------------------------------
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
 static GLFWwindow *window;                      // Native window (graphic device)
 #elif defined(PLATFORM_ANDROID)
 static struct android_app *app;                 // Android activity
@@ -160,7 +161,7 @@ static int renderOffsetY = 0;               // Offset Y from render area (must b
 static bool fullscreen = false;             // Fullscreen mode (useful only for PLATFORM_DESKTOP)
 static Matrix downscaleView;                // Matrix to downscale view (in case screen size bigger than display size)
 
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 static const char *windowTitle;             // Window text title...
 static char configFlags = 0;
 
@@ -226,12 +227,15 @@ static void RestoreKeyboard(void);                      // Restore keyboard syst
 static void InitGamepad(void);                          // Init raw gamepad input
 #endif
 
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
 static void ErrorCallback(int error, const char *description);                             // GLFW3 Error Callback, runs on GLFW3 error
 static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods);  // GLFW3 Keyboard Callback, runs on key pressed
 static void ScrollCallback(GLFWwindow *window, double xoffset, double yoffset);            // GLFW3 Srolling Callback, runs on mouse wheel
 static void CursorEnterCallback(GLFWwindow *window, int enter);                            // GLFW3 Cursor Enter Callback, cursor enters client area
 static void WindowSizeCallback(GLFWwindow *window, int width, int height);                 // GLFW3 WindowSize Callback, runs when window is resized
+#endif
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
 static void TakeScreenshot(void);                                                          // Takes a screenshot and saves it in the same folder as executable
 #endif
 
@@ -243,7 +247,7 @@ static void CommandCallback(struct android_app *app, int32_t cmd);           //
 //----------------------------------------------------------------------------------
 // Module Functions Definition - Window and OpenGL Context Functions
 //----------------------------------------------------------------------------------
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 // Initialize Window and Graphics Context (OpenGL)
 void InitWindow(int width, int height, const char *title)
 {
@@ -348,7 +352,7 @@ void CloseWindow(void)
 
     rlglClose();                // De-init rlgl
 
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     glfwDestroyWindow(window);
     glfwTerminate();
 #elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@@ -380,7 +384,7 @@ void CloseWindow(void)
 // Detect if KEY_ESCAPE pressed or Close icon pressed
 bool WindowShouldClose(void)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     return (glfwWindowShouldClose(window));
 #elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
     return windowShouldClose;
@@ -402,7 +406,7 @@ void ToggleFullscreen(void)
 #endif
 }
 
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 // Set a custom cursor icon/image
 void SetCustomCursor(const char *cursorImage)
 {
@@ -411,6 +415,7 @@ void SetCustomCursor(const char *cursorImage)
     cursor = LoadTexture(cursorImage);
 
 #if defined(PLATFORM_DESKTOP)
+	// NOTE: emscripten not implemented
     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
 #endif
     customCursor = true;
@@ -612,7 +617,7 @@ void ShowLogo(void)
 //----------------------------------------------------------------------------------
 // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
 //----------------------------------------------------------------------------------
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 // Detect if a key has been pressed once
 bool IsKeyPressed(int key)
 {
@@ -731,7 +736,8 @@ Vector2 GetMousePosition(void)
 void SetMousePosition(Vector2 position)
 {
     mousePosition = position;
-#if defined(PLATFORM_DESKTOP)    
+#if defined(PLATFORM_DESKTOP)
+	// NOTE: emscripten not implemented
     glfwSetCursorPos(window, position.x, position.y);
 #endif
 }
@@ -747,7 +753,8 @@ int GetMouseWheelMove(void)
 }
 #endif
 
-// TODO: Enable gamepad usage on Rapsberr Pi
+// TODO: Enable gamepad usage on Rapsberry Pi
+// NOTE: emscripten not implemented
 #if defined(PLATFORM_DESKTOP)
 // Detect if a gamepad is available
 bool IsGamepadAvailable(int gamepad)
@@ -890,11 +897,13 @@ static void InitDisplay(int width, int height)
     // Downscale matrix is required in case desired screen area is bigger than display area
     downscaleView = MatrixIdentity();
 
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     glfwSetErrorCallback(ErrorCallback);
 
     if (!glfwInit()) TraceLog(ERROR, "Failed to initialize GLFW");
 
+    // NOTE: Getting video modes is not implemented in emscripten GLFW3 version
+#if defined(PLATFORM_DESKTOP)
     // Find monitor resolution
     const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
 
@@ -904,7 +913,11 @@ static void InitDisplay(int width, int height)
     // Screen size security check
     if (screenWidth <= 0) screenWidth = displayWidth;
     if (screenHeight <= 0) screenHeight = displayHeight;
-
+#elif defined(PLATFORM_WEB)
+    displayWidth = screenWidth;
+    displayHeight = screenHeight;
+#endif
+    
     glfwDefaultWindowHints();                     // Set default windows hints
 
     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);     // Avoid window being resizable
@@ -953,7 +966,9 @@ static void InitDisplay(int width, int height)
     else
     {
         TraceLog(INFO, "Display device initialized successfully");
+#if defined(PLATFORM_DESKTOP)
         TraceLog(INFO, "Display size: %i x %i", displayWidth, displayHeight);
+#endif
         TraceLog(INFO, "Render size: %i x %i", renderWidth, renderHeight);
         TraceLog(INFO, "Screen size: %i x %i", screenWidth, screenHeight);
         TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
@@ -1125,7 +1140,7 @@ void InitGraphics(void)
 #endif
 }
 
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
 // GLFW3 Error Callback, runs on GLFW3 error
 static void ErrorCallback(int error, const char *description)
 {
@@ -1147,10 +1162,12 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
 
         // NOTE: Before closing window, while loop must be left!
     }
+#if defined(PLATFORM_DESKTOP)
     else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
     {
         TakeScreenshot();
     }
+#endif
 }
 
 // GLFW3 CursorEnter Callback, when cursor enters the window
@@ -1395,7 +1412,7 @@ static void InitTimer(void)
 // Get current time measure since InitTimer()
 static double GetTime(void)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     return glfwGetTime();
 #elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
     struct timespec ts;
@@ -1409,7 +1426,7 @@ static double GetTime(void)
 // Get one key state
 static bool GetKeyStatus(int key)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     return glfwGetKey(window, key);
 #elif defined(PLATFORM_ANDROID)
     // TODO: Check virtual keyboard (?)
@@ -1424,7 +1441,7 @@ static bool GetKeyStatus(int key)
 // Get one mouse button state
 static bool GetMouseButtonStatus(int button)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     return glfwGetMouseButton(window, button);
 #elif defined(PLATFORM_ANDROID)
     // TODO: Check virtual keyboard (?)
@@ -1438,7 +1455,7 @@ static bool GetMouseButtonStatus(int button)
 // Poll (store) all input events
 static void PollInputEvents(void)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     // Mouse input polling
     double mouseX;
     double mouseY;
@@ -1732,7 +1749,7 @@ static void InitGamepad(void)
 // Copy back buffer to front buffers
 static void SwapBuffers(void)
 {
-#if defined(PLATFORM_DESKTOP)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
     glfwSwapBuffers(window);
 #elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
     eglSwapBuffers(display, surface);

+ 10 - 9
src/makefile

@@ -25,7 +25,7 @@
 
 # define raylib platform (by default, compile for RPI)
 # Other possible platforms: PLATFORM_DESKTOP_WIN PLATFORM_DESKTOP_LINUX PLATFORM_WEB
-PLATFORM ?= PLATFORM_RPI
+PLATFORM ?= PLATFORM_DESKTOP
 
 # define raylib graphics api depending on selected platform
 ifeq ($(PLATFORM),PLATFORM_RPI)
@@ -37,6 +37,10 @@ else
     #GRAPHICS = GRAPHICS_API_OPENGL_33  # Uncomment to use OpenGL 3.3
 endif
 
+ifeq ($(PLATFORM),PLATFORM_WEB)
+    GRAPHICS = GRAPHICS_API_OPENGL_ES2
+endif
+
 # NOTE: makefiles targets require tab indentation
 
 # define compiler: gcc for C program, define as g++ for C++
@@ -52,15 +56,12 @@ endif
 #  -O2         defines optimization level
 #  -Wall       turns on most, but not all, compiler warnings
 #  -std=c99    use standard C from 1999 revision
-ifeq ($(PLATFORM),PLATFORM_WEB)
-    CFLAGS = -O3 -s USE_GLFW=3 -s LEGACY_GL_EMULATION=1
-else
 ifeq ($(PLATFORM),PLATFORM_RPI)
-    CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
+    CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
 else
-    CFLAGS = -O2 -Wall -std=c99
-endif
+    CFLAGS = -O1 -Wall -std=c99
 endif
+
 #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
 
 # define any directories containing required header files
@@ -80,7 +81,7 @@ default: raylib
 # compile raylib library
 raylib: $(OBJS)
 ifeq ($(PLATFORM),PLATFORM_WEB)
-	emcc $(OBJS) -o raylib.bc
+	emcc -O1 $(OBJS) -o raylib.bc
 else
 	ar rcs libraylib.a $(OBJS)
 endif
@@ -92,7 +93,7 @@ core.o: core.c
 
 # compile rlgl module
 rlgl.o: rlgl.c
-	$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(GRAPHICS)
+	$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
 
 # compile raymath module
 raymath.o: raymath.c

+ 16 - 3
src/raylib.h

@@ -65,7 +65,7 @@
 //#define PLATFORM_RPI          // Raspberry Pi
 
 // Security check in case no PLATFORM_* defined
-#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI)
+#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
     #define PLATFORM_DESKTOP
 #endif
 
@@ -275,6 +275,15 @@ typedef struct Sound {
     unsigned int buffer;
 } Sound;
 
+// Wave type, defines audio wave data
+typedef struct Wave {
+    void *data;                 // Buffer data pointer
+    unsigned int dataSize;      // Data size in bytes
+    unsigned int sampleRate;
+    short bitsPerSample;
+    short channels;
+} Wave;
+
 #ifdef __cplusplus
 extern "C" {            // Prevents name mangling of functions
 #endif
@@ -327,7 +336,7 @@ void ShowLogo(void);                                        // Activates raylib
 //------------------------------------------------------------------------------------
 // Input Handling Functions (Module: core)
 //------------------------------------------------------------------------------------
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 bool IsKeyPressed(int key);                             // Detect if a key has been pressed once
 bool IsKeyDown(int key);                                // Detect if a key is being pressed
 bool IsKeyReleased(int key);                            // Detect if a key has been released once
@@ -342,7 +351,9 @@ int GetMouseY(void);                                    // Returns mouse positio
 Vector2 GetMousePosition(void);                         // Returns mouse position XY
 void SetMousePosition(Vector2 position);                // Set mouse position XY
 int GetMouseWheelMove(void);                            // Returns mouse wheel movement Y
+#endif
 
+#if defined(PLATFORM_DESKTOP)
 bool IsGamepadAvailable(int gamepad);                   // Detect if a gamepad is available
 Vector2 GetGamepadMovement(int gamepad);                // Return axis movement vector for a gamepad
 bool IsGamepadButtonPressed(int gamepad, int button);   // Detect if a gamepad button has been pressed once
@@ -395,7 +406,8 @@ Image LoadImage(const char *fileName);
 Image LoadImageFromRES(const char *rresName, int resId);                                           // Load an image from rRES file (raylib Resource)
 Texture2D LoadTexture(const char *fileName);                                                       // Load an image as texture into GPU memory
 Texture2D LoadTextureFromRES(const char *rresName, int resId);                                     // Load an image as texture from rRES file (raylib Resource)
-Texture2D CreateTexture(Image image, bool genMipmaps);                                             // Create a Texture2D from Image data (and generate mipmaps)
+Texture2D LoadTextureFromImage(Image image, bool genMipmaps);                                      // Load a texture from image data (and generate mipmaps)
+Texture2D CreateTexture(Image image, bool genMipmaps);                                             // [DEPRECATED] Same as LoadTextureFromImage()
 void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory
 
@@ -465,6 +477,7 @@ void InitAudioDevice(void);                                     // Initialize au
 void CloseAudioDevice(void);                                    // Close the audio device and context (and music stream)
 
 Sound LoadSound(char *fileName);                                // Load sound to memory
+Sound LoadSoundFromWave(Wave wave);                             // Load sound from wave data
 Sound LoadSoundFromRES(const char *rresName, int resId);        // Load sound to memory from rRES file (raylib Resource)
 void UnloadSound(Sound sound);                                  // Unload sound
 void PlaySound(Sound sound);                                    // Play a sound

+ 11 - 5
src/rlgl.c

@@ -177,6 +177,7 @@ static bool vaoSupported = false;
 
 #if defined(GRAPHICS_API_OPENGL_ES2)
 // NOTE: VAO functionality is exposed through extensions (OES)
+// emscripten does not support VAOs
 static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
 static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
 static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
@@ -764,10 +765,13 @@ void rlglInit(void)
 #endif
 
 #if defined(GRAPHICS_API_OPENGL_ES2)
+	// NOTE: emscripten does not support VAOs
+#if !defined(PLATFORM_WEB)
     glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
     glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
     glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES");
     glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
+#endif
 
     if (glGenVertexArrays == NULL) TraceLog(WARNING, "Could not initialize VAO extensions, VAOs not supported");
     else
@@ -852,8 +856,8 @@ void rlglInit(void)
 
     whiteTexture = rlglLoadTexture(pixels, 1, 1, false);
 
-    if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture created successfully", whiteTexture);
-    else TraceLog(WARNING, "Base white texture could not be created");
+    if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
+    else TraceLog(WARNING, "Base white texture could not be loaded");
 
     // Init draw calls tracking system
     draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
@@ -1352,7 +1356,7 @@ Model rlglLoadModel(VertexData mesh)
 #elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     model.textureId = 1;        // Default whiteTexture
 
-    GLuint vaoModel;            // Vertex Array Objects (VAO)
+    GLuint vaoModel = 0;        // Vertex Array Objects (VAO)
     GLuint vertexBuffer[3];     // Vertex Buffer Objects (VBO)
 
     if (vaoSupported)
@@ -1804,7 +1808,7 @@ static void InitializeBuffersGPU(void)
         glGenVertexArrays(1, &vaoTriangles);
         glBindVertexArray(vaoTriangles);
     }
-
+    
     // Create buffers for our vertex data
     glGenBuffers(2, trianglesBuffer);
 
@@ -1829,7 +1833,7 @@ static void InitializeBuffersGPU(void)
         glGenVertexArrays(1, &vaoQuads);
         glBindVertexArray(vaoQuads);
     }
-
+    
     // Create buffers for our vertex data
     glGenBuffers(4, quadsBuffer);
 
@@ -1865,6 +1869,8 @@ static void InitializeBuffersGPU(void)
 }
 
 // Update VBOs with vertex array data
+// TODO: 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 every frame!
 static void UpdateBuffers(void)
 {
     // Activate Lines VAO

+ 1 - 1
src/rlgl.h

@@ -45,7 +45,7 @@
 // Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
 //#define GRAPHICS_API_OPENGL_11     // Only available on PLATFORM_DESKTOP
 //#define GRAPHICS_API_OPENGL_33     // Only available on PLATFORM_DESKTOP
-//#define GRAPHICS_API_OPENGL_ES2    // Only available on PLATFORM_ANDROID or PLATFORM_RPI
+//#define GRAPHICS_API_OPENGL_ES2    // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
 
 // Security check in case no GRAPHICS_API_OPENGL_* defined
 #if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)

+ 4 - 4
src/text.c

@@ -135,7 +135,7 @@ extern void LoadDefaultFont(void)
         if (counter > 256) counter = 0;         // Security check...
     }
 
-    defaultFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
+    defaultFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
     UnloadImage(image);
 
     // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
@@ -168,7 +168,7 @@ extern void LoadDefaultFont(void)
         else currentPosX = testPosX;
     }
 
-    TraceLog(INFO, "Default font loaded successfully");
+    TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
 }
 
 extern void UnloadDefaultFont(void)
@@ -240,7 +240,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
             image.height = potHeight;
         }
 */
-        spriteFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
+        spriteFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
         UnloadImage(image);
     }
 
@@ -566,7 +566,7 @@ static SpriteFont LoadRBMF(const char *fileName)
 
     TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
 
-    spriteFont.texture = CreateTexture(image, false);
+    spriteFont.texture = LoadTextureFromImage(image, false);
     UnloadImage(image);     // Unload image data
 
     TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);

+ 65 - 45
src/textures.c

@@ -175,8 +175,6 @@ Image LoadImage(const char *fileName)
 // Load an image from rRES file (raylib Resource)
 Image LoadImageFromRES(const char *rresName, int resId)
 {
-    // TODO: rresName could be directly a char array with all the data! --> support it! :P
-
     Image image;
     bool found = false;
 
@@ -295,6 +293,11 @@ Image LoadImageFromRES(const char *rresName, int resId)
 Texture2D LoadTexture(const char *fileName)
 {
     Texture2D texture;
+    
+    // Init texture to default values
+    texture.id = 0;
+    texture.width = 0;
+    texture.height = 0;
 
     if (strcmp(GetExtension(fileName),"dds") == 0)
     {
@@ -337,7 +340,7 @@ Texture2D LoadTexture(const char *fileName)
 
         if (image.pixels != NULL)
         {
-            texture = CreateTexture(image, false);
+            texture = LoadTextureFromImage(image, false);
             UnloadImage(image);
         }
     }
@@ -345,13 +348,66 @@ Texture2D LoadTexture(const char *fileName)
     return texture;
 }
 
+// Load a texture from image data
+// NOTE: image is not unloaded, it must be done manually
+Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
+{
+    Texture2D texture;
+
+    // Init texture to default values
+    texture.id = 0;
+    texture.width = 0;
+    texture.height = 0;
+
+    if (image.pixels != NULL)
+    {
+        unsigned char *imgData = malloc(image.width * image.height * 4);
+
+        int j = 0;
+
+        for (int i = 0; i < image.width * image.height * 4; i += 4)
+        {
+            imgData[i] = image.pixels[j].r;
+            imgData[i+1] = image.pixels[j].g;
+            imgData[i+2] = image.pixels[j].b;
+            imgData[i+3] = image.pixels[j].a;
+
+            j++;
+        }
+
+        // NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
+        texture.id = rlglLoadTexture(imgData, image.width, image.height, genMipmaps);
+
+        texture.width = image.width;
+        texture.height = image.height;
+
+        free(imgData);
+    }
+    else TraceLog(WARNING, "Texture could not be created, image data is not valid");
+
+    return texture;
+}
+
+// [DEPRECATED] Load a texture from image data
+// NOTE: Use LoadTextureFromImage() instead
+Texture2D CreateTexture(Image image, bool genMipmaps)
+{
+    Texture2D texture;
+    
+    texture = LoadTextureFromImage(image, genMipmaps);
+    
+    TraceLog(INFO, "Created texture id: %i", texture.id);
+
+    return texture;
+}
+
 // Load an image as texture from rRES file (raylib Resource)
 Texture2D LoadTextureFromRES(const char *rresName, int resId)
 {
     Texture2D texture;
 
     Image image = LoadImageFromRES(rresName, resId);
-    texture = CreateTexture(image, false);
+    texture = LoadTextureFromImage(image, false);
     UnloadImage(image);
 
     return texture;
@@ -436,49 +492,13 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
     rlDisableTexture();
 }
 
-// Create a texture from an image
-// NOTE: image is not unloaded, iot must be done manually
-Texture2D CreateTexture(Image image, bool genMipmaps)
-{
-    Texture2D texture;
-
-    // Init texture to default values
-    texture.id = 0;
-    texture.width = 0;
-    texture.height = 0;
-
-    if (image.pixels != NULL)
-    {
-        unsigned char *imgData = malloc(image.width * image.height * 4);
-
-        int j = 0;
-
-        for (int i = 0; i < image.width * image.height * 4; i += 4)
-        {
-            imgData[i] = image.pixels[j].r;
-            imgData[i+1] = image.pixels[j].g;
-            imgData[i+2] = image.pixels[j].b;
-            imgData[i+3] = image.pixels[j].a;
-
-            j++;
-        }
-
-        // NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
-        texture.id = rlglLoadTexture(imgData, image.width, image.height, genMipmaps);
-
-        texture.width = image.width;
-        texture.height = image.height;
-
-        free(imgData);
-    }
-    else TraceLog(WARNING, "Texture could not be created, image data is not valid");
-
-    return texture;
-}
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
 
 // Loading DDS image data (compressed or uncompressed)
 // NOTE: Compressed data loading not supported on OpenGL 1.1
-ImageEx LoadDDS(const char *fileName)
+static ImageEx LoadDDS(const char *fileName)
 {
     #define FOURCC_DXT1 0x31545844  // Equivalent to "DXT1" in ASCII
     #define FOURCC_DXT3 0x33545844  // Equivalent to "DXT3" in ASCII
@@ -636,7 +656,7 @@ ImageEx LoadDDS(const char *fileName)
 // Loading PKM image data (ETC1/ETC2 compression)
 // NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps)
 // PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
-ImageEx LoadPKM(const char *fileName)
+static ImageEx LoadPKM(const char *fileName)
 {
     // If OpenGL ES 2.0. the following format could be supported (ETC1):
     //GL_ETC1_RGB8_OES

+ 2 - 0
src/utils.c

@@ -157,7 +157,9 @@ void WritePNG(const char *fileName, unsigned char *imgData, int width, int heigh
 {
     stbi_write_png(fileName, width, height, 4, imgData, width*4); // It WORKS!!!
 }
+#endif
 
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 // Outputs a trace log message (INFO, ERROR, WARNING)
 // NOTE: If a file has been init, output log is written there
 void TraceLog(int msgType, const char *text, ...)