Просмотр исходного кода

Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop

victorfisac 9 лет назад
Родитель
Сommit
c453ac8265

+ 6 - 3
examples/core_3d_camera_first_person.c

@@ -74,10 +74,13 @@ int main()
                 }
 
             End3dMode();
+            
+            DrawRectangle( 10, 10, 220, 70, Fade(SKYBLUE, 0.5f));
+            DrawRectangleLines( 10, 10, 220, 70, BLUE);
 
-            DrawText("First person camera default controls:", 20, 20, 10, GRAY);
-            DrawText("- Move with keys: W, A, S, D", 40, 50, 10, DARKGRAY);
-            DrawText("- Mouse move to look around", 40, 70, 10, DARKGRAY);
+            DrawText("First person camera default controls:", 20, 20, 10, BLACK);
+            DrawText("- Move with keys: W, A, S, D", 40, 40, 10, DARKGRAY);
+            DrawText("- Mouse move to look around", 40, 60, 10, DARKGRAY);
 
         EndDrawing();
         //----------------------------------------------------------------------------------

BIN
examples/core_3d_camera_first_person.png


+ 10 - 7
examples/core_3d_camera_free.c

@@ -59,13 +59,16 @@ int main()
                 DrawGrid(10, 1.0f);
 
             End3dMode();
-
-            DrawText("Free camera default controls:", 20, 20, 10, GRAY);
-            DrawText("- Mouse Wheel to Zoom in-out", 40, 50, 10, DARKGRAY);
-            DrawText("- Mouse Wheel Pressed to Pan", 40, 70, 10, DARKGRAY);
-            DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 90, 10, DARKGRAY);
-            DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 110, 10, DARKGRAY);
-            DrawText("- Z to zoom to (0, 0, 0)", 40, 130, 10, DARKGRAY);
+            
+            DrawRectangle( 10, 10, 320, 133, Fade(SKYBLUE, 0.5f));
+            DrawRectangleLines( 10, 10, 320, 133, BLUE);
+            
+            DrawText("Free camera default controls:", 20, 20, 10, BLACK);
+            DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, DARKGRAY);
+            DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, DARKGRAY);
+            DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, DARKGRAY);
+            DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, DARKGRAY);
+            DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, DARKGRAY);
 
         EndDrawing();
         //----------------------------------------------------------------------------------

BIN
examples/core_3d_camera_free.png


+ 1 - 1
examples/core_3d_picking.c

@@ -77,7 +77,7 @@ int main()
 
             End3dMode();
             
-            DrawText("Try selecting the box with mouse!", 240, 10, 20, GRAY);
+            DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY);
             
             if(collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN);
 

BIN
examples/shapes_basic_shapes.png


BIN
examples/textures_srcrec_dstrec.png


+ 91 - 84
src/core.c

@@ -116,9 +116,9 @@
 
 #if defined(PLATFORM_RPI)
     // Old device inputs system
-    #define DEFAULT_KEYBOARD_DEV      STDIN_FILENO            // Standard input
-    #define DEFAULT_MOUSE_DEV         "/dev/input/mouse0"
-    #define DEFAULT_GAMEPAD_DEV       "/dev/input/js0"
+    #define DEFAULT_KEYBOARD_DEV      STDIN_FILENO              // Standard input
+    #define DEFAULT_MOUSE_DEV         "/dev/input/mouse0"       // Mouse input
+    #define DEFAULT_GAMEPAD_DEV       "/dev/input/js"           // Gamepad input (base dev for all gamepads: js0, js1, ...)
 
     // New device input events (evdev) (must be detected)
     //#define DEFAULT_KEYBOARD_DEV    "/dev/input/eventN"
@@ -126,7 +126,10 @@
     //#define DEFAULT_GAMEPAD_DEV     "/dev/input/eventN"
     
     #define MOUSE_SENSITIVITY         0.8f
-    #define MAX_GAMEPAD_BUTTONS       11
+    
+    #define MAX_GAMEPADS              2         // Max number of gamepads supported
+    #define MAX_GAMEPAD_BUTTONS       11        // Max bumber of buttons supported (per gamepad)
+    #define MAX_GAMEPAD_AXIS          8         // Max number of axis supported (per gamepad)
 #endif
 
 //----------------------------------------------------------------------------------
