diff --git a/examples/core_3d_camera_first_person.c b/examples/core_3d_camera_first_person.c index 16d388dfd..56e38a237 100644 --- a/examples/core_3d_camera_first_person.c +++ b/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(); //---------------------------------------------------------------------------------- diff --git a/examples/core_3d_camera_first_person.png b/examples/core_3d_camera_first_person.png index 9373da2da..7130b0a20 100644 Binary files a/examples/core_3d_camera_first_person.png and b/examples/core_3d_camera_first_person.png differ diff --git a/examples/core_3d_camera_free.c b/examples/core_3d_camera_free.c index 234c46b3b..fa7ad85f4 100644 --- a/examples/core_3d_camera_free.c +++ b/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(); //---------------------------------------------------------------------------------- diff --git a/examples/core_3d_camera_free.png b/examples/core_3d_camera_free.png index 179206201..8857a4789 100644 Binary files a/examples/core_3d_camera_free.png and b/examples/core_3d_camera_free.png differ diff --git a/examples/core_3d_picking.c b/examples/core_3d_picking.c index 33eaed8a5..da3031078 100644 --- a/examples/core_3d_picking.c +++ b/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); diff --git a/examples/shapes_basic_shapes.png b/examples/shapes_basic_shapes.png index 03ecf2ec0..a7d4a991b 100644 Binary files a/examples/shapes_basic_shapes.png and b/examples/shapes_basic_shapes.png differ diff --git a/examples/textures_srcrec_dstrec.png b/examples/textures_srcrec_dstrec.png index 7459d6ecc..9ea00fe43 100644 Binary files a/examples/textures_srcrec_dstrec.png and b/examples/textures_srcrec_dstrec.png differ diff --git a/src/core.c b/src/core.c index 6b2321c29..c05de93b3 100644 --- a/src/core.c +++ b/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 }; - + float value = 0; + +#if defined(PLATFORM_RPI) + if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) + { + if (axis < MAX_GAMEPAD_AXIS) value = gamepadAxisValues[gamepad][axis]; + } +#else const float *axes; int axisCount = 0; -#if defined(PLATFORM_RPI) - // TODO: Get gamepad axis information - // Use gamepadAxisX, gamepadAxisY -#else axes = glfwGetJoystickAxes(gamepad, &axisCount); -#endif - if (axisCount >= 2) - { - vec.x = axes[0]; // Left joystick X - vec.y = axes[1]; // Left joystick Y + if (axis < axisCount) value = axes[axis]; +#endif - //vec.x = axes[2]; // Right joystick X - //vec.x = axes[3]; // Right joystick Y - } - - 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) + char gamepadDev[128] = ""; + + for (int i = 0; i < MAX_GAMEPADS; i++) { - TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available"); - } - else - { - 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; + } } - */ } } } diff --git a/src/gestures.c b/src/gestures.c index 583b77cda..b0a80084e 100644 --- a/src/gestures.c +++ b/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; } diff --git a/src/raylib.h b/src/raylib.h index ddfccea7d..a87b58da3 100644 --- a/src/raylib.h +++ b/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 diff --git a/src/rlgl.c b/src/rlgl.c index d9761732a..fc14a0af9 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -32,7 +32,9 @@ #include // Declares malloc() and free() for memory management, rand() #include // 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 diff --git a/src/rlgl.h b/src/rlgl.h index 69640febe..1a5260ebb 100644 --- a/src/rlgl.h +++ b/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 diff --git a/src/shapes.c b/src/shapes.c index 51730a053..14d113150 100644 --- a/src/shapes.c +++ b/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;