@@ -143,10 +146,12 @@ static bool windowMinimized = false;
 #elif defined(PLATFORM_ANDROID)
 static struct android_app *app;                 // Android activity
 static struct android_poll_source *source;      // Android events polling source
-static int ident, events;
+static int ident, events;                       // Android ALooper_pollAll() variables
+
 static bool windowReady = false;                // Used to detect display initialization
 static bool appEnabled = true;                  // Used to detec if app is active
 static bool contextRebindRequired = false;      // Used to know context rebind required
+
 static int previousButtonState[128] = { 1 };    // Required to check if button pressed/released once
 static int currentButtonState[128] = { 1 };     // Required to check if button pressed/released once
 #elif defined(PLATFORM_RPI)
@@ -163,13 +168,12 @@ static bool mouseReady = false;                 // Flag to know if mouse is read
 pthread_t mouseThreadId;                        // Mouse reading thread id
 
 // Gamepad input variables
-static int gamepadStream = -1;                  // Gamepad device file descriptor
-static bool gamepadReady = false;               // Flag to know if gamepad is ready
-pthread_t gamepadThreadId;                      // Gamepad reading thread id
+static int gamepadStream[MAX_GAMEPADS] = { -1 };    // Gamepad device file descriptor (two gamepads supported)
+static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready (two gamepads supported)
+pthread_t gamepadThreadId;                          // Gamepad reading thread id
 
-int gamepadButtons[MAX_GAMEPAD_BUTTONS];
-int gamepadAxisX = 0;
-int gamepadAxisY = 0;
+int gamepadButtons[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS];        // Gamepad buttons state
+float gamepadAxisValues[MAX_GAMEPADS][MAX_GAMEPAD_AXIS];      // Gamepad axis state
 #endif
 
 #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@@ -191,9 +195,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_ANDROID) || defined(PLATFORM_WEB)
 static Vector2 touchPosition[MAX_TOUCH_POINTS];     // Touch position on screen
-#endif
 
 #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
 static const char *windowTitle;             // Window text title...
@@ -401,13 +403,6 @@ void InitWindow(int width, int height, struct android_app *state)
 
     TraceLog(INFO, "Android app initialized successfully");
 
-    // Init button states values (default up)
-    for(int i = 0; i < 128; i++)
-    {
-        currentButtonState[i] = 1;
-        previousButtonState[i] = 1;
-    }
-
     // Wait for window to be initialized (display and context)
     while (!windowReady)
     {
@@ -641,6 +636,8 @@ void Begin3dMode(Camera camera)
     // Setup Camera view
     Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
     rlMultMatrixf(MatrixToFloat(matView));      // Multiply MODELVIEW matrix by view matrix (camera)
+    
+    rlEnableDepthTest();                // Enable DEPTH_TEST for 3D
 }
 
 // Ends 3D mode and returns to default 2D orthographic mode
@@ -655,6 +652,8 @@ void End3dMode(void)
     rlLoadIdentity();                   // Reset current matrix (MODELVIEW)
 
     //rlTranslatef(0.375, 0.375, 0);      // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
+    
+    rlDisableDepthTest();               // Disable DEPTH_TEST for 2D
 }
 
 // Set target FPS for the game
@@ -1168,7 +1167,7 @@ bool IsGamepadAvailable(int gamepad)
     bool result = false;
     
 #if defined(PLATFORM_RPI)
-    if (gamepadReady && (gamepad == 0)) result = true;
+    if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
 #else
     if (glfwJoystickPresent(gamepad) == 1) result = true;
 #endif
@@ -1177,30 +1176,25 @@ bool IsGamepadAvailable(int gamepad)
 }
 
 // Return axis movement vector for a gamepad
-Vector2 GetGamepadMovement(int gamepad)
+float GetGamepadAxisMovement(int gamepad, int axis)
 {
-    Vector2 vec = { 0, 0 };
-
-    const float *axes;
-    int axisCount = 0;
+    float value = 0;
     
 #if defined(PLATFORM_RPI)
-    // TODO: Get gamepad axis information
-    // Use gamepadAxisX, gamepadAxisY
+    if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad])
+    {
+        if (axis < MAX_GAMEPAD_AXIS) value = gamepadAxisValues[gamepad][axis];
+    }
 #else
+    const float *axes;
+    int axisCount = 0;
+    
     axes = glfwGetJoystickAxes(gamepad, &axisCount);
-#endif
     
-    if (axisCount >= 2)
-    {
-        vec.x = axes[0];    // Left joystick X
-        vec.y = axes[1];    // Left joystick Y
-
-        //vec.x = axes[2];    // Right joystick X
-        //vec.x = axes[3];    // Right joystick Y
-    }
+    if (axis < axisCount) value = axes[axis];
+#endif
 
-    return vec;
+    return value;
 }
 
 // Detect if a gamepad button has been pressed once
@@ -1227,7 +1221,7 @@ bool IsGamepadButtonDown(int gamepad, int button)
     
 #if defined(PLATFORM_RPI)
     // Get gamepad buttons information
-    if ((gamepad == 0) && (gamepadButtons[button] == 1)) result = true;
+    if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 1)) result = true;
     else result = false;
 #else
     const unsigned char *buttons;
@@ -1266,7 +1260,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
 
 #if defined(PLATFORM_RPI)
     // Get gamepad buttons information
-    if ((gamepad == 0) && (gamepadButtons[button] == 0)) result = true;
+    if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 0)) result = true;
     else result = false;
 #else
     const unsigned char *buttons;
@@ -1487,11 +1481,11 @@ static void InitDisplay(int width, int height)
         TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
     }
 
-    glfwSetWindowSizeCallback(window, WindowSizeCallback);
+    glfwSetWindowSizeCallback(window, WindowSizeCallback);      // NOTE: Resizing not allowed by default!
     glfwSetCursorEnterCallback(window, CursorEnterCallback);
     glfwSetKeyCallback(window, KeyCallback);
     glfwSetMouseButtonCallback(window, MouseButtonCallback);
-    glfwSetCursorPosCallback(window, MouseCursorPosCallback);    // Track mouse position changes
+    glfwSetCursorPosCallback(window, MouseCursorPosCallback);   // Track mouse position changes
     glfwSetCharCallback(window, CharCallback);
     glfwSetScrollCallback(window, ScrollCallback);
     glfwSetWindowIconifyCallback(window, WindowIconifyCallback);
@@ -1785,6 +1779,9 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
     GestureEvent gestureEvent;
 
     gestureEvent.touchAction = TOUCH_MOVE;
+    
+    // Assign a pointer ID
+    gestureEvent.pointerId[0] = 0;
 
     // Register touch points count
     gestureEvent.pointCount = 1;
@@ -1792,6 +1789,8 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
     // Register touch points position, only one point registered
     gestureEvent.position[0] = (Vector2){ (float)x, (float)y };
     
+    touchPosition[0] = gestureEvent.position[0];
+    
     // Normalize gestureEvent.position[0] for screenWidth and screenHeight
     gestureEvent.position[0].x /= (float)GetScreenWidth(); 
     gestureEvent.position[0].y /= (float)GetScreenHeight();
@@ -1817,16 +1816,19 @@ static void CursorEnterCallback(GLFWwindow *window, int enter)
 }
 
 // GLFW3 WindowSize Callback, runs when window is resized
+// NOTE: Window resizing not allowed by default
 static void WindowSizeCallback(GLFWwindow *window, int width, int height)
 {
     // If window is resized, graphics device is re-initialized (but only ortho mode)
-    rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight);
+    rlglInitGraphics(0, 0, width, height);
 
     // Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
-    //screenWidth = width;
-    //screenHeight = height;
-
-    // TODO: Update render size?
+    screenWidth = width;
+    screenHeight = height;
+    renderWidth = width;
+    renderHeight = height;
+    
+    // NOTE: Postprocessing texture is not scaled to new size
 
     // Background must be also re-cleared
     ClearBackground(RAYWHITE);
@@ -2455,19 +2457,31 @@ static void *MouseThread(void *arg)
 // Init gamepad system
 static void InitGamepad(void)
 {
-    if ((gamepadStream = open(DEFAULT_GAMEPAD_DEV, O_RDONLY|O_NONBLOCK)) < 0) 
-    {
-        TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available");
-    }
-    else
+    char gamepadDev[128] = "";
+            
+    for (int i = 0; i < MAX_GAMEPADS; i++)
     {
-        gamepadReady = true;
+        sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
+        
+        if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0) 
+        {
+            // NOTE: Only show message for first gamepad
+            if (i == 0) TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available");
+        }
+        else
+        {
+            gamepadReady[i] = true;
 
-        int error = pthread_create(&gamepadThreadId, NULL, &GamepadThread, NULL);
+            // NOTE: Only create one thread
+            if (i == 0)
+            {
+                int error = pthread_create(&gamepadThreadId, NULL, &GamepadThread, NULL);
 
-        if (error != 0) TraceLog(WARNING, "Error creating gamepad input event thread");
-        else  TraceLog(INFO, "Gamepad device initialized successfully");
-    }
+                if (error != 0) TraceLog(WARNING, "Error creating gamepad input event thread");
+                else  TraceLog(INFO, "Gamepad device initialized successfully");
+            }
+        }
+    }       
 }
 
 // Process Gamepad (/dev/input/js0)
@@ -2484,45 +2498,38 @@ static void *GamepadThread(void *arg)
         unsigned char number;   // event axis/button number
     };
 
-    // These values are sensible on Logitech Dual Action Rumble and Xbox360 controller
-    const int joystickAxisX = 0;
-    const int joystickAxisY = 1;
-
     // Read gamepad event
 	struct js_event gamepadEvent;
     
 	while (1) 
     {
-        if (read(gamepadStream, &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
+        for (int i = 0; i < MAX_GAMEPADS; i++)
         {
-            gamepadEvent.type &= ~JS_EVENT_INIT;     // Ignore synthetic events
-            
-            // Process gamepad events by type
-            if (gamepadEvent.type == JS_EVENT_BUTTON) 
+            if (read(gamepadStream[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
             {
-                TraceLog(DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
+                gamepadEvent.type &= ~JS_EVENT_INIT;     // Ignore synthetic events
                 
-                if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) 
+                // Process gamepad events by type
+                if (gamepadEvent.type == JS_EVENT_BUTTON) 
                 {
-                    // 1 - button pressed, 0 - button released
-                    gamepadButtons[gamepadEvent.number] = (int)gamepadEvent.value;
+                    TraceLog(DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
+                    
+                    if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) 
+                    {
+                        // 1 - button pressed, 0 - button released
+                        gamepadButtons[i][gamepadEvent.number] = (int)gamepadEvent.value;
+                    }
                 }
-            }
-            else if (gamepadEvent.type == JS_EVENT_AXIS) 
-            {
-                TraceLog(DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
-                
-                if (gamepadEvent.number == joystickAxisX) gamepadAxisX = (int)gamepadEvent.value;
-                if (gamepadEvent.number == joystickAxisY) gamepadAxisY = (int)gamepadEvent.value;
-                /*
-                switch (gamepadEvent.number)
+                else if (gamepadEvent.type == JS_EVENT_AXIS) 
                 {
-                    case 0: // 1st Axis X
-                    case 1: // 1st Axis Y
-                    case 2: // 2st Axis X
-                    case 3: // 2st Axis Y
+                    TraceLog(DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
+                    
+                    if (gamepadEvent.number < MAX_GAMEPAD_AXIS)
+                    {
+                        // NOTE: Scaling of gamepadEvent.value to get values between -1..1
+                        gamepadAxisValues[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
+                    }
                 }
-                */
             }
         }
 	}

+ 2 - 0
src/gestures.c

@@ -179,6 +179,7 @@ void ProcessGestureEvent(GestureEvent event)
             }
             
             touchDownDragPosition = (Vector2){ 0.0f, 0.0f };
+            pointCount = 0;
         }
         else if (event.touchAction == TOUCH_MOVE)
         {
@@ -257,6 +258,7 @@ void ProcessGestureEvent(GestureEvent event)
             pinchDistance = 0.0f;
             pinchAngle = 0.0f;
             pinchVector = (Vector2){ 0.0f, 0.0f };
+            pointCount = 0;
             
             currentGesture = GESTURE_NONE;
         }

+ 32 - 4
src/raylib.h

@@ -174,8 +174,8 @@
 // Gamepad Number
 #define GAMEPAD_PLAYER1       0
 #define GAMEPAD_PLAYER2       1
-#define GAMEPAD_PLAYER3       2
-#define GAMEPAD_PLAYER4       3
+#define GAMEPAD_PLAYER3       2     // Not supported
+#define GAMEPAD_PLAYER4       3     // Not supported
 
 // Gamepad Buttons
 // NOTE: Adjusted for a PS3 USB Controller
@@ -190,7 +190,35 @@
 #define GAMEPAD_BUTTON_SELECT   9
 #define GAMEPAD_BUTTON_START   10
 
-// TODO: Review Xbox360 USB Controller Buttons
+// Xbox360 USB Controller Buttons
+#define GAMEPAD_XBOX_BUTTON_A       0
+#define GAMEPAD_XBOX_BUTTON_B       1
+#define GAMEPAD_XBOX_BUTTON_X       2
+#define GAMEPAD_XBOX_BUTTON_Y       3
+#define GAMEPAD_XBOX_BUTTON_LB      4
+#define GAMEPAD_XBOX_BUTTON_RB      5
+#define GAMEPAD_XBOX_BUTTON_SELECT  6
+#define GAMEPAD_XBOX_BUTTON_START   7
+
+#if defined(PLATFORM_RPI)
+    #define GAMEPAD_XBOX_AXIS_DPAD_X    7
+    #define GAMEPAD_XBOX_AXIS_DPAD_Y    6
+    #define GAMEPAD_XBOX_AXIS_RIGHT_X   3
+    #define GAMEPAD_XBOX_AXIS_RIGHT_Y   4
+    #define GAMEPAD_XBOX_AXIS_LT        2
+    #define GAMEPAD_XBOX_AXIS_RT        5
+#else
+    #define GAMEPAD_XBOX_BUTTON_UP      10
+    #define GAMEPAD_XBOX_BUTTON_DOWN    12
+    #define GAMEPAD_XBOX_BUTTON_LEFT    13
+    #define GAMEPAD_XBOX_BUTTON_RIGHT   11
+    #define GAMEPAD_XBOX_AXIS_RIGHT_X   4
+    #define GAMEPAD_XBOX_AXIS_RIGHT_Y   3
+    #define GAMEPAD_XBOX_AXIS_LT_RT     2
+#endif
+
+#define GAMEPAD_XBOX_AXIS_LEFT_X    0
+#define GAMEPAD_XBOX_AXIS_LEFT_Y    1
 
 // Android Physic Buttons
 #define ANDROID_BACK            4
@@ -592,7 +620,7 @@ void DisableCursor(void);                               // Disables cursor
 bool IsCursorHidden(void);                              // Returns true if cursor is not visible
 
 bool IsGamepadAvailable(int gamepad);                   // Detect if a gamepad is available
-Vector2 GetGamepadMovement(int gamepad);                // Return axis movement vector for a gamepad
+float GetGamepadAxisMovement(int gamepad, int axis);    // Return axis movement value for a gamepad axis
 bool IsGamepadButtonPressed(int gamepad, int button);   // Detect if a gamepad button has been pressed once
 bool IsGamepadButtonDown(int gamepad, int button);      // Detect if a gamepad button is being pressed
 bool IsGamepadButtonReleased(int gamepad, int button);  // Detect if a gamepad button has been released once

+ 69 - 11
src/rlgl.c

@@ -32,7 +32,9 @@
 #include <stdlib.h>         // Declares malloc() and free() for memory management, rand()
 #include <string.h>         // Declares strcmp(), strlen(), strtok()
 
-#include "raymath.h"        // Required for Vector3 and Matrix functions
+#ifndef RLGL_STANDALONE
+    #include "raymath.h"    // Required for Vector3 and Matrix functions
+#endif
 
 #if defined(GRAPHICS_API_OPENGL_11)
     #ifdef __APPLE__                // OpenGL include for OSX
@@ -186,6 +188,8 @@ typedef struct {
 // Framebuffer Object type
 typedef struct {
     GLuint id;
+    int width;
+    int height;
     GLuint colorTextureId;
     GLuint depthTextureId;
 } FBO;
@@ -298,6 +302,7 @@ static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight);
 
 #if defined(RLGL_STANDALONE)
 static void TraceLog(int msgType, const char *text, ...);
+float *MatrixToFloat(Matrix mat);   // Converts Matrix to float array
 #endif
 
 #if defined(GRAPHICS_API_OPENGL_ES2)
@@ -780,6 +785,18 @@ void rlDisableTexture(void)
 #endif
 }
 
+// Enable depth test
+void rlEnableDepthTest(void)
+{
+    glEnable(GL_DEPTH_TEST);
+}
+
+// Disable depth test
+void rlDisableDepthTest(void)
+{
+    glDisable(GL_DEPTH_TEST);
+}
+
 // Unload texture from GPU memory
 void rlDeleteTextures(unsigned int id)
 {
@@ -1056,8 +1073,8 @@ void rlglInitPostpro(void)
         
         quad.vertexCount = 6;
         
-        float w = (float)screenWidth;
-        float h = (float)screenHeight;
+        float w = (float)postproFbo.width;
+        float h = (float)postproFbo.height;
         
         float quadPositions[6*3] = { w, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, h, 0.0f, 0.0f, h, 0.0f, w, h, 0.0f, w, 0.0f, 0.0f }; 
         float quadTexcoords[6*2] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
@@ -1081,6 +1098,8 @@ FBO rlglLoadFBO(int width, int height)
 {
     FBO fbo;   
     fbo.id = 0;
+    fbo.width = width;
+    fbo.height = height;
 
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     // Create the texture that will serve as the color attachment for the framebuffer
@@ -1579,7 +1598,7 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
     //glClearDepth(1.0f);                                   // Clear depth buffer (default)
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear used buffers, depth buffer is used for 3D
 
-    glEnable(GL_DEPTH_TEST);                                // Enables depth testing (required for 3D)
+    glDisable(GL_DEPTH_TEST);                               // Disable depth testing for 2D (only used for 3D)
     glDepthFunc(GL_LEQUAL);                                 // Type of depth testing to apply
 
     glEnable(GL_BLEND);                                     // Enable color blending (required to work with transparencies)
@@ -2324,22 +2343,21 @@ void SetCustomShader(Shader shader)
 }
 
 // Set postprocessing shader
-// NOTE: Uses global variables screenWidth and screenHeight
 void SetPostproShader(Shader shader)
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     if (!enabledPostpro)
     {
         enabledPostpro = true;
-        rlglInitPostpro();
+        rlglInitPostpro();      // Lazy initialization on postprocessing usage
     }
 
     SetModelShader(&postproQuad, shader);
     
     Texture2D texture;
     texture.id = postproFbo.colorTextureId;
-    texture.width = screenWidth;
-    texture.height = screenHeight;
+    texture.width = postproFbo.width;
+    texture.height = postproFbo.height;
 
     postproQuad.material.texDiffuse = texture;
     
@@ -2569,6 +2587,7 @@ static Shader LoadDefaultShader(void)
     char fShaderStr[] = "#version 330       \n"
         "in vec2 fragTexCoord;              \n"
         "in vec4 fragTintColor;             \n"
+        "out vec4 fragColor;                \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
     char fShaderStr[] = "#version 100       \n"
         "precision mediump float;           \n"     // precision required for OpenGL ES2 (WebGL)
@@ -2578,8 +2597,13 @@ static Shader LoadDefaultShader(void)
         "uniform sampler2D texture0;        \n"
         "void main()                        \n"
         "{                                  \n"
-        "    vec4 texelColor = texture2D(texture0, fragTexCoord); \n"   // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0, use texture() instead
-        "    gl_FragColor = texelColor*fragTintColor; \n"    
+#if defined(GRAPHICS_API_OPENGL_33)
+        "    vec4 texelColor = texture(texture0, fragTexCoord); \n"
+        "    fragColor = texelColor*fragTintColor; \n"
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+        "    vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0
+        "    gl_FragColor = texelColor*fragTintColor; \n"
+#endif
         "}                                  \n";
 
     shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
@@ -2639,6 +2663,7 @@ static Shader LoadSimpleShader(void)
 #if defined(GRAPHICS_API_OPENGL_33)
     char fShaderStr[] = "#version 330       \n"
         "in vec2 fragTexCoord;              \n"
+        "out vec4 fragColor;                \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
     char fShaderStr[] = "#version 100       \n"
         "precision mediump float;           \n"     // precision required for OpenGL ES2 (WebGL)
@@ -2648,8 +2673,13 @@ static Shader LoadSimpleShader(void)
         "uniform vec4 fragTintColor;        \n"
         "void main()                        \n"
         "{                                  \n"
-        "    vec4 texelColor = texture2D(texture0, fragTexCoord); \n"   // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0, use texture() instead
+#if defined(GRAPHICS_API_OPENGL_33)
+        "    vec4 texelColor = texture(texture0, fragTexCoord); \n"
+        "    fragColor = texelColor*fragTintColor; \n"
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+        "    vec4 texelColor = texture2D(texture0, fragTexCoord); \n"
         "    gl_FragColor = texelColor*fragTintColor; \n"
+#endif
         "}                                  \n";
 
     shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
@@ -3090,4 +3120,32 @@ static void TraceLog(int msgType, const char *text, ...)
 
     if (msgType == ERROR) exit(1);
 }
+
+// Converts Matrix to float array
+// NOTE: Returned vector is a transposed version of the Matrix struct, 
+// it should be this way because, despite raymath use OpenGL column-major convention,
+// Matrix struct memory alignment and variables naming are not coherent
+float *MatrixToFloat(Matrix mat)
+{
+    static float buffer[16];
+
+    buffer[0] = mat.m0;
+    buffer[1] = mat.m4;
+    buffer[2] = mat.m8;
+    buffer[3] = mat.m12;
+    buffer[4] = mat.m1;
+    buffer[5] = mat.m5;
+    buffer[6] = mat.m9;
+    buffer[7] = mat.m13;
+    buffer[8] = mat.m2;
+    buffer[9] = mat.m6;
+    buffer[10] = mat.m10;
+    buffer[11] = mat.m14;
+    buffer[12] = mat.m3;
+    buffer[13] = mat.m7;
+    buffer[14] = mat.m11;
+    buffer[15] = mat.m15;
+
+    return buffer;
+}
 #endif

+ 7 - 1
src/rlgl.h

@@ -36,7 +36,11 @@
     #include "utils.h"          // Required for function TraceLog()
 #endif
 
-#include "raymath.h"
+#ifdef RLGL_STANDALONE
+    #define RAYMATH_STANDALONE
+#endif
+
+#include "raymath.h"            // Required for types: Vector3, Matrix
 
 // Select desired OpenGL version
 // NOTE: Those preprocessor defines are only used on rlgl module,
@@ -244,6 +248,8 @@ void rlColor4f(float x, float y, float z, float w); // Define one vertex (color)
 //------------------------------------------------------------------------------------
 void rlEnableTexture(unsigned int id);          // Enable texture usage
 void rlDisableTexture(void);                    // Disable texture usage
+void rlEnableDepthTest(void);                   // Enable depth test
+void rlDisableDepthTest(void);                  // Disable depth test
 void rlDeleteTextures(unsigned int id);         // Delete OpenGL texture from GPU
 void rlDeleteShader(unsigned int id);           // Delete OpenGL shader program from GPU
 void rlDeleteVertexArrays(unsigned int id);     // Unload vertex data (VAO) from GPU memory

+ 110 - 34
src/shapes.c

@@ -98,7 +98,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
 // Draw a color-filled circle
 void DrawCircle(int centerX, int centerY, float radius, Color color)
 {
-    DrawPoly((Vector2){ centerX, centerY }, 36, radius, 0, color);
+    DrawCircleV((Vector2){ centerX, centerY }, radius, color);
 }
 
 // Draw a gradient-filled circle
@@ -119,17 +119,40 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
 }
 
 // Draw a color-filled circle (Vector version)
+// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
 void DrawCircleV(Vector2 center, float radius, Color color)
 {
-    rlBegin(RL_TRIANGLES);
-        for (int i = 0; i < 360; i += 10)
-        {
-            rlColor4ub(color.r, color.g, color.b, color.a);
-            rlVertex2i(center.x, center.y);
-            rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
-            rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
-        }
-    rlEnd();
+    if (rlGetVersion() == OPENGL_11)
+    {
+        rlBegin(RL_TRIANGLES);
+            for (int i = 0; i < 360; i += 10)
+            {
+                rlColor4ub(color.r, color.g, color.b, color.a);
+                
+                rlVertex2i(center.x, center.y);
+                rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
+                rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
+            }
+        rlEnd();
+    }
+    else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
+    {
+        rlEnableTexture(whiteTexture); // Default white texture
+
+        rlBegin(RL_QUADS);
+            for (int i = 0; i < 360; i += 20)
+            {
+                rlColor4ub(color.r, color.g, color.b, color.a);
+                
+                rlVertex2i(center.x, center.y);
+                rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
+                rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
+                rlVertex2f(center.x + sin(DEG2RAD*(i + 20)) * radius, center.y + cos(DEG2RAD*(i + 20)) * radius);
+            }
+        rlEnd();
+        
+        rlDisableTexture();
+    }
 }
 
 // Draw circle outline
@@ -178,38 +201,76 @@ void DrawRectangleGradient(int posX, int posY, int width, int height, Color colo
 }
 
 // Draw a color-filled rectangle (Vector version)
+// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
 void DrawRectangleV(Vector2 position, Vector2 size, Color color)
 {
-    rlBegin(RL_TRIANGLES);
-        rlColor4ub(color.r, color.g, color.b, color.a);
+    if (rlGetVersion() == OPENGL_11)
+    {
+        rlBegin(RL_TRIANGLES);
+            rlColor4ub(color.r, color.g, color.b, color.a);
 
-        rlVertex2i(position.x, position.y);
-        rlVertex2i(position.x, position.y + size.y);
-        rlVertex2i(position.x + size.x, position.y + size.y);
+            rlVertex2i(position.x, position.y);
+            rlVertex2i(position.x, position.y + size.y);
+            rlVertex2i(position.x + size.x, position.y + size.y);
 
-        rlVertex2i(position.x, position.y);
-        rlVertex2i(position.x + size.x, position.y + size.y);
-        rlVertex2i(position.x + size.x, position.y);
-    rlEnd();
+            rlVertex2i(position.x, position.y);
+            rlVertex2i(position.x + size.x, position.y + size.y);
+            rlVertex2i(position.x + size.x, position.y);
+        rlEnd();
+    }
+    else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
+    {
+        rlEnableTexture(whiteTexture); // Default white texture
+
+        rlBegin(RL_QUADS);
+            rlColor4ub(color.r, color.g, color.b, color.a);
+            rlNormal3f(0.0f, 0.0f, 1.0f);
+
+            rlTexCoord2f(0.0f, 0.0f);
+            rlVertex2f(position.x, position.y);
+
+            rlTexCoord2f(0.0f, 1.0f);
+            rlVertex2f(position.x, position.y + size.y);
+
+            rlTexCoord2f(1.0f, 1.0f);
+            rlVertex2f(position.x + size.x, position.y + size.y);
+
+            rlTexCoord2f(1.0f, 0.0f);
+            rlVertex2f(position.x + size.x, position.y);
+        rlEnd();
+
+        rlDisableTexture();
+    }
 }
 
 // Draw rectangle outline
+// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
 void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
-{
-    rlBegin(RL_LINES);
-        rlColor4ub(color.r, color.g, color.b, color.a);
-        rlVertex2i(posX + 1, posY + 1);
-        rlVertex2i(posX + width, posY + 1);
+{   
+    if (rlGetVersion() == OPENGL_11)
+    {
+        rlBegin(RL_LINES);
+            rlColor4ub(color.r, color.g, color.b, color.a);
+            rlVertex2i(posX + 1, posY + 1);
+            rlVertex2i(posX + width, posY + 1);
 
-        rlVertex2i(posX + width, posY + 1);
-        rlVertex2i(posX + width, posY + height);
+            rlVertex2i(posX + width, posY + 1);
+            rlVertex2i(posX + width, posY + height);
 
-        rlVertex2i(posX + width, posY + height);
-        rlVertex2i(posX + 1, posY + height);
+            rlVertex2i(posX + width, posY + height);
+            rlVertex2i(posX + 1, posY + height);
 
-        rlVertex2i(posX + 1, posY + height);
-        rlVertex2i(posX + 1, posY + 1);
-    rlEnd();
+            rlVertex2i(posX + 1, posY + height);
+            rlVertex2i(posX + 1, posY + 1);
+        rlEnd();
+    }
+    else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
+    {
+        DrawRectangle(posX, posY, width, 1, color);
+        DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);
+        DrawRectangle(posX, posY + height - 1, width, 1, color);
+        DrawRectangle(posX, posY + 1, 1, height - 2, color);
+    }
 }
 
 // Draw a triangle
@@ -429,9 +490,24 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
                 retRec.height = rec2.height - dyy;
             }
         }
-
-        if (retRec.width >= rec2.width) retRec.width = rec2.width;
-        if (retRec.height >= rec2.height) retRec.height = rec2.height;
+		
+        if (rec1.width > rec2.width)
+        {
+            if (retRec.width >= rec2.width) retRec.width = rec2.width;
+        }
+        else
+        {
+            if (retRec.width >= rec1.width) retRec.width = rec1.width;
+        }
+        
+        if (rec1.height > rec2.height)
+        {
+            if (retRec.height >= rec2.height) retRec.height = rec2.height;
+        }
+        else
+        {
+           if (retRec.height >= rec1.height) retRec.height = rec1.height;
+        }
     }
 
     return retRec;