diff --git a/CHANGELOG b/CHANGELOG index 293158f4b..2487befaf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,8 @@ Release: raylib 1.3.0 (01 September 2015) NOTE: This version supposed a big boost for raylib, new modules have been added with lots of features. Most of the modules have been completely reviewed to accomodate to the new features. + Over 50 new functions have been added to previous raylib version. + Most of the examples have been redone and 10 new advanced examples have been added. BIG changes: [camera] NEW MODULE: Set of cameras for 3d view: Free, Orbital, 1st person, 3rd person @@ -27,6 +29,7 @@ smaller changes: [core] Added functions ShowCursor(), HideCursor(), IsCursorHidden() [core] Renamed function SetFlags() to SetConfigFlags() [shapes] Simplified some functions to improve performance +[textures] Review of Image struct to support multiple data formats [textures] Added function LoadImageEx() [textures] Added function LoadImageRaw() [textures] Added function LoadTextureEx() @@ -37,6 +40,8 @@ smaller changes: [textures] Added function ImageConvertFormat() [textures] Added function GenTextureMipmaps() [text] Added support for Latin-1 Extended characters for default font +[text] Redesigned SpriteFont struct, replaced Character struct by Rectangle +[text] Removed function GetFontBaseSize(), use directly spriteFont.size [models] Review of struct: Model (added shaders support) [models] Added 3d collision functions (sphere vs sphere vs box vs box) [models] Added function DrawCubeTexture() diff --git a/README.md b/README.md index 5a1a268b7..33f6cede8 100644 --- a/README.md +++ b/README.md @@ -87,10 +87,10 @@ assigned to models or used as fullscreen postrocessing shaders. Textures module has been improved to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT). -New camera module offers the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, third person), -very easy to use, just calling functions: SetCameraMode() and UpdateCamera(). +New camera module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). +Camera modes are very easy to use, just calling functions: SetCameraMode() and UpdateCamera(). -New gestures module simplifies getures detection on Android and HTML5 programs. +New gestures module simplifies gestures detection on Android and HTML5 programs. New IMGUI (Immediate Mode GUI) module: raygui, offers a set of functions to create simple user interfaces, primary intended for tools development, still in experimental state but already fully functional. @@ -277,7 +277,7 @@ If you are using raylib and you enjoy it, please, [let me know][raysan5]. If you feel you can help, then, [helpme!](http://www.raylib.com/helpme.htm) -acknowledgments +acknowledgements --------------- The following people have contributed in some way to make raylib project a reality. Big thanks to them! @@ -288,9 +288,9 @@ The following people have contributed in some way to make raylib project a reali - Marc Palau for implementating and testing of 3D shapes functions and helping on development of camera and getures modules. - Kevin Gato for improving texture internal formats support and helping on raygui development. - Daniel Nicolas for improving texture internal formats support and helping on raygui development. - - Marc Agüera for testing and using raylib on a real product (Koala Seasons) - - Daniel Moreno for testing and using raylib on a real product (Koala Seasons) - - Daniel Gomez for testing and using raylib on a real product (Koala Seasons) + - Marc Agüera for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) + - Daniel Moreno for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) + - Daniel Gomez for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) - Sergio Martinez for helping on raygui development and tools development. diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c index 359af0aff..1376a27d2 100644 --- a/examples/audio_sound_loading.c +++ b/examples/audio_sound_loading.c @@ -7,7 +7,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_3d_camera_first_person.c b/examples/core_3d_camera_first_person.c new file mode 100644 index 000000000..cd37f873d --- /dev/null +++ b/examples/core_3d_camera_first_person.c @@ -0,0 +1,91 @@ +/******************************************************************************************* +* +* raylib [core] example - 3d camera first person +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define MAX_COLUMNS 20 + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); + + // Define the camera to look into our 3d world + Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + + // Generates some random columns + float heights[MAX_COLUMNS]; + Vector3 positions[MAX_COLUMNS] = { 0.0, 2.5, 0.0 }; + Color colors[MAX_COLUMNS]; + + for (int i = 0; i < MAX_COLUMNS; i++) + { + heights[i] = (float)GetRandomValue(1, 12); + positions[i] = (Vector3){ GetRandomValue(-15, 15), heights[i]/2, GetRandomValue(-15, 15) }; + colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 }; + } + + Vector3 playerPosition = { 4, 2, 4 }; // Define player position + + SetCameraMode(CAMERA_FIRST_PERSON); // Set a first person camera mode + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCameraPlayer(&camera, &playerPosition); // Update camera and player position + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + Begin3dMode(camera); + + DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 32, 32 }, LIGHTGRAY); // Draw ground + DrawCube((Vector3){ -16, 2.5, 0 }, 1, 5, 32, BLUE); // Draw a blue wall + DrawCube((Vector3){ 16, 2.5, 0 }, 1, 5, 32, LIME); // Draw a green wall + DrawCube((Vector3){ 0, 2.5, 16 }, 32, 5, 1, GOLD); // Draw a yellow wall + + // Draw some cubes around + for (int i = 0; i < MAX_COLUMNS; i++) + { + DrawCube(positions[i], 2, heights[i], 2, colors[i]); + DrawCubeWires(positions[i], 2, heights[i], 2, MAROON); + } + + End3dMode(); + + 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 lokk around", 40, 70, 10, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core_3d_camera_first_person.png b/examples/core_3d_camera_first_person.png new file mode 100644 index 000000000..9373da2da Binary files /dev/null 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 new file mode 100644 index 000000000..cca9cfd50 --- /dev/null +++ b/examples/core_3d_camera_free.c @@ -0,0 +1,75 @@ +/******************************************************************************************* +* +* raylib [core] example - Initialize 3d camera free +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free"); + + // Define the camera to look into our 3d world + Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + + Vector3 cubePosition = { 0.0, 0.0, 0.0 }; + + SetCameraMode(CAMERA_FREE); // Set a free camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our camera position + SetCameraTarget(camera.target); // Set internal camera target to match our camera target + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera); // Update internal camera and our camera + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(WHITE); + + Begin3dMode(camera); + + DrawCube(cubePosition, 2, 2, 2, RED); + DrawCubeWires(cubePosition, 2, 2, 2, MAROON); + + DrawGrid(10.0, 1.0); + + 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); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core_3d_camera_free.png b/examples/core_3d_camera_free.png new file mode 100644 index 000000000..afb5a7c50 Binary files /dev/null and b/examples/core_3d_camera_free.png differ diff --git a/examples/core_3d_mode.c b/examples/core_3d_mode.c index 2275058d4..c38da256b 100644 --- a/examples/core_3d_mode.c +++ b/examples/core_3d_mode.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_3d_picking.c b/examples/core_3d_picking.c index a7a96fa9f..13839070d 100644 --- a/examples/core_3d_picking.c +++ b/examples/core_3d_picking.c @@ -2,10 +2,10 @@ * * raylib [core] example - Picking in 3d mode * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com) * ********************************************************************************************/ @@ -23,23 +23,30 @@ int main() // Define the camera to look into our 3d world Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - Vector3 cubePosition = { 0.0, 0.0, 0.0 }; + Vector3 cubePosition = { 0.0, 1.0, 0.0 }; - Ray pickingLine; + Ray ray; // Picking line ray - SetCameraMode(CAMERA_FREE); + SetCameraMode(CAMERA_FREE); // Set a free camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our camera position - SetTargetFPS(60); + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - camera = UpdateCamera(0); + UpdateCamera(&camera); // Update internal camera and our camera - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pickingLine = GetMouseRay(GetMousePosition(), camera); + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + // NOTE: This function is NOT WORKING properly! + ray = GetMouseRay(GetMousePosition(), camera); + + // TODO: Check collision between ray and box + } //---------------------------------------------------------------------------------- // Draw @@ -50,14 +57,16 @@ int main() Begin3dMode(camera); - DrawCube(cubePosition, 2, 2, 2, RED); - DrawCubeWires(cubePosition, 2, 2, 2, MAROON); + DrawCube(cubePosition, 2, 2, 2, GRAY); + DrawCubeWires(cubePosition, 2, 2, 2, DARKGRAY); DrawGrid(10.0, 1.0); - DrawRay(pickingLine, MAROON); + DrawRay(ray, MAROON); End3dMode(); + + DrawText("Try selecting the box with mouse!", 240, 10, 20, GRAY); DrawFPS(10, 10); diff --git a/examples/core_3d_picking.png b/examples/core_3d_picking.png new file mode 100644 index 000000000..828c41a83 Binary files /dev/null and b/examples/core_3d_picking.png differ diff --git a/examples/core_basic_window_web.c b/examples/core_basic_window_web.c index b35c07e67..65650b1aa 100644 --- a/examples/core_basic_window_web.c +++ b/examples/core_basic_window_web.c @@ -15,7 +15,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_color_select.c b/examples/core_color_select.c index a2a79ed98..118dc88a9 100644 --- a/examples/core_color_select.c +++ b/examples/core_color_select.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/models_planes.c b/examples/core_drop_files.c similarity index 55% rename from examples/models_planes.c rename to examples/core_drop_files.c index 58b5137e4..5802e48f4 100644 --- a/examples/models_planes.c +++ b/examples/core_drop_files.c @@ -1,8 +1,8 @@ /******************************************************************************************* * -* raylib [models] example - Draw 3d planes +* raylib [core] example - Windows drop files * -* This example has been created using raylib 1.2 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) @@ -18,12 +18,12 @@ int main() int screenWidth = 800; int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [models] example - 3d planes"); - - // Define the camera to look into our 3d world - Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + InitWindow(screenWidth, screenHeight, "raylib [core] example - drop files"); + + int count = 0; + char **droppedFiles; + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -31,7 +31,10 @@ int main() { // Update //---------------------------------------------------------------------------------- - // TODO: Update your variables here + if (IsFileDropped()) + { + droppedFiles = GetDroppedFiles(&count); + } //---------------------------------------------------------------------------------- // Draw @@ -40,15 +43,21 @@ int main() ClearBackground(RAYWHITE); - Begin3dMode(camera); - - DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 4, 4 }, RED); // Draw a plane XZ - - DrawGrid(10.0, 1.0); - - End3dMode(); - - DrawFPS(10, 10); + if (count == 0) DrawText("Drop your files to this window!", 100, 40, 20, DARKGRAY); + else + { + DrawText("Dropped files:", 100, 40, 20, DARKGRAY); + + for (int i = 0; i < count; i++) + { + if (i%2 == 0) DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.5f)); + else DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.3f)); + + DrawText(droppedFiles[i], 120, 100 + 40*i, 10, GRAY); + } + + DrawText("Drop new files...", 100, 110 + 40*count, 20, DARKGRAY); + } EndDrawing(); //---------------------------------------------------------------------------------- @@ -56,7 +65,9 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context + ClearDroppedFiles(); // Clear internal buffers + + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/core_drop_files.png b/examples/core_drop_files.png new file mode 100644 index 000000000..d46c44cfd Binary files /dev/null and b/examples/core_drop_files.png differ diff --git a/examples/core_input_gamepad.c b/examples/core_input_gamepad.c index 384ef989e..64be4cd84 100644 --- a/examples/core_input_gamepad.c +++ b/examples/core_input_gamepad.c @@ -8,7 +8,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_input_keys.c b/examples/core_input_keys.c index 442ae8408..99d5e5160 100644 --- a/examples/core_input_keys.c +++ b/examples/core_input_keys.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_input_mouse.c b/examples/core_input_mouse.c index eeef8c7ab..c64b421e3 100644 --- a/examples/core_input_mouse.c +++ b/examples/core_input_mouse.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_mouse_wheel.c b/examples/core_mouse_wheel.c index 08c2ee1e2..6a5252ee5 100644 --- a/examples/core_mouse_wheel.c +++ b/examples/core_mouse_wheel.c @@ -5,7 +5,7 @@ * This test has been created using raylib 1.1 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/core_random_values.c b/examples/core_random_values.c index 20989ee19..98e0e91ef 100644 --- a/examples/core_random_values.c +++ b/examples/core_random_values.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.1 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/models_billboard.c b/examples/models_billboard.c index a58ec7d76..05d836ca3 100644 --- a/examples/models_billboard.c +++ b/examples/models_billboard.c @@ -2,10 +2,10 @@ * * raylib [models] example - Drawing billboards * -* This example has been created using raylib 1.2 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2015 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -21,24 +21,24 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards"); // Define the camera to look into our 3d world - Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + Camera camera = {{ 5.0, 4.0, 5.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - Texture2D lena = LoadTexture("resources/lena.png"); // Our texture for billboard - Rectangle eyesRec = { 225, 240, 155, 50 }; // Part of the texture to draw - Vector3 billPosition = { 0.0, 0.0, 0.0 }; // Position where draw billboard + Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard + Vector3 billPosition = { 0.0, 2.0, 0.0 }; // Position where draw billboard + + SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our camera position + SetCameraTarget(camera.target); // Set internal camera target to match our camera target - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - if (IsKeyDown(KEY_LEFT)) camera.position.x -= 0.2; - if (IsKeyDown(KEY_RIGHT)) camera.position.x += 0.2; - if (IsKeyDown(KEY_UP)) camera.position.y -= 0.2; - if (IsKeyDown(KEY_DOWN)) camera.position.y += 0.2; + UpdateCamera(&camera); // Update internal camera and our camera //---------------------------------------------------------------------------------- // Draw @@ -49,8 +49,7 @@ int main() Begin3dMode(camera); - //DrawBillboard(camera, lena, billPosition, 1.0, WHITE); - DrawBillboardRec(camera, lena, eyesRec, billPosition, 4.0, WHITE); + DrawBillboard(camera, bill, billPosition, 2.0f, WHITE); DrawGrid(10.0, 1.0); // Draw a grid @@ -64,7 +63,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - UnloadTexture(lena); // Unload texture + UnloadTexture(bill); // Unload texture CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/models_billboard.png b/examples/models_billboard.png new file mode 100644 index 000000000..f1ed92399 Binary files /dev/null and b/examples/models_billboard.png differ diff --git a/examples/models_cubicmap.c b/examples/models_cubicmap.c index 62f7b076e..d7fe896ce 100644 --- a/examples/models_cubicmap.c +++ b/examples/models_cubicmap.c @@ -2,10 +2,10 @@ * * raylib [models] example - Cubicmap loading and drawing * -* This example has been created using raylib 1.2 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com) * ********************************************************************************************/ @@ -21,29 +21,32 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing"); // Define the camera to look into our 3d world - Camera camera = {{ 7.0, 7.0, 7.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + Camera camera = {{ 16.0, 14.0, 16.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - Image image = LoadImage("resources/cubicmap.png"); // Load cubesmap image (RAM) - Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) + Image image = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM) + Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM) Model map = LoadCubicmap(image); // Load cubicmap model (generate model from image) - SetModelTexture(&map, texture); // Bind texture to model - Vector3 mapPosition = { -1, 0.0, -1 }; // Set model position + + // NOTE: By default each cube is mapped to one part of texture atlas + Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture + SetModelTexture(&map, texture); // Bind texture to map model + + Vector3 mapPosition = { -16, 0.0, -8 }; // Set model position UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM + + SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - if (IsKeyDown(KEY_UP)) camera.position.y += 0.2f; - else if (IsKeyDown(KEY_DOWN)) camera.position.y -= 0.2f; - - if (IsKeyDown(KEY_RIGHT)) camera.position.z += 0.2f; - else if (IsKeyDown(KEY_LEFT)) camera.position.z -= 0.2f; + UpdateCamera(&camera); // Update internal camera and our camera //---------------------------------------------------------------------------------- // Draw @@ -54,13 +57,15 @@ int main() Begin3dMode(camera); - DrawModel(map, mapPosition, 1.0f, MAROON); - - DrawGrid(10.0, 1.0); - - DrawGizmo(mapPosition); + DrawModel(map, mapPosition, 1.0f, WHITE); End3dMode(); + + DrawTextureEx(cubicmap, (Vector2){ screenWidth - cubicmap.width*4 - 20, 20 }, 0.0f, 4.0f, WHITE); + DrawRectangleLines(screenWidth - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN); + + DrawText("cubicmap image used to", 658, 90, 10, GRAY); + DrawText("generate map 3d model", 658, 104, 10, GRAY); DrawFPS(10, 10); @@ -70,8 +75,9 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - UnloadTexture(texture); // Unload texture - UnloadModel(map); // Unload model + UnloadTexture(cubicmap); // Unload cubicmap texture + UnloadTexture(texture); // Unload map texture + UnloadModel(map); // Unload map model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/models_cubicmap.png b/examples/models_cubicmap.png index f686ba21c..9cb854cb9 100644 Binary files a/examples/models_cubicmap.png and b/examples/models_cubicmap.png differ diff --git a/examples/models_custom_shader.c b/examples/models_custom_shader.c deleted file mode 100644 index 5430ed65a..000000000 --- a/examples/models_custom_shader.c +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************************* -* -* raylib [models] example - Load and draw a 3d model (OBJ) -* -* This example has been created using raylib 1.0 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) -* -********************************************************************************************/ - -#include "raylib.h" - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - int screenWidth = 1280; - int screenHeight = 720; - - InitWindow(screenWidth, screenHeight, "raylib [models] example - custom shader"); - - // Define the camera to look into our 3d world - Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - - Texture2D texture = LoadTexture("resources/catsham.png"); // Load model texture - Shader shader = LoadShader("resources/shaders/custom.vs", "resources/shaders/custom.fs"); - //Shader poste = LoadShader("resources/shaders/custom.vs", "resources/shaders/pixel.fs"); - - Model cat = LoadModel("resources/cat.obj"); // Load OBJ model - - SetModelTexture(&cat, texture); // Bind texture to model - //SetModelShader(&cat, poste); - - Vector3 catPosition = { 0.0, 0.0, 0.0 }; // Set model position - - SetPostproShader(shader); - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - if (IsKeyDown(KEY_LEFT)) catPosition.x -= 0.2; - if (IsKeyDown(KEY_RIGHT)) catPosition.x += 0.2; - if (IsKeyDown(KEY_UP)) catPosition.z -= 0.2; - if (IsKeyDown(KEY_DOWN)) catPosition.z += 0.2; - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - Begin3dMode(camera); - - DrawModel(cat, catPosition, 0.1f, WHITE); // Draw 3d model with texture - - DrawGrid(10.0, 1.0); // Draw a grid - - DrawGizmo(catPosition); // Draw gizmo - - End3dMode(); - - DrawFPS(10, 10); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - UnloadTexture(texture); // Unload texture - UnloadModel(cat); // Unload model - UnloadShader(shader); - //UnloadShader(poste); - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} \ No newline at end of file diff --git a/examples/models_geometric_shapes.c b/examples/models_geometric_shapes.c index 3a649a3a6..e2d41dcd5 100644 --- a/examples/models_geometric_shapes.c +++ b/examples/models_geometric_shapes.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/models_heightmap.c b/examples/models_heightmap.c index a23656a56..fec3f5e63 100644 --- a/examples/models_heightmap.c +++ b/examples/models_heightmap.c @@ -2,10 +2,10 @@ * * raylib [models] example - Heightmap loading and drawing * -* This example has been created using raylib 1.1 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2015 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -20,26 +20,29 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing"); - // Define the camera to look into our 3d world - Camera camera = {{ 10.0, 12.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + // Define our custom camera to look into our 3d world + Camera camera = {{ 24.0, 18.0, 24.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) - Model map = LoadHeightmap(image, 4); // Load heightmap model + Model map = LoadHeightmap(image, 32); // Load heightmap model SetModelTexture(&map, texture); // Bind texture to model - Vector3 mapPosition = { -4, 0.0, -4 }; // Set model position + Vector3 mapPosition = { -16, 0.0, -16 }; // Set model position (depends on model scaling!) - UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM + UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM + + SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - // ... + UpdateCamera(&camera); // Update internal camera and our camera //---------------------------------------------------------------------------------- // Draw @@ -50,13 +53,13 @@ int main() Begin3dMode(camera); - DrawModel(map, mapPosition, 0.5f, MAROON); - - DrawGrid(10.0, 1.0); - - DrawGizmo(mapPosition); + // NOTE: Model is scaled to 1/4 of its original size (128x128 units) + DrawModel(map, mapPosition, 1/4.0f, RED); End3dMode(); + + DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE); + DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN); DrawFPS(10, 10); diff --git a/examples/models_heightmap.png b/examples/models_heightmap.png index a32ec954b..9ed04586e 100644 Binary files a/examples/models_heightmap.png and b/examples/models_heightmap.png differ diff --git a/examples/models_obj_loading.c b/examples/models_obj_loading.c index 55501f65c..ef0243561 100644 --- a/examples/models_obj_loading.c +++ b/examples/models_obj_loading.c @@ -2,7 +2,7 @@ * * raylib [models] example - Load and draw a 3d model (OBJ) * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2014 Ramon Santamaria (@raysan5) diff --git a/examples/models_obj_loading.png b/examples/models_obj_loading.png index da49c457b..560348b48 100644 Binary files a/examples/models_obj_loading.png and b/examples/models_obj_loading.png differ diff --git a/examples/openal32.dll b/examples/openal32.dll deleted file mode 100644 index 71ced6a21..000000000 Binary files a/examples/openal32.dll and /dev/null differ diff --git a/examples/resources/billboard.png b/examples/resources/billboard.png new file mode 100644 index 000000000..e2fe398db Binary files /dev/null and b/examples/resources/billboard.png differ diff --git a/examples/resources/cubicmap.png b/examples/resources/cubicmap.png index 87b95d506..b361c0182 100644 Binary files a/examples/resources/cubicmap.png and b/examples/resources/cubicmap.png differ diff --git a/examples/resources/cubicmap_atlas.png b/examples/resources/cubicmap_atlas.png new file mode 100644 index 000000000..7ddfc83a8 Binary files /dev/null and b/examples/resources/cubicmap_atlas.png differ diff --git a/examples/resources/guybrush.png b/examples/resources/guybrush.png new file mode 100644 index 000000000..32c9dcedd Binary files /dev/null and b/examples/resources/guybrush.png differ diff --git a/examples/resources/heightmap.png b/examples/resources/heightmap.png index c17050fcc..fe30f679f 100644 Binary files a/examples/resources/heightmap.png and b/examples/resources/heightmap.png differ diff --git a/examples/resources/lena.png b/examples/resources/lena.png deleted file mode 100644 index 59ef68aab..000000000 Binary files a/examples/resources/lena.png and /dev/null differ diff --git a/examples/resources/raylib_logo.dds b/examples/resources/raylib_logo.dds deleted file mode 100644 index b558bc156..000000000 Binary files a/examples/resources/raylib_logo.dds and /dev/null differ diff --git a/examples/resources/raylib_logo_uncompressed.dds b/examples/resources/raylib_logo_uncompressed.dds deleted file mode 100644 index 2b40a205a..000000000 Binary files a/examples/resources/raylib_logo_uncompressed.dds and /dev/null differ diff --git a/examples/resources/smoke.png b/examples/resources/smoke.png new file mode 100644 index 000000000..7bad8c685 Binary files /dev/null and b/examples/resources/smoke.png differ diff --git a/examples/resources/texture_formats/sonic.png b/examples/resources/texture_formats/sonic.png new file mode 100644 index 000000000..7a0968471 Binary files /dev/null and b/examples/resources/texture_formats/sonic.png differ diff --git a/examples/resources/texture_formats/sonic_A1R5G5B5.dds b/examples/resources/texture_formats/sonic_A1R5G5B5.dds new file mode 100644 index 000000000..5e2347db1 Binary files /dev/null and b/examples/resources/texture_formats/sonic_A1R5G5B5.dds differ diff --git a/examples/resources/texture_formats/sonic_A4R4G4B4.dds b/examples/resources/texture_formats/sonic_A4R4G4B4.dds new file mode 100644 index 000000000..c5ccaf0cc Binary files /dev/null and b/examples/resources/texture_formats/sonic_A4R4G4B4.dds differ diff --git a/examples/resources/texture_formats/sonic_A8R8G8B8.dds b/examples/resources/texture_formats/sonic_A8R8G8B8.dds new file mode 100644 index 000000000..fb71b7be7 Binary files /dev/null and b/examples/resources/texture_formats/sonic_A8R8G8B8.dds differ diff --git a/examples/resources/texture_formats/sonic_ASTC_4x4_ldr.astc b/examples/resources/texture_formats/sonic_ASTC_4x4_ldr.astc new file mode 100644 index 000000000..9a98d9a06 Binary files /dev/null and b/examples/resources/texture_formats/sonic_ASTC_4x4_ldr.astc differ diff --git a/examples/resources/texture_formats/sonic_ASTC_8x8_ldr.astc b/examples/resources/texture_formats/sonic_ASTC_8x8_ldr.astc new file mode 100644 index 000000000..360a264ad Binary files /dev/null and b/examples/resources/texture_formats/sonic_ASTC_8x8_ldr.astc differ diff --git a/examples/resources/texture_formats/sonic_DXT1_RGB.dds b/examples/resources/texture_formats/sonic_DXT1_RGB.dds new file mode 100644 index 000000000..9d0b45988 Binary files /dev/null and b/examples/resources/texture_formats/sonic_DXT1_RGB.dds differ diff --git a/examples/resources/texture_formats/sonic_DXT1_RGBA.dds b/examples/resources/texture_formats/sonic_DXT1_RGBA.dds new file mode 100644 index 000000000..102bae7f1 Binary files /dev/null and b/examples/resources/texture_formats/sonic_DXT1_RGBA.dds differ diff --git a/examples/resources/texture_formats/sonic_DXT3_RGBA.dds b/examples/resources/texture_formats/sonic_DXT3_RGBA.dds new file mode 100644 index 000000000..46d965cbd Binary files /dev/null and b/examples/resources/texture_formats/sonic_DXT3_RGBA.dds differ diff --git a/examples/resources/texture_formats/sonic_DXT5_RGBA.dds b/examples/resources/texture_formats/sonic_DXT5_RGBA.dds new file mode 100644 index 000000000..b3a59a793 Binary files /dev/null and b/examples/resources/texture_formats/sonic_DXT5_RGBA.dds differ diff --git a/examples/resources/texture_formats/sonic_ETC1_RGB.ktx b/examples/resources/texture_formats/sonic_ETC1_RGB.ktx new file mode 100644 index 000000000..66241b9d0 Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC1_RGB.ktx differ diff --git a/examples/resources/texture_formats/sonic_ETC1_RGB.pkm b/examples/resources/texture_formats/sonic_ETC1_RGB.pkm new file mode 100644 index 000000000..c6fc6df4c Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC1_RGB.pkm differ diff --git a/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx new file mode 100644 index 000000000..b01812cb0 Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx differ diff --git a/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.old.pkm b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.old.pkm new file mode 100644 index 000000000..61ac48ce0 Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.old.pkm differ diff --git a/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm new file mode 100644 index 000000000..61ac48ce0 Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm differ diff --git a/examples/resources/texture_formats/sonic_ETC2_RGB.ktx b/examples/resources/texture_formats/sonic_ETC2_RGB.ktx new file mode 100644 index 000000000..7f1207f7c Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC2_RGB.ktx differ diff --git a/examples/resources/texture_formats/sonic_ETC2_RGB.pkm b/examples/resources/texture_formats/sonic_ETC2_RGB.pkm new file mode 100644 index 000000000..f290f019a Binary files /dev/null and b/examples/resources/texture_formats/sonic_ETC2_RGB.pkm differ diff --git a/examples/resources/texture_formats/sonic_GRAYSCALE.pvr b/examples/resources/texture_formats/sonic_GRAYSCALE.pvr new file mode 100644 index 000000000..d31e26519 Binary files /dev/null and b/examples/resources/texture_formats/sonic_GRAYSCALE.pvr differ diff --git a/examples/resources/texture_formats/sonic_L8A8.pvr b/examples/resources/texture_formats/sonic_L8A8.pvr new file mode 100644 index 000000000..ccf5932e2 Binary files /dev/null and b/examples/resources/texture_formats/sonic_L8A8.pvr differ diff --git a/examples/resources/texture_formats/sonic_PVRT_RGB.pvr b/examples/resources/texture_formats/sonic_PVRT_RGB.pvr new file mode 100644 index 000000000..22f3f66a1 Binary files /dev/null and b/examples/resources/texture_formats/sonic_PVRT_RGB.pvr differ diff --git a/examples/resources/texture_formats/sonic_PVRT_RGBA.pvr b/examples/resources/texture_formats/sonic_PVRT_RGBA.pvr new file mode 100644 index 000000000..feb9aeafb Binary files /dev/null and b/examples/resources/texture_formats/sonic_PVRT_RGBA.pvr differ diff --git a/examples/resources/texture_formats/sonic_PVRT_RGBA_2bpp.pvr b/examples/resources/texture_formats/sonic_PVRT_RGBA_2bpp.pvr new file mode 100644 index 000000000..9147e1bbc Binary files /dev/null and b/examples/resources/texture_formats/sonic_PVRT_RGBA_2bpp.pvr differ diff --git a/examples/resources/texture_formats/sonic_PVRT_RGB_2bpp.pvr b/examples/resources/texture_formats/sonic_PVRT_RGB_2bpp.pvr new file mode 100644 index 000000000..2a8aea8c9 Binary files /dev/null and b/examples/resources/texture_formats/sonic_PVRT_RGB_2bpp.pvr differ diff --git a/examples/resources/texture_formats/sonic_R4G4B4A4.pvr b/examples/resources/texture_formats/sonic_R4G4B4A4.pvr new file mode 100644 index 000000000..3f7368a37 Binary files /dev/null and b/examples/resources/texture_formats/sonic_R4G4B4A4.pvr differ diff --git a/examples/resources/texture_formats/sonic_R5G5B5A1.pvr b/examples/resources/texture_formats/sonic_R5G5B5A1.pvr new file mode 100644 index 000000000..c7fa098d2 Binary files /dev/null and b/examples/resources/texture_formats/sonic_R5G5B5A1.pvr differ diff --git a/examples/resources/texture_formats/sonic_R5G6B5.dds b/examples/resources/texture_formats/sonic_R5G6B5.dds new file mode 100644 index 000000000..217da954f Binary files /dev/null and b/examples/resources/texture_formats/sonic_R5G6B5.dds differ diff --git a/examples/resources/texture_formats/sonic_R5G6B5.pvr b/examples/resources/texture_formats/sonic_R5G6B5.pvr new file mode 100644 index 000000000..9bb8320e2 Binary files /dev/null and b/examples/resources/texture_formats/sonic_R5G6B5.pvr differ diff --git a/examples/resources/texture_formats/sonic_R8G8B8.pvr b/examples/resources/texture_formats/sonic_R8G8B8.pvr new file mode 100644 index 000000000..072cf3ef2 Binary files /dev/null and b/examples/resources/texture_formats/sonic_R8G8B8.pvr differ diff --git a/examples/resources/texture_formats/sonic_R8G8B8A8.pvr b/examples/resources/texture_formats/sonic_R8G8B8A8.pvr new file mode 100644 index 000000000..f82534f9a Binary files /dev/null and b/examples/resources/texture_formats/sonic_R8G8B8A8.pvr differ diff --git a/examples/resources/texture_formats/sonic_R8G8B8A8.raw b/examples/resources/texture_formats/sonic_R8G8B8A8.raw new file mode 100644 index 000000000..fc5858e7d Binary files /dev/null and b/examples/resources/texture_formats/sonic_R8G8B8A8.raw differ diff --git a/examples/shapes_basic_shapes.c b/examples/shapes_basic_shapes.c index 4ae9f4df8..4b14af89d 100644 --- a/examples/shapes_basic_shapes.c +++ b/examples/shapes_basic_shapes.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/shapes_colors_palette.c b/examples/shapes_colors_palette.c index 926dcdf8a..3e1611145 100644 --- a/examples/shapes_colors_palette.c +++ b/examples/shapes_colors_palette.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/shapes_logo_raylib.c b/examples/shapes_logo_raylib.c index a9e5104a2..3dd8fbf39 100644 --- a/examples/shapes_logo_raylib.c +++ b/examples/shapes_logo_raylib.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/shapes_logo_raylib_anim.c b/examples/shapes_logo_raylib_anim.c index cd3a4aa63..d08313782 100644 --- a/examples/shapes_logo_raylib_anim.c +++ b/examples/shapes_logo_raylib_anim.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.1 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/text_font_select.c b/examples/text_font_select.c index 25825aba6..fe586db86 100644 --- a/examples/text_font_select.c +++ b/examples/text_font_select.c @@ -2,10 +2,10 @@ * * raylib [text] example - Font selector * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (@raysan5) +* Copyright (c) 2015 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -41,7 +41,7 @@ int main() const char text[50] = "THIS is THE FONT you SELECTED!"; // Main text - Vector2 textSize = MeasureTextEx(fonts[currentFont], text, GetFontBaseSize(fonts[currentFont])*3, 1); + Vector2 textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1); Vector2 mousePoint; @@ -118,7 +118,7 @@ int main() } // Text measurement for better positioning on screen - textSize = MeasureTextEx(fonts[currentFont], text, GetFontBaseSize(fonts[currentFont])*3, 1); + textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1); //---------------------------------------------------------------------------------- // Draw @@ -140,7 +140,7 @@ int main() DrawText("NEXT", 700, positionY + 13, 20, btnNextOutColor); DrawTextEx(fonts[currentFont], text, (Vector2){ screenWidth/2 - textSize.x/2, - 260 + (70 - textSize.y)/2 }, GetFontBaseSize(fonts[currentFont])*3, + 260 + (70 - textSize.y)/2 }, fonts[currentFont].size*3, 1, colors[currentFont]); EndDrawing(); diff --git a/examples/text_font_select.png b/examples/text_font_select.png index 27bf94325..65040df67 100644 Binary files a/examples/text_font_select.png and b/examples/text_font_select.png differ diff --git a/examples/text_format_text.c b/examples/text_format_text.c index 516e3ecf4..ca28be742 100644 --- a/examples/text_format_text.c +++ b/examples/text_format_text.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.1 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/text_rbmf_fonts.c b/examples/text_rbmf_fonts.c index a521862bd..b4bd851bd 100644 --- a/examples/text_rbmf_fonts.c +++ b/examples/text_rbmf_fonts.c @@ -5,10 +5,10 @@ * NOTE: raylib is distributed with some free to use fonts (even for commercial pourposes!) * To view details and credits for those fonts, check raylib license file * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2015 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -50,8 +50,8 @@ int main() for (int i = 0; i < 8; i++) { - positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], GetFontBaseSize(fonts[i])*2, spacings[i]).x/2; - positions[i].y = 60 + GetFontBaseSize(fonts[i]) + 50*i; + positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], fonts[i].size*2, spacings[i]).x/2; + positions[i].y = 60 + fonts[i].size + 50*i; } Color colors[8] = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD }; @@ -76,7 +76,7 @@ int main() for (int i = 0; i < 8; i++) { - DrawTextEx(fonts[i], messages[i], positions[i], GetFontBaseSize(fonts[i])*2, spacings[i], colors[i]); + DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].size*2, spacings[i], colors[i]); } EndDrawing(); diff --git a/examples/text_rbmf_fonts.png b/examples/text_rbmf_fonts.png index 58f6d83f6..c047c5037 100644 Binary files a/examples/text_rbmf_fonts.png and b/examples/text_rbmf_fonts.png differ diff --git a/examples/text_sprite_fonts.c b/examples/text_sprite_fonts.c index e27e8c085..c73eda854 100644 --- a/examples/text_sprite_fonts.c +++ b/examples/text_sprite_fonts.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -31,14 +31,14 @@ int main() Vector2 fontPosition1, fontPosition2, fontPosition3; - fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, GetFontBaseSize(font1), -3).x/2; - fontPosition1.y = screenHeight/2 - GetFontBaseSize(font1)/2 - 80; + fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, font1.size, -3).x/2; + fontPosition1.y = screenHeight/2 - font1.size/2 - 80; - fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, GetFontBaseSize(font2), -2).x/2; - fontPosition2.y = screenHeight/2 - GetFontBaseSize(font2)/2 - 10; + fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, font2.size, -2).x/2; + fontPosition2.y = screenHeight/2 - font2.size/2 - 10; - fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, GetFontBaseSize(font3), 2).x/2; - fontPosition3.y = screenHeight/2 - GetFontBaseSize(font3)/2 + 50; + fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, font3.size, 2).x/2; + fontPosition3.y = screenHeight/2 - font3.size/2 + 50; //-------------------------------------------------------------------------------------- @@ -56,9 +56,9 @@ int main() ClearBackground(RAYWHITE); - DrawTextEx(font1, msg1, fontPosition1, GetFontBaseSize(font1), -3, WHITE); - DrawTextEx(font2, msg2, fontPosition2, GetFontBaseSize(font2), -2, WHITE); - DrawTextEx(font3, msg3, fontPosition3, GetFontBaseSize(font3), 2, WHITE); + DrawTextEx(font1, msg1, fontPosition1, font1.size, -3, WHITE); + DrawTextEx(font2, msg2, fontPosition2, font2.size, -2, WHITE); + DrawTextEx(font3, msg3, fontPosition3, font3.size, 2, WHITE); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/textures_formats_loading.c b/examples/textures_formats_loading.c new file mode 100644 index 000000000..a758fe278 --- /dev/null +++ b/examples/textures_formats_loading.c @@ -0,0 +1,244 @@ +/******************************************************************************************* +* +* raylib [textures] example - texture formats loading (compressed and uncompressed) +* +* NOTE: This example requires raylib OpenGL 3.3+ or ES2 versions for compressed textures, +* OpenGL 1.1 does not support compressed textures, only uncompressed ones. +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define NUM_TEXTURES 24 + +typedef enum { + PNG_R8G8B8A8 = 0, + PVR_GRAYSCALE, + PVR_GRAY_ALPHA, + PVR_R5G6B5, + PVR_R5G5B5A1, + PVR_R4G4B4A4, + DDS_R5G6B5, + DDS_R5G5B5A1, + DDS_R4G4B4A4, + DDS_R8G8B8A8, + DDS_DXT1_RGB, + DDS_DXT1_RGBA, + DDS_DXT3_RGBA, + DDS_DXT5_RGBA, + PKM_ETC1_RGB, + PKM_ETC2_RGB, + PKM_ETC2_EAC_RGBA, + KTX_ETC1_RGB, + KTX_ETC2_RGB, + KTX_ETC2_EAC_RGBA, + ASTC_4x4_LDR, + ASTC_8x8_LDR, + PVR_PVRT_RGB, + PVR_PVRT_RGBA + +} TextureFormats; + +static const char *formatText[] = { + "PNG_R8G8B8A8", + "PVR_GRAYSCALE", + "PVR_GRAY_ALPHA", + "PVR_R5G6B5", + "PVR_R5G5B5A1", + "PVR_R4G4B4A4", + "DDS_R5G6B5", + "DDS_R5G5B5A1", + "DDS_R4G4B4A4", + "DDS_R8G8B8A8", + "DDS_DXT1_RGB", + "DDS_DXT1_RGBA", + "DDS_DXT3_RGBA", + "DDS_DXT5_RGBA", + "PKM_ETC1_RGB", + "PKM_ETC2_RGB", + "PKM_ETC2_EAC_RGBA", + "KTX_ETC1_RGB", + "KTX_ETC2_RGB", + "KTX_ETC2_EAC_RGBA", + "ASTC_4x4_LDR", + "ASTC_8x8_LDR", + "PVR_PVRT_RGB", + "PVR_PVRT_RGBA" +}; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 480; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture formats loading"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + + Texture2D sonic[NUM_TEXTURES]; + + sonic[PNG_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic.png"); + + // Load UNCOMPRESSED PVR texture data + sonic[PVR_GRAYSCALE] = LoadTexture("resources/texture_formats/sonic_GRAYSCALE.pvr"); + sonic[PVR_GRAY_ALPHA] = LoadTexture("resources/texture_formats/sonic_L8A8.pvr"); + sonic[PVR_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.pvr"); + sonic[PVR_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_R5G5B5A1.pvr"); + sonic[PVR_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_R4G4B4A4.pvr"); + + // Load UNCOMPRESSED DDS texture data + sonic[DDS_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.dds"); + sonic[DDS_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_A1R5G5B5.dds"); + sonic[DDS_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_A4R4G4B4.dds"); + sonic[DDS_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic_A8R8G8B8.dds"); + + // Load COMPRESSED DXT DDS texture data (if supported) + sonic[DDS_DXT1_RGB] = LoadTexture("resources/texture_formats/sonic_DXT1_RGB.dds"); + sonic[DDS_DXT1_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT1_RGBA.dds"); + sonic[DDS_DXT3_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT3_RGBA.dds"); + sonic[DDS_DXT5_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT5_RGBA.dds"); + + // Load COMPRESSED ETC texture data (if supported) + sonic[PKM_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.pkm"); + sonic[PKM_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.pkm"); + sonic[PKM_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm"); + + sonic[KTX_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.ktx"); + sonic[KTX_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.ktx"); + sonic[KTX_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx"); + + // Load COMPRESSED ASTC texture data (if supported) + sonic[ASTC_4x4_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_4x4_ldr.astc"); + sonic[ASTC_8x8_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_8x8_ldr.astc"); + + // Load COMPRESSED PVR texture data (if supported) + sonic[PVR_PVRT_RGB] = LoadTexture("resources/texture_formats/sonic_PVRT_RGB.pvr"); + sonic[PVR_PVRT_RGBA] = LoadTexture("resources/texture_formats/sonic_PVRT_RGBA.pvr"); + + int selectedFormat = PNG_R8G8B8A8; + + Rectangle selectRecs[NUM_TEXTURES]; + + for (int i = 0; i < NUM_TEXTURES; i++) + { + if (i < NUM_TEXTURES/2) selectRecs[i] = (Rectangle){ 40, 45 + 32*i, 150, 30 }; + else selectRecs[i] = (Rectangle){ 40 + 152, 45 + 32*(i - NUM_TEXTURES/2), 150, 30 }; + } + + // Texture sizes in KB + float textureSizes[NUM_TEXTURES] = { + 512*512*32/8/1024, //PNG_R8G8B8A8 (32 bpp) + 512*512*8/8/1024, //PVR_GRAYSCALE (8 bpp) + 512*512*16/8/1024, //PVR_GRAY_ALPHA (16 bpp) + 512*512*16/8/1024, //PVR_R5G6B5 (16 bpp) + 512*512*16/8/1024, //PVR_R5G5B5A1 (16 bpp) + 512*512*16/8/1024, //PVR_R4G4B4A4 (16 bpp) + 512*512*16/8/1024, //DDS_R5G6B5 (16 bpp) + 512*512*16/8/1024, //DDS_R5G5B5A1 (16 bpp) + 512*512*16/8/1024, //DDS_R4G4B4A4 (16 bpp) + 512*512*32/8/1024, //DDS_R8G8B8A8 (32 bpp) + 512*512*4/8/1024, //DDS_DXT1_RGB (4 bpp) -Compressed- + 512*512*4/8/1024, //DDS_DXT1_RGBA (4 bpp) -Compressed- + 512*512*8/8/1024, //DDS_DXT3_RGBA (8 bpp) -Compressed- + 512*512*8/8/1024, //DDS_DXT5_RGBA (8 bpp) -Compressed- + 512*512*4/8/1024, //PKM_ETC1_RGB (4 bpp) -Compressed- + 512*512*4/8/1024, //PKM_ETC2_RGB (4 bpp) -Compressed- + 512*512*8/8/1024, //PKM_ETC2_EAC_RGBA (8 bpp) -Compressed- + 512*512*4/8/1024, //KTX_ETC1_RGB (4 bpp) -Compressed- + 512*512*4/8/1024, //KTX_ETC2_RGB (4 bpp) -Compressed- + 512*512*8/8/1024, //KTX_ETC2_EAC_RGBA (8 bpp) -Compressed- + 512*512*8/8/1024, //ASTC_4x4_LDR (8 bpp) -Compressed- + 512*512*2/8/1024, //ASTC_8x8_LDR (2 bpp) -Compressed- + 512*512*4/8/1024, //PVR_PVRT_RGB (4 bpp) -Compressed- + 512*512*4/8/1024, //PVR_PVRT_RGBA (4 bpp) -Compressed- + }; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsKeyPressed(KEY_DOWN)) + { + selectedFormat++; + if (selectedFormat >= NUM_TEXTURES) selectedFormat = 0; + } + else if (IsKeyPressed(KEY_UP)) + { + selectedFormat--; + if (selectedFormat < 0) selectedFormat = NUM_TEXTURES - 1; + } + else if (IsKeyPressed(KEY_RIGHT)) + { + if (selectedFormat < NUM_TEXTURES/2) selectedFormat += NUM_TEXTURES/2; + } + else if (IsKeyPressed(KEY_LEFT)) + { + if (selectedFormat >= NUM_TEXTURES/2) selectedFormat -= NUM_TEXTURES/2; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw rectangles + for (int i = 0; i < NUM_TEXTURES; i++) + { + if (i == selectedFormat) + { + DrawRectangleRec(selectRecs[i], SKYBLUE); + DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE); + DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)/2, selectRecs[i].y + 11, 10, DARKBLUE); + } + else + { + DrawRectangleRec(selectRecs[i], LIGHTGRAY); + DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY); + DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)/2, selectRecs[i].y + 11, 10, DARKGRAY); + } + } + + // Draw selected texture + if (sonic[selectedFormat].id != 0) + { + DrawTexture(sonic[selectedFormat], 350, 0, WHITE); + } + else + { + DrawRectangleLines(488, 165, 200, 110, DARKGRAY); + DrawText("FORMAT", 550, 180, 20, MAROON); + DrawText("NOT SUPPORTED", 500, 210, 20, MAROON); + DrawText("ON YOUR GPU", 520, 240, 20, MAROON); + } + + DrawText("Select texture format (use cursor keys):", 40, 26, 10, DARKGRAY); + DrawText("Required GPU memory size (VRAM):", 40, 442, 10, DARKGRAY); + DrawText(FormatText("%4.0f KB", textureSizes[selectedFormat]), 240, 435, 20, DARKBLUE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + for (int i = 0; i < NUM_TEXTURES; i++) UnloadTexture(sonic[i]); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures_formats_loading.png b/examples/textures_formats_loading.png new file mode 100644 index 000000000..4cdb2f13b Binary files /dev/null and b/examples/textures_formats_loading.png differ diff --git a/examples/textures_logo_raylib.c b/examples/textures_logo_raylib.c index f4aeb738f..2ebf08672 100644 --- a/examples/textures_logo_raylib.c +++ b/examples/textures_logo_raylib.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/textures_particles_trail_blending.c b/examples/textures_particles_trail_blending.c new file mode 100644 index 000000000..1e7abf7e3 --- /dev/null +++ b/examples/textures_particles_trail_blending.c @@ -0,0 +1,132 @@ +/******************************************************************************************* +* +* raylib example - particles trail blending +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define MAX_PARTICLES 200 + +typedef struct { + Vector2 position; + Color color; + float alpha; + float size; + float rotation; + bool active; // NOTE: Use it to activate/deactive particle +} Particle; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles trail blending"); + + // Particles pool, reuse them! + Particle mouseTail[MAX_PARTICLES]; + + // Initialize particles + for (int i = 0; i < MAX_PARTICLES; i++) + { + mouseTail[i].position = (Vector2){ 0, 0 }; + mouseTail[i].color = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 }; + mouseTail[i].alpha = 1.0f; + mouseTail[i].size = (float)GetRandomValue(1, 30)/20; + mouseTail[i].rotation = GetRandomValue(0, 360); + mouseTail[i].active = false; + } + + float gravity = 3; + + Texture2D smoke = LoadTexture("resources/smoke.png"); + + int blending = BLEND_ALPHA; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + // Activate one particle every frame and Update active particles + // NOTE: Particles initial position should be mouse position when activated + // NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0) + // NOTE: When a particle disappears, active = false and it can be reused. + for (int i = 0; i < MAX_PARTICLES; i++) + { + if (!mouseTail[i].active) + { + mouseTail[i].active = true; + mouseTail[i].alpha = 1.0f; + mouseTail[i].position = GetMousePosition(); + i = MAX_PARTICLES; + } + } + + for (int i = 0; i < MAX_PARTICLES; i++) + { + if (mouseTail[i].active) + { + mouseTail[i].position.y += gravity; + mouseTail[i].alpha -= 0.01f; + + if (mouseTail[i].alpha <= 0.0f) mouseTail[i].active = false; + + mouseTail[i].rotation += 5; + } + } + + if (IsKeyPressed(KEY_SPACE)) + { + if (blending == BLEND_ALPHA) blending = BLEND_ADDITIVE; + else blending = BLEND_ALPHA; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(DARKGRAY); + + SetBlendMode(blending); + + // Draw active particles + for (int i = 0; i < MAX_PARTICLES; i++) + { + if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height }, + (Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size }, + (Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation, + Fade(mouseTail[i].color, mouseTail[i].alpha)); + } + + DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, RAYWHITE); + + if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, RAYWHITE); + else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(smoke); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures_particles_trail_blending.png b/examples/textures_particles_trail_blending.png new file mode 100644 index 000000000..b0c40fd24 Binary files /dev/null and b/examples/textures_particles_trail_blending.png differ diff --git a/examples/textures_raw_data.c b/examples/textures_raw_data.c new file mode 100644 index 000000000..a4ff71b3c --- /dev/null +++ b/examples/textures_raw_data.c @@ -0,0 +1,90 @@ +/******************************************************************************************* +* +* raylib [textures] example - Load textures from raw data +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include // Required for malloc() and free() + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture from raw data"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + + // Load RAW image data (512x512, 32bit RGBA, no file header) + Image sonicRaw = LoadImageRaw("resources/texture_formats/sonic_R8G8B8A8.raw", 512, 512, UNCOMPRESSED_R8G8B8A8, 0); + Texture2D sonic = LoadTextureFromImage(sonicRaw); // Upload CPU (RAM) image to GPU (VRAM) + UnloadImage(sonicRaw); // Unload CPU (RAM) image data + + // Generate a checked texture by code (1024x1024 pixels) + int width = 1024; + int height = 1024; + + Color *pixels = (Color *)malloc(width*height*sizeof(Color)); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + if (((x/32+y/32)/1)%2 == 0) pixels[y*height + x] = DARKBLUE; + else pixels[y*height + x] = SKYBLUE; + } + } + + // Load pixels data into an image structure and create texture + Image checkedIm = LoadImageEx(pixels, width, height); + Texture2D checked = LoadTextureFromImage(checkedIm); + UnloadImage(checkedIm); // Unload CPU (RAM) image data + free(pixels); // Unload CPU (RAM) pixels data + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.3f)); + DrawTexture(sonic, 330, -20, WHITE); + + DrawText("CHECKED TEXTURE ", 84, 100, 30, DARKBLUE); + DrawText("GENERATED by CODE", 72, 164, 30, DARKBLUE); + DrawText("and RAW IMAGE LOADING", 46, 226, 30, DARKBLUE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(sonic); // Texture unloading + UnloadTexture(checked); // Texture unloading + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures_raw_data.png b/examples/textures_raw_data.png new file mode 100644 index 000000000..374d22665 Binary files /dev/null and b/examples/textures_raw_data.png differ diff --git a/examples/textures_rectangle.c b/examples/textures_rectangle.c index c0fb0d972..61cce9fbe 100644 --- a/examples/textures_rectangle.c +++ b/examples/textures_rectangle.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -20,15 +20,12 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [texture] example - texture rectangle"); - const char textLine1[] = "Lena image is a standard test image which has been in use since 1973."; - const char textLine2[] = "It comprises 512x512 pixels, and it is probably the most widely used"; - const char textLine3[] = "test image for all sorts of image processing algorithms."; - // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - Texture2D texture = LoadTexture("resources/lena.png"); // Texture loading + Texture2D guybrush = LoadTexture("resources/guybrush.png"); // Texture loading - Rectangle eyesRec = { 225, 240, 155, 50 }; // Part of the texture to draw - Vector2 position = { 369, 241 }; + Vector2 position = { 350, 240 }; + Rectangle frameRec = { 0, 0, guybrush.width/7, guybrush.height }; + int currentFrame = 0; //-------------------------------------------------------------------------------------- // Main game loop @@ -36,7 +33,14 @@ int main() { // Update //---------------------------------------------------------------------------------- - // TODO: Update your variables here + if (IsKeyPressed(KEY_RIGHT)) + { + currentFrame++; + + if (currentFrame > 6) currentFrame = 0; + + frameRec.x = currentFrame*guybrush.width/7; + } //---------------------------------------------------------------------------------- // Draw @@ -45,15 +49,19 @@ int main() ClearBackground(RAYWHITE); - DrawText("LENA", 220, 100, 20, PINK); - - DrawTexture(texture, screenWidth/2 - 256, 0, Fade(WHITE, 0.1f)); // Draw background image - - DrawTextureRec(texture, eyesRec, position, WHITE); // Draw eyes part of image - - DrawText(textLine1, 220, 140, 10, DARKGRAY); - DrawText(textLine2, 220, 160, 10, DARKGRAY); - DrawText(textLine3, 220, 180, 10, DARKGRAY); + DrawTexture(guybrush, 35, 40, WHITE); + DrawRectangleLines(35, 40, guybrush.width, guybrush.height, LIME); + + DrawTextureRec(guybrush, frameRec, position, WHITE); // Draw part of the texture + + DrawRectangleLines(35 + frameRec.x, 40 + frameRec.y, frameRec.width, frameRec.height, RED); + + DrawText("PRESS RIGHT KEY to", 540, 310, 10, GRAY); + DrawText("CHANGE DRAWING RECTANGLE", 520, 330, 10, GRAY); + + DrawText("Guybrush Ulysses Threepwood,", 100, 300, 10, GRAY); + DrawText("main character of the Monkey Island series", 80, 320, 10, GRAY); + DrawText("of computer adventure games by LucasArts.", 80, 340, 10, GRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -61,7 +69,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - UnloadTexture(texture); // Texture unloading + UnloadTexture(guybrush); // Texture unloading CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/textures_rectangle.png b/examples/textures_rectangle.png index fb434a8ea..d89404abc 100644 Binary files a/examples/textures_rectangle.png and b/examples/textures_rectangle.png differ diff --git a/examples/textures_srcrec_dstrec.c b/examples/textures_srcrec_dstrec.c index 1f0b56e26..72a209fbe 100644 --- a/examples/textures_srcrec_dstrec.c +++ b/examples/textures_srcrec_dstrec.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.1 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -21,16 +21,23 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [textures] examples - texture source and destination rectangles"); // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - Texture2D texture = LoadTexture("resources/raylib_logo.png"); // Texture loading + Texture2D guybrush = LoadTexture("resources/guybrush.png"); // Texture loading + int frameWidth = guybrush.width/7; + int frameHeight = guybrush.height; + // NOTE: Source rectangle (part of the texture to use for drawing) - Rectangle sourceRec = { 128, 128, 128, 128 }; + Rectangle sourceRec = { 0, 0, frameWidth, frameHeight }; // NOTE: Destination rectangle (screen rectangle where drawing part of texture) - Rectangle destRec = { screenWidth/2, screenHeight/2, 256, 256 }; + Rectangle destRec = { screenWidth/2, screenHeight/2, frameWidth*2, frameHeight*2 }; - // NOTE: Origin of the texture in case of rotation, it's relative to destination rectangle size - Vector2 origin = { 128, 128 }; + // NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size + Vector2 origin = { frameWidth, frameHeight }; + + int rotation = 0; + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -38,7 +45,7 @@ int main() { // Update //---------------------------------------------------------------------------------- - // TODO: Update your variables here + rotation++; //---------------------------------------------------------------------------------- // Draw @@ -48,10 +55,10 @@ int main() ClearBackground(RAYWHITE); // NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw - DrawTexturePro(texture, sourceRec, destRec, origin, 45, LIGHTGRAY); + DrawTexturePro(guybrush, sourceRec, destRec, origin, rotation, WHITE); - DrawLine(destRec.x, 0, destRec.x, screenHeight, RED); - DrawLine(0, destRec.y, screenWidth, destRec.y, RED); + DrawLine(destRec.x, 0, destRec.x, screenHeight, GRAY); + DrawLine(0, destRec.y, screenWidth, destRec.y, GRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -59,7 +66,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - UnloadTexture(texture); // Texture unloading + UnloadTexture(guybrush); // Texture unloading CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/textures_srcrec_dstrec.png b/examples/textures_srcrec_dstrec.png index 95b7130e4..7459d6ecc 100644 Binary files a/examples/textures_srcrec_dstrec.png and b/examples/textures_srcrec_dstrec.png differ diff --git a/examples/textures_to_image.c b/examples/textures_to_image.c new file mode 100644 index 000000000..3ea8e017e --- /dev/null +++ b/examples/textures_to_image.c @@ -0,0 +1,68 @@ +/******************************************************************************************* +* +* raylib [textures] example - Retrieve image data from texture: GetTextureData() +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* This example has been created using raylib 1.1 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture to image"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + + Image image = LoadImage("resources/raylib_logo.png"); // Load image data into CPU memory (RAM) + Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (RAM -> VRAM) + UnloadImage(image); // Unload image data from CPU memory (RAM) + + image = GetTextureData(texture); // Retrieve image data from GPU memory (VRAM -> RAM) + UnloadTexture(texture); // Unload texture from GPU memory (VRAM) + + texture = LoadTextureFromImage(image); // Recreate texture from retrieved image data (RAM -> VRAM) + UnloadImage(image); // Unload retrieved image data from CPU memory (RAM) + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE); + + DrawText("this IS a texture loaded from an image!", 300, 370, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(texture); // Texture unloading + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures_to_image.png b/examples/textures_to_image.png new file mode 100644 index 000000000..410103a5e Binary files /dev/null and b/examples/textures_to_image.png differ diff --git a/src/camera.c b/src/camera.c index 627451fe8..b637b1e4d 100644 --- a/src/camera.c +++ b/src/camera.c @@ -84,12 +84,12 @@ typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_D //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Camera internalCamera = {{2,0,2},{0,0,0},{0,1,0}}; +static Camera internalCamera = {{2, 0, 2}, {0, 0, 0}, {0, 1, 0}}; static Vector2 cameraAngle = { 0, 0 }; -static float cameraTargetDistance = 5; +static float cameraTargetDistance = 5.0f; static Vector2 cameraMousePosition = { 0, 0 }; static Vector2 cameraMouseVariation = { 0, 0 }; -static float mouseSensitivity = 0.003; +static float mouseSensitivity = 0.003f; static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; static int cameraMoveCounter = 0; static int cameraUseGravity = 1; @@ -123,6 +123,7 @@ static int IsKeyDown(int key) { return 0; } //---------------------------------------------------------------------------------- // Select camera mode (multiple camera modes available) +// TODO: Review hardcoded values when changing modes... void SetCameraMode(int mode) { if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) @@ -144,7 +145,7 @@ void SetCameraMode(int mode) cameraTargetDistance = 10; cameraAngle.x = 45 * DEG2RAD; cameraAngle.y = -40 * DEG2RAD; - internalCamera.target = (Vector3){ 0, 0, 0}; + internalCamera.target = (Vector3){ 0, 0, 0 }; ProcessCamera(&internalCamera, &internalCamera.position); ShowCursor(); @@ -154,22 +155,82 @@ void SetCameraMode(int mode) cameraTargetDistance = 10; cameraAngle.x = 225 * DEG2RAD; cameraAngle.y = -40 * DEG2RAD; - internalCamera.target = (Vector3){ 3, 0, 3}; + internalCamera.target = (Vector3){ 0, 0, 0}; ProcessCamera(&internalCamera, &internalCamera.position); } cameraMode = mode; } -// Update camera with position -Camera UpdateCamera(Vector3 *position) +// Update camera (player position is ignored) +void UpdateCamera(Camera *camera) { - // Calculate camera - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); + Vector3 position = { 0, 0, 0 }; + + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); - return internalCamera; + *camera = internalCamera; } +// Update camera and player position (1st person and 3rd person cameras) +void UpdateCameraPlayer(Camera *camera, Vector3 *position) +{ + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); + + *camera = internalCamera; +} + +// Set internal camera position +void SetCameraPosition(Vector3 position) +{ + internalCamera.position = position; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera target +void SetCameraTarget(Vector3 target) +{ + internalCamera.target = target; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set camera pan key to combine with mouse movement (free camera) +void SetCameraPanControl(int panKey) +{ + panControlKey = panKey; +} + +// Set camera alt key to combine with mouse movement (free camera) +void SetCameraAltControl(int altKey) +{ + altControlKey = altKey; +} + +// Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraSmoothZoomControl(int szKey) +{ + smoothZoomControlKey = szKey; +} + +// Set camera move controls (1st person and 3rd person cameras) void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) { cameraMoveControl[MOVE_FRONT] = frontKey; @@ -180,32 +241,12 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, cameraMoveControl[MOVE_DOWN] = downKey; } +// Set camera mouse sensitivity (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity) { - mouseSensitivity = (sensitivity / 10000.0); + mouseSensitivity = (sensitivity/10000.0); } -void SetCameraPanControl(int panKey) -{ - panControlKey = panKey; -} - -void SetCameraAltControl(int altKey) -{ - altControlKey = altKey; -} - -void SetCameraSmoothZoomControl(int szKey) -{ - smoothZoomControlKey = szKey; -} - -void SetCameraTarget(Vector3 target) -{ - internalCamera.target = target; -} - - //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -247,7 +288,9 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; } - cameraMousePosition = mousePosition; + // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call + // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON + cameraMousePosition = GetMousePosition(); // Support for multiple automatic camera modes switch (cameraMode) @@ -298,7 +341,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) } else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) { - cameraTargetDistance -= (mouseWheelMove * CAMERA_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; } @@ -449,8 +492,8 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (isMoving) cameraMoveCounter++; // Camera orientation calculation - cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity; - cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity; + cameraAngle.x += (cameraMouseVariation.x * -mouseSensitivity); + cameraAngle.y += (cameraMouseVariation.y * -mouseSensitivity); // Angle clamp if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP*DEG2RAD; diff --git a/src/camera.h b/src/camera.h index 63d8f7864..ed85320a4 100644 --- a/src/camera.h +++ b/src/camera.h @@ -76,18 +76,20 @@ extern "C" { // Prevents name mangling of functions // Module Functions Declaration //---------------------------------------------------------------------------------- void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) -Camera UpdateCamera(Vector3 *playerPosition); // Update camera and player position (1st person and 3rd person cameras) +void UpdateCamera(Camera *camera); // Update camera (player position is ignored) +void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) -void SetCameraMoveControls(int frontKey, int backKey, - int leftKey, int rightKey, - int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) +void SetCameraPosition(Vector3 position); // Set internal camera position +void SetCameraTarget(Vector3 target); // Set internal camera target void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraMoveControls(int frontKey, int backKey, + int leftKey, int rightKey, + int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameraTarget(Vector3 target); // Set internal camera target #ifdef __cplusplus } diff --git a/src/core.c b/src/core.c index e3c4e10ba..1ebc8a8ff 100644 --- a/src/core.c +++ b/src/core.c @@ -638,6 +638,7 @@ void ShowLogo(void) showLogo = true; } +#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) // Check if a file have been dropped into window bool IsFileDropped(void) { @@ -664,6 +665,7 @@ void ClearDroppedFiles(void) dropFilesCount = 0; } } +#endif // TODO: Gives the ray trace from mouse position Ray GetMouseRay(Vector2 mousePosition, Camera camera) @@ -1007,8 +1009,8 @@ static void InitDisplay(int width, int height) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window - //glfwWindowHint(GLFW_RED_BITS, 8); // Color framebuffer red component bits - //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depth buffer bits (24 by default) + //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits + //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window //glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // Default OpenGL API to use. Alternative: GLFW_OPENGL_ES_API //glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers diff --git a/src/raygui.c b/src/raygui.c new file mode 100644 index 000000000..fd45e1f2d --- /dev/null +++ b/src/raygui.c @@ -0,0 +1,1002 @@ +/********************************************************************************************** +* +* raygui - raylib IMGUI system (Immedite Mode GUI) +* +* Copyright (c) 2015 Kevin Gato, Daniel Nicolás, Sergio Martinez and Ramon Santamaria +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raygui.h" + +#include +#include +#include // Required for malloc(), free() +#include // Required for strcmp() + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// GUI elements states +typedef enum { BUTTON_DEFAULT, BUTTON_HOVER, BUTTON_PRESSED, BUTTON_CLICKED } ButtonState; +typedef enum { TOGGLE_UNACTIVE, TOGGLE_HOVER, TOGGLE_PRESSED, TOGGLE_ACTIVE } ToggleState; +typedef enum { COMBOBOX_UNACTIVE, COMBOBOX_HOVER, COMBOBOX_PRESSED, COMBOBOX_ACTIVE } ComboBoxState; +typedef enum { SPINNER_DEFAULT, SPINNER_HOVER, SPINNER_PRESSED } SpinnerState; +typedef enum { CHECKBOX_STATUS, CHECKBOX_HOVER, CHECKBOX_PRESSED } CheckBoxState; +typedef enum { SLIDER_DEFAULT, SLIDER_HOVER, SLIDER_ACTIVE } SliderState; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- + +//Current GUI style (default light) +static int style[NUM_PROPERTIES] = { + 0xf5f5f5ff, // GLOBAL_BASE_COLOR, + 0xf5f5f5ff, // GLOBAL_BORDER_COLOR, + 0xf5f5f5ff, // GLOBAL_TEXT_COLOR, + 10, // GLOBAL_TEXT_FONTSIZE + 1, // GLOBAL_BORDER_WIDTH + 0xf5f5f5ff, // BACKGROUND_COLOR + 1, // LABEL_BORDER_WIDTH + 0x000000ff, // LABEL_TEXT_COLOR + 20, // LABEL_TEXT_PADDING + 2, // BUTTON_BORDER_WIDTH + 20, // BUTTON_TEXT_PADDING + 0x828282ff, // BUTTON_DEFAULT_BORDER_COLOR + 0xc8c8c8ff, // BUTTON_DEFAULT_INSIDE_COLOR + 0x000000ff, // BUTTON_DEFAULT_TEXT_COLOR + 0xc8c8c8ff, // BUTTON_HOVER_BORDER_COLOR + 0xffffffff, // BUTTON_HOVER_INSIDE_COLOR + 0x000000ff, // BUTTON_HOVER_TEXT_COLOR + 0x7bb0d6ff, // BUTTON_PRESSED_BORDER_COLOR + 0xbcecffff, // BUTTON_PRESSED_INSIDE_COLOR + 0x5f9aa7ff, // BUTTON_PRESSED_TEXT_COLOR + 20, // TOGGLE_TEXT_PADDING + 1, // TOGGLE_BORDER_WIDTH + 0x828282ff, // TOGGLE_DEFAULT_BORDER_COLOR + 0xc8c8c8ff, // TOGGLE_DEFAULT_INSIDE_COLOR + 0x828282ff, // TOGGLE_DEFAULT_TEXT_COLOR + 0xc8c8c8ff, // TOGGLE_HOVER_BORDER_COLOR + 0xffffffff, // TOGGLE_HOVER_INSIDE_COLOR + 0x828282ff, // TOGGLE_HOVER_TEXT_COLOR + 0xbdd7eaff, // TOGGLE_PRESSED_BORDER_COLOR + 0xddf5ffff, // TOGGLE_PRESSED_INSIDE_COLOR + 0xafccd3ff, // TOGGLE_PRESSED_TEXT_COLOR + 0x7bb0d6ff, // TOGGLE_ACTIVE_BORDER_COLOR + 0xbcecffff, // TOGGLE_ACTIVE_INSIDE_COLOR + 0x5f9aa7ff, // TOGGLE_ACTIVE_TEXT_COLOR + 3, // TOGGLEGROUP_PADDING + 1, // SLIDER_BORDER_WIDTH + 1, // SLIDER_BUTTON_BORDER_WIDTH + 0x828282ff, // SLIDER_BORDER_COLOR + 0xc8c8c8ff, // SLIDER_INSIDE_COLOR + 0xbcecffff, // SLIDER_DEFAULT_COLOR + 0xffffffff, // SLIDER_HOVER_COLOR + 0xddf5ffff, // SLIDER_ACTIVE_COLOR + 0x828282ff, // SLIDERBAR_BORDER_COLOR + 0xc8c8c8ff, // SLIDERBAR_INSIDE_COLOR + 0xbcecffff, // SLIDERBAR_DEFAULT_COLOR + 0xffffffff, // SLIDERBAR_HOVER_COLOR + 0xddf5ffff, // SLIDERBAR_ACTIVE_COLOR + 0x828282ff, // SLIDERBAR_ZERO_LINE_COLOR + 0x828282ff, // PROGRESSBAR_BORDER_COLOR + 0xc8c8c8ff, // PROGRESSBAR_INSIDE_COLOR + 0xbcecffff, // PROGRESSBAR_PROGRESS_COLOR + 2, // PROGRESSBAR_BORDER_WIDTH + 0x828282ff, // SPINNER_LABEL_BORDER_COLOR + 0xc8c8c8ff, // SPINNER_LABEL_INSIDE_COLOR + 0x828282ff, // SPINNER_DEFAULT_BUTTON_BORDER_COLOR + 0xc8c8c8ff, // SPINNER_DEFAULT_BUTTON_INSIDE_COLOR + 0x000000ff, // SPINNER_DEFAULT_SYMBOL_COLOR + 0x000000ff, // SPINNER_DEFAULT_TEXT_COLOR + 0xc8c8c8ff, // SPINNER_HOVER_BUTTON_BORDER_COLOR + 0xffffffff, // SPINNER_HOVER_BUTTON_INSIDE_COLOR + 0x000000ff, // SPINNER_HOVER_SYMBOL_COLOR + 0x000000ff, // SPINNER_HOVER_TEXT_COLOR + 0x7bb0d6ff, // SPINNER_PRESSED_BUTTON_BORDER_COLOR + 0xbcecffff, // SPINNER_PRESSED_BUTTON_INSIDE_COLOR + 0x5f9aa7ff, // SPINNER_PRESSED_SYMBOL_COLOR + 0x000000ff, // SPINNER_PRESSED_TEXT_COLOR + 1, // COMBOBOX_PADDING + 30, // COMBOBOX_BUTTON_WIDTH + 30, // COMBOBOX_BUTTON_HEIGHT + 1, // COMBOBOX_BORDER_WIDTH + 0x828282ff, // COMBOBOX_DEFAULT_BORDER_COLOR + 0xc8c8c8ff, // COMBOBOX_DEFAULT_INSIDE_COLOR + 0x828282ff, // COMBOBOX_DEFAULT_TEXT_COLOR + 0x828282ff, // COMBOBOX_DEFAULT_LIST_TEXT_COLOR + 0xc8c8c8ff, // COMBOBOX_HOVER_BORDER_COLOR + 0xffffffff, // COMBOBOX_HOVER_INSIDE_COLOR + 0x828282ff, // COMBOBOX_HOVER_TEXT_COLOR + 0x828282ff, // COMBOBOX_HOVER_LIST_TEXT_COLOR + 0x7bb0d6ff, // COMBOBOX_PRESSED_BORDER_COLOR + 0xbcecffff, // COMBOBOX_PRESSED_INSIDE_COLOR + 0x5f9aa7ff, // COMBOBOX_PRESSED_TEXT_COLOR + 0x0078acff, // COMBOBOX_PRESSED_LIST_BORDER_COLOR + 0x66e7ffff, // COMBOBOX_PRESSED_LIST_INSIDE_COLOR + 0x0078acff, // COMBOBOX_PRESSED_LIST_TEXT_COLOR + 0x828282ff, // CHECKBOX_DEFAULT_BORDER_COLOR + 0xffffffff, // CHECKBOX_DEFAULT_INSIDE_COLOR + 0xc8c8c8ff, // CHECKBOX_HOVER_BORDER_COLOR + 0xffffffff, // CHECKBOX_HOVER_INSIDE_COLOR + 0x66e7ffff, // CHECKBOX_CLICK_BORDER_COLOR + 0xddf5ffff, // CHECKBOX_CLICK_INSIDE_COLOR + 0x7bb0d6ff, // CHECKBOX_STATUS_ACTIVE_COLOR + 4, // CHECKBOX_INSIDE_WIDTH + 1, // TEXTBOX_BORDER_WIDTH + 0x828282ff, // TEXTBOX_BORDER_COLOR + 0xf5f5f5ff, // TEXTBOX_INSIDE_COLOR + 0x000000ff, // TEXTBOX_TEXT_COLOR + 0x000000ff, // TEXTBOX_LINE_COLOR + 10 // TEXTBOX_TEXT_FONTSIZE +}; + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static Color ColorMultiply(Color baseColor, float value); + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Label element, show text +void GuiLabel(Rectangle bounds, const char *text) +{ + GuiLabelEx(bounds,text, GetColor(style[LABEL_TEXT_COLOR]), BLANK, BLANK); +} + +// Label element extended, configurable colors +void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color border, Color inner) +{ + int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); + int textHeight = GetFontBaseSize(GetDefaultFont()); + + if (bounds.width < textWidth) bounds.width = textWidth + style[LABEL_TEXT_PADDING]; + if (bounds.height < textHeight) bounds.height = textHeight + style[LABEL_TEXT_PADDING]/2; + + // Draw control + //-------------------------------------------------------------------- + DrawRectangleRec(bounds, border); + DrawRectangle(bounds.x + style[LABEL_BORDER_WIDTH], bounds.y + style[LABEL_BORDER_WIDTH], bounds.width - (2 * style[LABEL_BORDER_WIDTH]), bounds.height - (2 * style[LABEL_BORDER_WIDTH]), inner); + DrawText(text, bounds.x + ((bounds.width/2) - (textWidth/2)), bounds.y + ((bounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], textColor); + //-------------------------------------------------------------------- +} + +// Button element, returns true when clicked +bool GuiButton(Rectangle bounds, const char *text) +{ + ButtonState buttonState = BUTTON_DEFAULT; + + Rectangle button = bounds; + Vector2 mousePoint = GetMousePosition(); + + int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); + int textHeight = GetFontBaseSize(GetDefaultFont()); + + if (button.width < textWidth) button.width = textWidth + style[BUTTON_TEXT_PADDING]; + if (button.height < textHeight) button.height = textHeight + style[BUTTON_TEXT_PADDING]/2; + + if (CheckCollisionPointRec(mousePoint, button)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) buttonState = BUTTON_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) buttonState = BUTTON_CLICKED; + else buttonState = BUTTON_HOVER; + } + + // Draw control + //-------------------------------------------------------------------- + switch (buttonState) + { + case BUTTON_DEFAULT: + { + DrawRectangleRec(button, GetColor(style[BUTTON_DEFAULT_BORDER_COLOR])); + DrawRectangle((int)(button.x + style[BUTTON_BORDER_WIDTH]), (int)(button.y + style[BUTTON_BORDER_WIDTH]) , (int)(button.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(button.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_DEFAULT_INSIDE_COLOR])); + DrawText(text, button.x + ((button.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), button.y + ((button.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_DEFAULT_TEXT_COLOR])); + } break; + case BUTTON_HOVER: + { + DrawRectangleRec(button, GetColor(style[BUTTON_HOVER_BORDER_COLOR])); + DrawRectangle((int)(button.x + style[BUTTON_BORDER_WIDTH]), (int)(button.y + style[BUTTON_BORDER_WIDTH]) , (int)(button.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(button.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_HOVER_INSIDE_COLOR])); + DrawText(text, button.x + ((button.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), button.y + ((button.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_HOVER_TEXT_COLOR])); + } break; + case BUTTON_PRESSED: + { + DrawRectangleRec(button, GetColor(style[BUTTON_PRESSED_BORDER_COLOR])); + DrawRectangle((int)(button.x + style[BUTTON_BORDER_WIDTH]), (int)(button.y + style[BUTTON_BORDER_WIDTH]) , (int)(button.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(button.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_PRESSED_INSIDE_COLOR])); + DrawText(text, button.x + ((button.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), button.y + ((button.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_PRESSED_TEXT_COLOR])); + } break; + case BUTTON_CLICKED: + { + DrawRectangleRec(button, GetColor(style[BUTTON_PRESSED_BORDER_COLOR])); + DrawRectangle((int)(button.x + style[BUTTON_BORDER_WIDTH]), (int)(button.y + style[BUTTON_BORDER_WIDTH]) , (int)(button.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(button.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_PRESSED_INSIDE_COLOR])); + } break; + default: break; + } + //------------------------------------------------------------------ + + if (buttonState == BUTTON_CLICKED) return true; + else return false; +} + +// Toggle Button element, returns true when active +bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle) +{ + ToggleState toggleState = TOGGLE_UNACTIVE; + Rectangle toggleButton = bounds; + Vector2 mousePoint = GetMousePosition(); + + int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]); + int textHeight = GetFontBaseSize(GetDefaultFont()); + + if (toggleButton.width < textWidth) toggleButton.width = textWidth + style[TOGGLE_TEXT_PADDING]; + if (toggleButton.height < textHeight) toggleButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2; + if (CheckCollisionPointRec(mousePoint, toggleButton)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) toggleState = TOGGLE_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) toggleState = TOGGLE_ACTIVE; + else toggleState = TOGGLE_HOVER; + } + + if (toggleState == TOGGLE_ACTIVE && !toggle) toggle = true; + if (toggle) toggleState = TOGGLE_ACTIVE; + + // Draw control + //-------------------------------------------------------------------- + switch (toggleState) + { + case TOGGLE_UNACTIVE: + { + DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_DEFAULT_BORDER_COLOR])); + DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_DEFAULT_INSIDE_COLOR])); + DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_DEFAULT_TEXT_COLOR])); + } break; + case TOGGLE_HOVER: + { + DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_HOVER_BORDER_COLOR])); + DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_HOVER_INSIDE_COLOR])); + DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_HOVER_TEXT_COLOR])); + } break; + case TOGGLE_PRESSED: + { + DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_PRESSED_BORDER_COLOR])); + DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_PRESSED_INSIDE_COLOR])); + DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_PRESSED_TEXT_COLOR])); + } break; + case TOGGLE_ACTIVE: + { + DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_ACTIVE_BORDER_COLOR])); + DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_ACTIVE_INSIDE_COLOR])); + DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_ACTIVE_TEXT_COLOR])); + } break; + default: break; + } + //-------------------------------------------------------------------- + + return toggle; +} + +// Toggle Group element, returns toggled button index +int GuiToggleGroup(Rectangle bounds, int toggleNum, char **toggleText, int toggleActive) +{ + for (int i = 0; i < toggleNum; i++) + { + if (i == toggleActive) GuiToggleButton((Rectangle){bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]),bounds.y,bounds.width,bounds.height}, toggleText[i], true); + else if (GuiToggleButton((Rectangle){bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]),bounds.y,bounds.width,bounds.height}, toggleText[i], false) == true) toggleActive = i; + } + + return toggleActive; +} + +// Combo Box element, returns selected item index +int GuiComboBox(Rectangle bounds, int comboNum, char **comboText, int comboActive) +{ + ComboBoxState comboBoxState = COMBOBOX_UNACTIVE; + Rectangle comboBoxButton = bounds; + Rectangle click = { bounds.x + bounds.width + style[COMBOBOX_PADDING], bounds.y, style[COMBOBOX_BUTTON_WIDTH], bounds.height }; + Vector2 mousePoint = GetMousePosition(); + + int textHeight = GetFontBaseSize(GetDefaultFont()); + + for (int i = 0; i < comboNum; i++) + { + if (i == comboActive) + { + int textWidth = MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE]); + + if (comboBoxButton.width < textWidth) comboBoxButton.width = textWidth + style[TOGGLE_TEXT_PADDING]; + if (comboBoxButton.height < textHeight) comboBoxButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2; + + if (CheckCollisionPointRec(mousePoint, comboBoxButton) || CheckCollisionPointRec(mousePoint, click)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) comboBoxState = COMBOBOX_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) comboBoxState = COMBOBOX_ACTIVE; + else comboBoxState = COMBOBOX_HOVER; + } + + // Draw control + //-------------------------------------------------------------------- + switch (comboBoxState) + { + case COMBOBOX_UNACTIVE: + { + DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_DEFAULT_BORDER_COLOR])); + DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_DEFAULT_INSIDE_COLOR])); + + DrawRectangleRec(click, GetColor(style[COMBOBOX_DEFAULT_BORDER_COLOR])); + DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_DEFAULT_INSIDE_COLOR])); + DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_DEFAULT_LIST_TEXT_COLOR])); + DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_DEFAULT_TEXT_COLOR])); + } break; + case COMBOBOX_HOVER: + { + DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_HOVER_BORDER_COLOR])); + DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_HOVER_INSIDE_COLOR])); + + DrawRectangleRec(click, GetColor(style[COMBOBOX_HOVER_BORDER_COLOR])); + DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_HOVER_INSIDE_COLOR])); + DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_HOVER_LIST_TEXT_COLOR])); + DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_HOVER_TEXT_COLOR])); + } break; + case COMBOBOX_PRESSED: + { + DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_PRESSED_BORDER_COLOR])); + DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_INSIDE_COLOR])); + + DrawRectangleRec(click, GetColor(style[COMBOBOX_PRESSED_LIST_BORDER_COLOR])); + DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR])); + DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_LIST_TEXT_COLOR])); + DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_TEXT_COLOR])); + } break; + case COMBOBOX_ACTIVE: + { + DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_PRESSED_BORDER_COLOR])); + DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_INSIDE_COLOR])); + + DrawRectangleRec(click, GetColor(style[COMBOBOX_PRESSED_LIST_BORDER_COLOR])); + DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR])); + DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_LIST_TEXT_COLOR])); + DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_TEXT_COLOR])); + } break; + default: break; + } + + //DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[]globalTextFontSize)/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[]globalTextFontSize/2)), style[]globalTextFontSize, COMBOBOX_PRESSED_TEXT_COLOR); + //-------------------------------------------------------------------- + } + } + + if (CheckCollisionPointRec(GetMousePosition(), bounds) || CheckCollisionPointRec(GetMousePosition(), click)) + { + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + comboActive += 1; + if(comboActive >= comboNum) comboActive = 0; + } + } + + return comboActive; +} + +// Check Box element, returns true when active +bool GuiCheckBox(Rectangle checkBoxBounds, const char *text, bool checked) +{ + CheckBoxState checkBoxState = CHECKBOX_STATUS; + Rectangle checkBoxRec = checkBoxBounds; + Vector2 mousePoint = GetMousePosition(); + + if (CheckCollisionPointRec(mousePoint, checkBoxRec)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) checkBoxState = CHECKBOX_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + { + checkBoxState = CHECKBOX_STATUS; + checked = !checked; + } + else checkBoxState = CHECKBOX_HOVER; + } + + // Draw control + //-------------------------------------------------------------------- + switch (checkBoxState) + { + case CHECKBOX_HOVER: + { + DrawRectangleRec(checkBoxRec, GetColor(style[CHECKBOX_HOVER_BORDER_COLOR])); + DrawRectangle((int)(checkBoxRec.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxRec.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_HOVER_INSIDE_COLOR])); + } break; + case CHECKBOX_STATUS: + { + DrawRectangleRec(checkBoxRec, GetColor(style[CHECKBOX_DEFAULT_BORDER_COLOR])); + DrawRectangle((int)(checkBoxRec.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxRec.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_DEFAULT_INSIDE_COLOR])); + } break; + case CHECKBOX_PRESSED: + { + DrawRectangleRec(checkBoxRec, GetColor(style[CHECKBOX_CLICK_BORDER_COLOR])); + DrawRectangle((int)(checkBoxRec.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxRec.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxRec.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_CLICK_INSIDE_COLOR])); + } break; + default: break; + } + + if (checked) + { + DrawRectangle((int)(checkBoxRec.x + style[CHECKBOX_INSIDE_WIDTH]), (int)(checkBoxRec.y + style[CHECKBOX_INSIDE_WIDTH]), (int)(checkBoxRec.width - (2*style[CHECKBOX_INSIDE_WIDTH])), (int)(checkBoxRec.height - (2*style[CHECKBOX_INSIDE_WIDTH])), GetColor(style[CHECKBOX_STATUS_ACTIVE_COLOR])); + } + //-------------------------------------------------------------------- + + return checked; +} + +// Slider element, returns selected value +float GuiSlider(Rectangle bounds, float value, float minValue, float maxValue) +{ + SliderState sliderState = SLIDER_DEFAULT; + float buttonTravelDistance = 0; + float sliderPos = 0; + Vector2 mousePoint = GetMousePosition(); + + if (value < minValue) value = minValue; + else if (value >= maxValue) value = maxValue; + + sliderPos = (value - minValue)/(maxValue - minValue); + + Rectangle sliderButton; + sliderButton.width = ((int)(bounds.width - (2 * style[SLIDER_BUTTON_BORDER_WIDTH]))/10 - 8); + sliderButton.height =((int)(bounds.height - ( 2 * style[SLIDER_BORDER_WIDTH] + 2 * style[SLIDER_BUTTON_BORDER_WIDTH]))); + + float sliderButtonMinPos = bounds.x + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH]; + float sliderButtonMaxPos = bounds.x + bounds.width - (style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH] + sliderButton.width); + + buttonTravelDistance = sliderButtonMaxPos - sliderButtonMinPos; + + sliderButton.x = ((int)(bounds.x + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH]) + (sliderPos * buttonTravelDistance)); + sliderButton.y = ((int)(bounds.y + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH])); + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + sliderState = SLIDER_HOVER; + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) sliderState = SLIDER_ACTIVE; + + if ((sliderState == SLIDER_ACTIVE) && (IsMouseButtonDown(MOUSE_LEFT_BUTTON))) + { + sliderButton.x = mousePoint.x - sliderButton.width / 2; + + if (sliderButton.x <= sliderButtonMinPos) sliderButton.x = sliderButtonMinPos; + else if (sliderButton.x >= sliderButtonMaxPos) sliderButton.x = sliderButtonMaxPos; + + sliderPos = (sliderButton.x - sliderButtonMinPos) / buttonTravelDistance; + } + } + else sliderState = SLIDER_DEFAULT; + + // Draw control + //-------------------------------------------------------------------- + DrawRectangleRec(bounds, GetColor(style[SLIDER_BORDER_COLOR])); + DrawRectangle((int)(bounds.x + style[SLIDER_BORDER_WIDTH]), (int)(bounds.y + style[SLIDER_BORDER_WIDTH]), (int)(bounds.width - (2*style[SLIDER_BORDER_WIDTH])), (int)(bounds.height - (2*style[SLIDER_BORDER_WIDTH])), GetColor(style[SLIDER_INSIDE_COLOR])); + + switch (sliderState) + { + case SLIDER_DEFAULT: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_DEFAULT_COLOR])); break; + case SLIDER_HOVER: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_HOVER_COLOR])); break; + case SLIDER_ACTIVE: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_ACTIVE_COLOR])); break; + default: break; + } + //-------------------------------------------------------------------- + + return minValue + (maxValue - minValue)*sliderPos; +} + +// Slider Bar element, returns selected value +float GuiSliderBar(Rectangle bounds, float value, float minValue, float maxValue) +{ + SliderState sliderState = SLIDER_DEFAULT; + Vector2 mousePoint = GetMousePosition(); + float fixedValue; + float fixedMinValue; + + fixedValue = value - minValue; + maxValue = maxValue - minValue; + fixedMinValue = 0; + + if (fixedValue <= fixedMinValue) fixedValue = fixedMinValue; + else if (fixedValue >= maxValue) fixedValue = maxValue; + + Rectangle sliderBar; + + sliderBar.x = bounds.x + style[SLIDER_BORDER_WIDTH]; + sliderBar.y = bounds.y + style[SLIDER_BORDER_WIDTH]; + sliderBar.width = ((fixedValue*((float)bounds.width - 2*style[SLIDER_BORDER_WIDTH]))/(maxValue - fixedMinValue)); + sliderBar.height = bounds.height - 2*style[SLIDER_BORDER_WIDTH]; + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + sliderState = SLIDER_HOVER; + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + sliderState = SLIDER_ACTIVE; + + sliderBar.width = (mousePoint.x - bounds.x - style[SLIDER_BORDER_WIDTH]); + + if (mousePoint.x <= (bounds.x + style[SLIDER_BORDER_WIDTH])) sliderBar.width = 0; + else if (mousePoint.x >= (bounds.x + bounds.width - style[SLIDER_BORDER_WIDTH])) sliderBar.width = bounds.width - 2*style[SLIDER_BORDER_WIDTH]; + } + } + else sliderState = SLIDER_DEFAULT; + + fixedValue = ((float)sliderBar.width*(maxValue - fixedMinValue))/((float)bounds.width - 2*style[SLIDER_BORDER_WIDTH]); + + // Draw control + //-------------------------------------------------------------------- + DrawRectangleRec(bounds, GetColor(style[SLIDERBAR_BORDER_COLOR])); + DrawRectangle((int)(bounds.x + style[SLIDER_BORDER_WIDTH]), (int)(bounds.y + style[SLIDER_BORDER_WIDTH]) , (int)(bounds.width - (2*style[SLIDER_BORDER_WIDTH])), (int)(bounds.height - (2*style[SLIDER_BORDER_WIDTH])), GetColor(style[SLIDERBAR_INSIDE_COLOR])); + + switch (sliderState) + { + case SLIDER_DEFAULT: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_DEFAULT_COLOR])); break; + case SLIDER_HOVER: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_HOVER_COLOR])); break; + case SLIDER_ACTIVE: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_ACTIVE_COLOR])); break; + default: break; + } + + if (minValue < 0 && maxValue > 0) DrawRectangle((bounds.x + style[SLIDER_BORDER_WIDTH]) - (minValue * ((bounds.width - (style[SLIDER_BORDER_WIDTH]*2))/maxValue)), sliderBar.y, 1, sliderBar.height, GetColor(style[SLIDERBAR_ZERO_LINE_COLOR])); + //-------------------------------------------------------------------- + + return fixedValue + minValue; +} + +// Progress Bar element, shows current progress value +void GuiProgressBar(Rectangle bounds, float value) +{ + if (value > 1.0f) value = 1.0f; + else if (value < 0.0f) value = 0.0f; + + Rectangle progressBar = { bounds.x + style[PROGRESSBAR_BORDER_WIDTH], bounds.y + style[PROGRESSBAR_BORDER_WIDTH], bounds.width - (style[PROGRESSBAR_BORDER_WIDTH] * 2), bounds.height - (style[PROGRESSBAR_BORDER_WIDTH] * 2)}; + Rectangle progressValue = { bounds.x + style[PROGRESSBAR_BORDER_WIDTH], bounds.y + style[PROGRESSBAR_BORDER_WIDTH], value * (bounds.width - (style[PROGRESSBAR_BORDER_WIDTH] * 2)), bounds.height - (style[PROGRESSBAR_BORDER_WIDTH] * 2)}; + + // Draw control + //-------------------------------------------------------------------- + DrawRectangleRec(bounds, GetColor(style[PROGRESSBAR_BORDER_COLOR])); + DrawRectangleRec(progressBar, GetColor(style[PROGRESSBAR_INSIDE_COLOR])); + DrawRectangleRec(progressValue, GetColor(style[PROGRESSBAR_PROGRESS_COLOR])); + //-------------------------------------------------------------------- +} + +// Spinner element, returns selected value +// NOTE: Requires static variables: framesCounter, valueSpeed - ERROR! +int GuiSpinner(Rectangle bounds, int value, int minValue, int maxValue) +{ + SpinnerState spinnerState = SPINNER_DEFAULT; + Rectangle labelBoxBound = { bounds.x + bounds.width/4 + 1, bounds.y, bounds.width/2, bounds.height }; + Rectangle leftButtonBound = { bounds.x, bounds.y, bounds.width/4, bounds.height }; + Rectangle rightButtonBound = { bounds.x + bounds.width - bounds.width/4 + 1, bounds.y, bounds.width/4, bounds.height }; + Vector2 mousePoint = GetMousePosition(); + + int textHeight = GetFontBaseSize(GetDefaultFont()); + + int textWidth = MeasureText(FormatText("%i", value), style[GLOBAL_TEXT_FONTSIZE]); + + int buttonSide = 0; + + static int framesCounter = 0; + static bool valueSpeed = false;; + + //if (comboBoxButton.width < textWidth) comboBoxButton.width = textWidth + style[TOGGLE_TEXT_PADDING]; + //if (comboBoxButton.height < textHeight) comboBoxButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2; + + if (CheckCollisionPointRec(mousePoint, leftButtonBound) || CheckCollisionPointRec(mousePoint, rightButtonBound) || CheckCollisionPointRec(mousePoint, labelBoxBound)) + { + if (IsKeyDown(KEY_LEFT)) + { + spinnerState = SPINNER_PRESSED; + buttonSide = 1; + + if (value > minValue) value -= 1; + } + else if (IsKeyDown(KEY_RIGHT)) + { + spinnerState = SPINNER_PRESSED; + buttonSide = 2; + + if (value < maxValue) value += 1; + } + } + + if (CheckCollisionPointRec(mousePoint, leftButtonBound)) + { + buttonSide = 1; + spinnerState = SPINNER_HOVER; + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (!valueSpeed) + { + if (value > minValue) value--; + valueSpeed = true; + } + else framesCounter++; + + spinnerState = SPINNER_PRESSED; + + if (value > minValue) + { + if (framesCounter >= 30) value -= 1; + } + } + } + else if (CheckCollisionPointRec(mousePoint, rightButtonBound)) + { + buttonSide = 2; + spinnerState = SPINNER_HOVER; + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (!valueSpeed) + { + if (value < maxValue) value++; + valueSpeed = true; + } + else framesCounter++; + + spinnerState = SPINNER_PRESSED; + + if (value < maxValue) + { + if (framesCounter >= 30) value += 1; + } + } + } + else if (!CheckCollisionPointRec(mousePoint, labelBoxBound)) buttonSide = 0; + + if(IsMouseButtonUp(MOUSE_LEFT_BUTTON)) + { + valueSpeed = false; + framesCounter = 0; + } + + // Draw control + //-------------------------------------------------------------------- + switch (spinnerState) + { + case SPINNER_DEFAULT: + { + DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + + DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR])); + DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR])); + + DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_TEXT_COLOR])); + } break; + case SPINNER_HOVER: + { + if (buttonSide == 1) + { + DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_HOVER_BUTTON_BORDER_COLOR])); + DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_HOVER_BUTTON_INSIDE_COLOR])); + + DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_SYMBOL_COLOR])); + DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + } + else if (buttonSide == 2) + { + DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_HOVER_BUTTON_BORDER_COLOR])); + DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_HOVER_BUTTON_INSIDE_COLOR])); + + DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_SYMBOL_COLOR])); + } + + DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR])); + DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR])); + + DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_TEXT_COLOR])); + } break; + case SPINNER_PRESSED: + { + if (buttonSide == 1) + { + DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_PRESSED_BUTTON_BORDER_COLOR])); + DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR])); + + DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_SYMBOL_COLOR])); + DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + } + else if (buttonSide == 2) + { + DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR])); + DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR])); + + DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_PRESSED_BUTTON_BORDER_COLOR])); + DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR])); + + DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR])); + DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_SYMBOL_COLOR])); + } + DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR])); + DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR])); + + DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - textHeight/2), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_TEXT_COLOR])); + } break; + default: break; + } + return value; +} + +// Text Box element, returns input text +// NOTE: Requires static variables: framesCounter, maxChars - ERROR! +char *GuiTextBox(Rectangle bounds, char *text) +{ + static int maxChars = 20; + int initPos = bounds.x + 4; + char letter = -1; + static int framesCounter = 0; + + framesCounter++; + + letter = GetKeyPressed(); + + if (letter != -1) + { + if (letter == 3) + { + for (int i = 0; i < maxChars; i++) + { + if ((text[i] == '\0') && (i > 0)) + { + text[i - 1] = '\0'; + break; + } + } + + text[19] = '\0'; + } + else + { + for (int i = 0; i < maxChars; i++) + { + if (text[i] == '\0') + { + text[i] = letter; + break; + } + } + } + } + + // Draw control + //-------------------------------------------------------------------- + DrawRectangleRec(bounds, GetColor(style[TEXTBOX_BORDER_COLOR])); + DrawRectangle(bounds.x + style[TEXTBOX_BORDER_WIDTH], bounds.y + style[TEXTBOX_BORDER_WIDTH], bounds.width - (style[TEXTBOX_BORDER_WIDTH] * 2), bounds.height - (style[TEXTBOX_BORDER_WIDTH] * 2), GetColor(style[TEXTBOX_INSIDE_COLOR])); + + for (int i = 0; i < maxChars; i++) + { + if (text[i] == '\0') break; + + DrawText(FormatText("%c", text[i]), initPos, bounds.y + 10, style[TEXTBOX_TEXT_FONTSIZE], GetColor(style[TEXTBOX_TEXT_COLOR])); + initPos += ((GetDefaultFont().charSet[(int)text[i] - 32].w + 2)); + } + + if ((framesCounter/20)%2) DrawLine(initPos + 2, bounds.y + 10, initPos + 2, bounds.y + 10 + 10, GetColor(style[TEXTBOX_LINE_COLOR])); + //-------------------------------------------------------------------- + + return text; +} + +// TODO: GuiBox? +// TODO: GuiWindow? +// TODO: GuiPanel? + +// Save current GUI style into a text file +void SaveGuiStyle(const char *fileName) +{ + FILE *styleFile = fopen(fileName, "wt"); + + for (int i = 0; i < NUM_PROPERTIES; i++) fprintf(styleFile, "%-40s0x%x\n", guiPropertyName[i], GetStyleProperty(i)); + + fclose(styleFile); +} + +// Load GUI style from a text file +void LoadGuiStyle(const char *fileName) +{ + typedef struct { + char id[64]; + int value; + } StyleProperty; + + StyleProperty *styleProp = (StyleProperty *)malloc(128*sizeof(StyleProperty));; + int counter = 0; + + FILE *styleFile = fopen(fileName, "rt"); + + while (!feof(styleFile)) + { + fscanf(styleFile, "%s %i\n", styleProp[counter].id, &styleProp[counter].value); + counter++; + } + + fclose(styleFile); + + for (int i = 0; i < counter; i++) + { + for (int j = 0; j < NUM_PROPERTIES; j++) + { + if (strcmp(styleProp[i].id, guiPropertyName[j]) == 0) + { + // Assign correct property to style + style[j] = styleProp[i].value; + } + } + } + + free(styleProp); +} + +// Set one style property value +void SetStyleProperty(int guiProperty, int value) +{ + #define NUM_COLOR_SAMPLES 10 + + if (guiProperty == GLOBAL_BASE_COLOR) + { + Color baseColor = GetColor(value); + Color fadeColor[NUM_COLOR_SAMPLES]; + + for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1)); + + style[GLOBAL_BASE_COLOR] = value; + style[BACKGROUND_COLOR] = GetHexValue(fadeColor[3]); + style[BUTTON_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[BUTTON_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[BUTTON_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[5]); + style[TOGGLE_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[TOGGLE_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[TOGGLE_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[5]); + style[TOGGLE_ACTIVE_INSIDE_COLOR] = GetHexValue(fadeColor[8]); + style[SLIDER_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[SLIDER_DEFAULT_COLOR] = GetHexValue(fadeColor[6]); + style[SLIDER_HOVER_COLOR] = GetHexValue(fadeColor[7]); + style[SLIDER_ACTIVE_COLOR] = GetHexValue(fadeColor[9]); + style[SLIDERBAR_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[SLIDERBAR_DEFAULT_COLOR] = GetHexValue(fadeColor[6]); + style[SLIDERBAR_HOVER_COLOR] = GetHexValue(fadeColor[7]); + style[SLIDERBAR_ACTIVE_COLOR] = GetHexValue(fadeColor[9]); + style[SLIDERBAR_ZERO_LINE_COLOR] = GetHexValue(fadeColor[8]); + style[PROGRESSBAR_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[PROGRESSBAR_PROGRESS_COLOR] = GetHexValue(fadeColor[6]); + style[SPINNER_LABEL_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[SPINNER_HOVER_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[5]); + style[COMBOBOX_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[COMBOBOX_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[COMBOBOX_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[8]); + style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR] = GetHexValue(fadeColor[8]); + style[CHECKBOX_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + style[CHECKBOX_CLICK_INSIDE_COLOR] = GetHexValue(fadeColor[6]); + style[CHECKBOX_STATUS_ACTIVE_COLOR] = GetHexValue(fadeColor[8]); + style[TEXTBOX_INSIDE_COLOR] = GetHexValue(fadeColor[4]); + } + else if (guiProperty == GLOBAL_BORDER_COLOR) + { + Color baseColor = GetColor(value); + Color fadeColor[NUM_COLOR_SAMPLES]; + + for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1)); + + style[GLOBAL_BORDER_COLOR] = value; + style[BUTTON_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[BUTTON_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]); + style[BUTTON_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[TOGGLE_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[TOGGLE_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]); + style[TOGGLE_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[TOGGLE_ACTIVE_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[SLIDER_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[SLIDERBAR_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[PROGRESSBAR_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[SPINNER_LABEL_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[SPINNER_HOVER_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[8]); + style[SPINNER_PRESSED_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[COMBOBOX_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[COMBOBOX_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]); + style[COMBOBOX_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[COMBOBOX_PRESSED_LIST_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[CHECKBOX_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]); + style[CHECKBOX_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]); + style[CHECKBOX_CLICK_BORDER_COLOR] = GetHexValue(fadeColor[9]); + style[TEXTBOX_BORDER_COLOR] = GetHexValue(fadeColor[7]); + } + else if (guiProperty == GLOBAL_TEXT_COLOR) + { + Color baseColor = GetColor(value); + Color fadeColor[NUM_COLOR_SAMPLES]; + + for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1)); + + style[GLOBAL_TEXT_COLOR] = value; + style[LABEL_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[BUTTON_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[BUTTON_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]); + style[BUTTON_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]); + style[TOGGLE_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[TOGGLE_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]); + style[TOGGLE_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]); + style[TOGGLE_ACTIVE_TEXT_COLOR] = GetHexValue(fadeColor[5]); + style[SPINNER_DEFAULT_SYMBOL_COLOR] = GetHexValue(fadeColor[9]); + style[SPINNER_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[SPINNER_HOVER_SYMBOL_COLOR] = GetHexValue(fadeColor[8]); + style[SPINNER_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]); + style[SPINNER_PRESSED_SYMBOL_COLOR] = GetHexValue(fadeColor[5]); + style[SPINNER_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]); + style[COMBOBOX_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[COMBOBOX_DEFAULT_LIST_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[COMBOBOX_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]); + style[COMBOBOX_HOVER_LIST_TEXT_COLOR] = GetHexValue(fadeColor[8]); + style[COMBOBOX_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[4]); + style[COMBOBOX_PRESSED_LIST_TEXT_COLOR] = GetHexValue(fadeColor[4]); + style[TEXTBOX_TEXT_COLOR] = GetHexValue(fadeColor[9]); + style[TEXTBOX_LINE_COLOR] = GetHexValue(fadeColor[6]); + } + else style[guiProperty] = value; + +} + +// Get one style property value +int GetStyleProperty(int guiProperty) { return style[guiProperty]; } + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +static Color ColorMultiply(Color baseColor, float value) +{ + Color multColor = baseColor; + + if (value > 1.0f) value = 1.0f; + else if (value < 0.0f) value = 0.0f; + + multColor.r += (255 - multColor.r)*value; + multColor.g += (255 - multColor.g)*value; + multColor.b += (255 - multColor.b)*value; + + return multColor; +} \ No newline at end of file diff --git a/src/raygui.h b/src/raygui.h new file mode 100644 index 000000000..6906eca71 --- /dev/null +++ b/src/raygui.h @@ -0,0 +1,271 @@ +/******************************************************************************************* +* +* raygui - raylib IMGUI system (Immedite Mode GUI) +* +* Copyright (c) 2015 Kevin Gato, Daniel Nicolás, Sergio Martinez and Ramon Santamaria +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ +#ifndef RAYGUI_H +#define RAYGUI_H + +#include "raylib.h" + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define NUM_PROPERTIES 98 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GuiProperty { + GLOBAL_BASE_COLOR = 0, + GLOBAL_BORDER_COLOR, + GLOBAL_TEXT_COLOR, + GLOBAL_TEXT_FONTSIZE, + GLOBAL_BORDER_WIDTH, + BACKGROUND_COLOR, + LABEL_BORDER_WIDTH, + LABEL_TEXT_COLOR, + LABEL_TEXT_PADDING, + BUTTON_BORDER_WIDTH, + BUTTON_TEXT_PADDING, + BUTTON_DEFAULT_BORDER_COLOR, + BUTTON_DEFAULT_INSIDE_COLOR, + BUTTON_DEFAULT_TEXT_COLOR, + BUTTON_HOVER_BORDER_COLOR, + BUTTON_HOVER_INSIDE_COLOR, + BUTTON_HOVER_TEXT_COLOR, + BUTTON_PRESSED_BORDER_COLOR, + BUTTON_PRESSED_INSIDE_COLOR, + BUTTON_PRESSED_TEXT_COLOR, + TOGGLE_TEXT_PADDING, + TOGGLE_BORDER_WIDTH, + TOGGLE_DEFAULT_BORDER_COLOR, + TOGGLE_DEFAULT_INSIDE_COLOR, + TOGGLE_DEFAULT_TEXT_COLOR, + TOGGLE_HOVER_BORDER_COLOR, + TOGGLE_HOVER_INSIDE_COLOR, + TOGGLE_HOVER_TEXT_COLOR, + TOGGLE_PRESSED_BORDER_COLOR, + TOGGLE_PRESSED_INSIDE_COLOR, + TOGGLE_PRESSED_TEXT_COLOR, + TOGGLE_ACTIVE_BORDER_COLOR, + TOGGLE_ACTIVE_INSIDE_COLOR, + TOGGLE_ACTIVE_TEXT_COLOR, + TOGGLEGROUP_PADDING, + SLIDER_BORDER_WIDTH, + SLIDER_BUTTON_BORDER_WIDTH, + SLIDER_BORDER_COLOR, + SLIDER_INSIDE_COLOR, + SLIDER_DEFAULT_COLOR, + SLIDER_HOVER_COLOR, + SLIDER_ACTIVE_COLOR, + SLIDERBAR_BORDER_COLOR, + SLIDERBAR_INSIDE_COLOR, + SLIDERBAR_DEFAULT_COLOR, + SLIDERBAR_HOVER_COLOR, + SLIDERBAR_ACTIVE_COLOR, + SLIDERBAR_ZERO_LINE_COLOR, + PROGRESSBAR_BORDER_COLOR, + PROGRESSBAR_INSIDE_COLOR, + PROGRESSBAR_PROGRESS_COLOR, + PROGRESSBAR_BORDER_WIDTH, + SPINNER_LABEL_BORDER_COLOR, + SPINNER_LABEL_INSIDE_COLOR, + SPINNER_DEFAULT_BUTTON_BORDER_COLOR, + SPINNER_DEFAULT_BUTTON_INSIDE_COLOR, + SPINNER_DEFAULT_SYMBOL_COLOR, + SPINNER_DEFAULT_TEXT_COLOR, + SPINNER_HOVER_BUTTON_BORDER_COLOR, + SPINNER_HOVER_BUTTON_INSIDE_COLOR, + SPINNER_HOVER_SYMBOL_COLOR, + SPINNER_HOVER_TEXT_COLOR, + SPINNER_PRESSED_BUTTON_BORDER_COLOR, + SPINNER_PRESSED_BUTTON_INSIDE_COLOR, + SPINNER_PRESSED_SYMBOL_COLOR, + SPINNER_PRESSED_TEXT_COLOR, + COMBOBOX_PADDING, + COMBOBOX_BUTTON_WIDTH, + COMBOBOX_BUTTON_HEIGHT, + COMBOBOX_BORDER_WIDTH, + COMBOBOX_DEFAULT_BORDER_COLOR, + COMBOBOX_DEFAULT_INSIDE_COLOR, + COMBOBOX_DEFAULT_TEXT_COLOR, + COMBOBOX_DEFAULT_LIST_TEXT_COLOR, + COMBOBOX_HOVER_BORDER_COLOR, + COMBOBOX_HOVER_INSIDE_COLOR, + COMBOBOX_HOVER_TEXT_COLOR, + COMBOBOX_HOVER_LIST_TEXT_COLOR, + COMBOBOX_PRESSED_BORDER_COLOR, + COMBOBOX_PRESSED_INSIDE_COLOR, + COMBOBOX_PRESSED_TEXT_COLOR, + COMBOBOX_PRESSED_LIST_BORDER_COLOR, + COMBOBOX_PRESSED_LIST_INSIDE_COLOR, + COMBOBOX_PRESSED_LIST_TEXT_COLOR, + CHECKBOX_DEFAULT_BORDER_COLOR, + CHECKBOX_DEFAULT_INSIDE_COLOR, + CHECKBOX_HOVER_BORDER_COLOR, + CHECKBOX_HOVER_INSIDE_COLOR, + CHECKBOX_CLICK_BORDER_COLOR, + CHECKBOX_CLICK_INSIDE_COLOR, + CHECKBOX_STATUS_ACTIVE_COLOR, + CHECKBOX_INSIDE_WIDTH, + TEXTBOX_BORDER_WIDTH, + TEXTBOX_BORDER_COLOR, + TEXTBOX_INSIDE_COLOR, + TEXTBOX_TEXT_COLOR, + TEXTBOX_LINE_COLOR, + TEXTBOX_TEXT_FONTSIZE +} GuiProperty; + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static const char *guiPropertyName[] = { + "GLOBAL_BASE_COLOR", + "GLOBAL_BORDER_COLOR", + "GLOBAL_TEXT_COLOR", + "GLOBAL_TEXT_FONTSIZE", + "GLOBAL_BORDER_WIDTH", + "BACKGROUND_COLOR", + "LABEL_BORDER_WIDTH", + "LABEL_TEXT_COLOR", + "LABEL_TEXT_PADDING", + "BUTTON_BORDER_WIDTH", + "BUTTON_TEXT_PADDING", + "BUTTON_DEFAULT_BORDER_COLOR", + "BUTTON_DEFAULT_INSIDE_COLOR", + "BUTTON_DEFAULT_TEXT_COLOR", + "BUTTON_HOVER_BORDER_COLOR", + "BUTTON_HOVER_INSIDE_COLOR", + "BUTTON_HOVER_TEXT_COLOR", + "BUTTON_PRESSED_BORDER_COLOR", + "BUTTON_PRESSED_INSIDE_COLOR", + "BUTTON_PRESSED_TEXT_COLOR", + "TOGGLE_TEXT_PADDING", + "TOGGLE_BORDER_WIDTH", + "TOGGLE_DEFAULT_BORDER_COLOR", + "TOGGLE_DEFAULT_INSIDE_COLOR", + "TOGGLE_DEFAULT_TEXT_COLOR", + "TOGGLE_HOVER_BORDER_COLOR", + "TOGGLE_HOVER_INSIDE_COLOR", + "TOGGLE_HOVER_TEXT_COLOR", + "TOGGLE_PRESSED_BORDER_COLOR", + "TOGGLE_PRESSED_INSIDE_COLOR", + "TOGGLE_PRESSED_TEXT_COLOR", + "TOGGLE_ACTIVE_BORDER_COLOR", + "TOGGLE_ACTIVE_INSIDE_COLOR", + "TOGGLE_ACTIVE_TEXT_COLOR", + "TOGGLEGROUP_PADDING", + "SLIDER_BORDER_WIDTH", + "SLIDER_BUTTON_BORDER_WIDTH", + "SLIDER_BORDER_COLOR", + "SLIDER_INSIDE_COLOR", + "SLIDER_DEFAULT_COLOR", + "SLIDER_HOVER_COLOR", + "SLIDER_ACTIVE_COLOR", + "SLIDERBAR_BORDER_COLOR", + "SLIDERBAR_INSIDE_COLOR", + "SLIDERBAR_DEFAULT_COLOR", + "SLIDERBAR_HOVER_COLOR", + "SLIDERBAR_ACTIVE_COLOR", + "SLIDERBAR_ZERO_LINE_COLOR", + "PROGRESSBAR_BORDER_COLOR", + "PROGRESSBAR_INSIDE_COLOR", + "PROGRESSBAR_PROGRESS_COLOR", + "PROGRESSBAR_BORDER_WIDTH", + "SPINNER_LABEL_BORDER_COLOR", + "SPINNER_LABEL_INSIDE_COLOR", + "SPINNER_DEFAULT_BUTTON_BORDER_COLOR", + "SPINNER_DEFAULT_BUTTON_INSIDE_COLOR", + "SPINNER_DEFAULT_SYMBOL_COLOR", + "SPINNER_DEFAULT_TEXT_COLOR", + "SPINNER_HOVER_BUTTON_BORDER_COLOR", + "SPINNER_HOVER_BUTTON_INSIDE_COLOR", + "SPINNER_HOVER_SYMBOL_COLOR", + "SPINNER_HOVER_TEXT_COLOR", + "SPINNER_PRESSED_BUTTON_BORDER_COLOR", + "SPINNER_PRESSED_BUTTON_INSIDE_COLOR", + "SPINNER_PRESSED_SYMBOL_COLOR", + "SPINNER_PRESSED_TEXT_COLOR", + "COMBOBOX_PADDING", + "COMBOBOX_BUTTON_WIDTH", + "COMBOBOX_BUTTON_HEIGHT", + "COMBOBOX_BORDER_WIDTH", + "COMBOBOX_DEFAULT_BORDER_COLOR", + "COMBOBOX_DEFAULT_INSIDE_COLOR", + "COMBOBOX_DEFAULT_TEXT_COLOR", + "COMBOBOX_DEFAULT_LIST_TEXT_COLOR", + "COMBOBOX_HOVER_BORDER_COLOR", + "COMBOBOX_HOVER_INSIDE_COLOR", + "COMBOBOX_HOVER_TEXT_COLOR", + "COMBOBOX_HOVER_LIST_TEXT_COLOR", + "COMBOBOX_PRESSED_BORDER_COLOR", + "COMBOBOX_PRESSED_INSIDE_COLOR", + "COMBOBOX_PRESSED_TEXT_COLOR", + "COMBOBOX_PRESSED_LIST_BORDER_COLOR", + "COMBOBOX_PRESSED_LIST_INSIDE_COLOR", + "COMBOBOX_PRESSED_LIST_TEXT_COLOR", + "CHECKBOX_DEFAULT_BORDER_COLOR", + "CHECKBOX_DEFAULT_INSIDE_COLOR", + "CHECKBOX_HOVER_BORDER_COLOR", + "CHECKBOX_HOVER_INSIDE_COLOR", + "CHECKBOX_CLICK_BORDER_COLOR", + "CHECKBOX_CLICK_INSIDE_COLOR", + "CHECKBOX_STATUS_ACTIVE_COLOR", + "CHECKBOX_INSIDE_WIDTH", + "TEXTBOX_BORDER_WIDTH", + "TEXTBOX_BORDER_COLOR", + "TEXTBOX_INSIDE_COLOR", + "TEXTBOX_TEXT_COLOR", + "TEXTBOX_LINE_COLOR", + "TEXTBOX_TEXT_FONTSIZE" +}; + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +void GuiLabel(Rectangle bounds, const char *text); // Label element, show text +void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color border, Color inner); // Label element extended, configurable colors +bool GuiButton(Rectangle bounds, const char *text); // Button element, returns true when clicked +bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle); // Toggle Button element, returns true when active +int GuiToggleGroup(Rectangle bounds, int toggleNum, char **toggleText, int toggleActive); // Toggle Group element, returns toggled button index +int GuiComboBox(Rectangle bounds, int comboNum, char **comboText, int comboActive); // Combo Box element, returns selected item index +bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box element, returns true when active +float GuiSlider(Rectangle bounds, float value, float minValue, float maxValue); // Slider element, returns selected value +float GuiSliderBar(Rectangle bounds, float value, float minValue, float maxValue); // Slider Bar element, returns selected value +void GuiProgressBar(Rectangle bounds, float value); // Progress Bar element, shows current progress value +int GuiSpinner(Rectangle bounds, int value, int minValue, int maxValue); // Spinner element, returns selected value +char *GuiTextBox(Rectangle bounds, char *text); // Text Box element, returns input text + +void SaveGuiStyle(const char *fileName); // Save GUI style file +void LoadGuiStyle(const char *fileName); // Load GUI style file + +void SetStyleProperty(int guiProperty, int value); // Set one style property +int GetStyleProperty(int guiProperty); // Get one style property + +#ifdef __cplusplus +} +#endif + +#endif // RAYGUI_H diff --git a/src/raylib.h b/src/raylib.h index f5220e2e1..bf5fe99f9 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -241,20 +241,13 @@ typedef struct Texture2D { int format; // Data format (TextureFormat) } Texture2D; -// Character type (one font glyph) -typedef struct Character { - int value; //char value = ' '; (int)value = 32; - int x; - int y; - int w; - int h; -} Character; - // SpriteFont type, includes texture and charSet array data typedef struct SpriteFont { - Texture2D texture; - int numChars; - Character *charSet; + Texture2D texture; // Font texture + int size; // Base size (default chars height) + int numChars; // Number of characters + int *charValues; // Characters values array + Rectangle *charRecs; // Characters rectangles within the texture } SpriteFont; // Camera type, defines a camera position/orientation in 3d space @@ -276,7 +269,7 @@ typedef struct VertexData { unsigned int vboId[4]; } VertexData; -// Shader type +// Shader type (generic shader) typedef struct Shader { unsigned int id; // Shader program id @@ -411,6 +404,8 @@ void EndDrawing(void); // End canvas drawin void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup) void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode +Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Returns a ray trace from mouse position + void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS float GetFrameTime(void); // Returns time in seconds for one frame @@ -421,38 +416,13 @@ int GetHexValue(Color color); // Returns hexadecim int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f -void SetConfigFlags(char flags); // Enable some window configurations +void SetConfigFlags(char flags); // Setup some window configuration flags void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) bool IsFileDropped(void); // Check if a file have been dropped into window char **GetDroppedFiles(int *count); // Retrieve dropped files into window void ClearDroppedFiles(void); // Clear dropped files paths buffer -Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Gives the ray trace from mouse position - -//------------------------------------------------------------------------------------ -// Shaders System Functions (Module: rlgl) -// NOTE: This functions are useless when using OpenGL 1.1 -//------------------------------------------------------------------------------------ -Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id -void UnloadShader(Shader shader); // Unload a custom shader from memory -void SetPostproShader(Shader shader); // Set fullscreen postproduction shader -void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw -void SetDefaultShader(void); // Set default shader to be used in batch draw -void SetModelShader(Model *model, Shader shader); // Link a shader to a model -bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled - -int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location -void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) -void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) -void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment -void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment -void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment -void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment - -void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) - //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ @@ -517,18 +487,20 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang // Camera System Functions (Module: camera) //------------------------------------------------------------------------------------ void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) -Camera UpdateCamera(Vector3 *playerPosition); // Update camera and player position (1st person and 3rd person cameras) +void UpdateCamera(Camera *camera); // Update camera (player position is ignored) +void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) -void SetCameraMoveControls(int frontKey, int backKey, - int leftKey, int rightKey, - int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) +void SetCameraPosition(Vector3 position); // Set internal camera position +void SetCameraTarget(Vector3 target); // Set internal camera target void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraMoveControls(int frontKey, int backKey, + int leftKey, int rightKey, + int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameraTarget(Vector3 target); // Set internal camera target //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) @@ -570,7 +542,7 @@ Image LoadImageFromRES(const char *rresName, int resId); Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // Load a texture from raw data into GPU memory Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -Texture2D LoadTextureFromImage(Image image); // Load a texture from image data (and generate mipmaps) +Texture2D LoadTextureFromImage(Image image); // Load a texture from image data void UnloadImage(Image image); // Unload image from CPU memory (RAM) void UnloadTexture(Texture2D texture); // Unload texture from GPU memory Color *GetImageData(Image image); // Get pixel data from image as a Color struct array @@ -598,7 +570,7 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); int MeasureText(const char *text, int fontSize); // Measure string width for default font Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont -int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height) + void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' @@ -644,6 +616,29 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface +//------------------------------------------------------------------------------------ +// Shaders System Functions (Module: rlgl) +// NOTE: This functions are useless when using OpenGL 1.1 +//------------------------------------------------------------------------------------ +Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations +unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shaders strings and return program id +void UnloadShader(Shader shader); // Unload a custom shader from memory +void SetPostproShader(Shader shader); // Set fullscreen postproduction shader +void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw +void SetDefaultShader(void); // Set default shader to be used in batch draw +void SetModelShader(Model *model, Shader shader); // Link a shader to a model +bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled + +int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location +void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) +void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) +void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment +void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment +void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment +void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment + +void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) + //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) //------------------------------------------------------------------------------------ diff --git a/src/rlgl.c b/src/rlgl.c index 163fa35a0..8806b4296 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -4,8 +4,8 @@ * * raylib now uses OpenGL 1.1 style functions (rlVertex) that are mapped to selected OpenGL version: * OpenGL 1.1 - Direct map rl* -> gl* -* OpenGL 3.3+ - Vertex data is stored in VAOs, call rlglDraw() to render -* OpenGL ES 2 - Same behaviour as OpenGL 3.3+ +* OpenGL 3.3 - Vertex data is stored in VAOs, call rlglDraw() to render +* OpenGL ES 2 - Vertex data is stored in VBOs or VAOs (when available), call rlglDraw() to render * * Copyright (c) 2014 Ramon Santamaria (@raysan5) * @@ -858,7 +858,7 @@ void rlglInit(void) // NOTE: We don't need that much data on screen... right now... #if defined(GRAPHICS_API_OPENGL_11) - TraceLog(INFO, "OpenGL 1.1 profile initialized"); + //TraceLog(INFO, "OpenGL 1.1 (or driver default) profile initialized"); #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -1938,15 +1938,17 @@ Model rlglLoadModel(VertexData mesh) } // Read screen pixel data (color buffer) +// ISSUE: Non pre-multiplied alpha when reading from backbuffer! +// TODO: Multiply alpha unsigned char *rlglReadScreenPixels(int width, int height) { - unsigned char *screenData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); + unsigned char *screenData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); // Flip image vertically! - unsigned char *imgData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); + unsigned char *imgData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); for (int y = height-1; y >= 0; y--) { @@ -2075,7 +2077,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName) return shader; } -// Load a custom shader and return program id +// Load custom shader strings and return program id unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr) { unsigned int program = 0; @@ -3059,8 +3061,6 @@ static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight) #if defined(RLGL_STANDALONE) -typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; - // Output a trace log message // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning static void TraceLog(int msgType, const char *text, ...) diff --git a/src/rlgl.h b/src/rlgl.h index af3125969..172b48683 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -4,7 +4,7 @@ * * raylib now uses OpenGL 1.1 style functions (rlVertex) that are mapped to selected OpenGL version: * OpenGL 1.1 - Direct map rl* -> gl* -* OpenGL 3.3+ - Vertex data is stored in VAOs, call rlglDraw() to render +* OpenGL 3.3 - Vertex data is stored in VAOs, call rlglDraw() to render * OpenGL ES 2 - Vertex data is stored in VBOs or VAOs (when available), call rlglDraw() to render * * Copyright (c) 2014 Ramon Santamaria (@raysan5) @@ -270,7 +270,7 @@ void PrintModelviewMatrix(void); // DEBUG: Print modelview matrix // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id +unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id void UnloadShader(Shader shader); // Unload a custom shader from memory void SetPostproShader(Shader shader); // Set fullscreen postproduction shader void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw diff --git a/src/text.c b/src/text.c index 65d52f261..3364a9bf0 100644 --- a/src/text.c +++ b/src/text.c @@ -67,7 +67,7 @@ static SpriteFont defaultFont; // Default font provided by raylib // Module specific Functions Declaration //---------------------------------------------------------------------------------- static bool PixelIsMagenta(Color p); // Check if a pixel is magenta -static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures +static int ParseImageData(Image image, int **charValues, Rectangle **charSet); // Parse image pixel data to obtain characters data static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font) static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required) @@ -181,21 +181,23 @@ extern void LoadDefaultFont(void) // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars //------------------------------------------------------------------------------ - defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data - // This memory should be freed at end! --> Done on CloseWindow() + defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int)); + defaultFont.charRecs = (Rectangle *)malloc(defaultFont.numChars*sizeof(Rectangle)); // Allocate space for our character rectangle data + // This memory should be freed at end! --> Done on CloseWindow() int currentLine = 0; int currentPosX = charsDivisor; int testPosX = charsDivisor; for (int i = 0; i < defaultFont.numChars; i++) { - defaultFont.charSet[i].value = FONT_FIRST_CHAR + i; // First char is 32 - defaultFont.charSet[i].x = currentPosX; - defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor); - defaultFont.charSet[i].w = charsWidth[i]; - defaultFont.charSet[i].h = charsHeight; + defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32 + + defaultFont.charRecs[i].x = currentPosX; + defaultFont.charRecs[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor); + defaultFont.charRecs[i].width = charsWidth[i]; + defaultFont.charRecs[i].height = charsHeight; - testPosX += (defaultFont.charSet[i].w + charsDivisor); + testPosX += (defaultFont.charRecs[i].width + charsDivisor); if (testPosX >= defaultFont.texture.width) { @@ -203,11 +205,13 @@ extern void LoadDefaultFont(void) currentPosX = 2 * charsDivisor + charsWidth[i]; testPosX = currentPosX; - defaultFont.charSet[i].x = charsDivisor; - defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor); + defaultFont.charRecs[i].x = charsDivisor; + defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor); } else currentPosX = testPosX; } + + defaultFont.size = defaultFont.charRecs[0].y; TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id); } @@ -215,7 +219,8 @@ extern void LoadDefaultFont(void) extern void UnloadDefaultFont(void) { UnloadTexture(defaultFont.texture); - free(defaultFont.charSet); + free(defaultFont.charValues); + free(defaultFont.charRecs); TraceLog(INFO, "Unloaded default font data"); } @@ -238,25 +243,20 @@ SpriteFont LoadSpriteFont(const char *fileName) { Image image = LoadImage(fileName); - // At this point we have a data array... - - Color *imagePixels = GetImageData(image); - #if defined(PLATFORM_RPI) || defined(PLATFORM_WEB) ImageConvertToPOT(&image, MAGENTA); #endif - // Process bitmap Font pixel data to get measures (Character array) + // Process bitmap font pixel data to get characters measures // spriteFont.charSet data is filled inside the function and memory is allocated! - int numChars = ParseImageData(imagePixels, image.width, image.height, &spriteFont.charSet); + int numChars = ParseImageData(image, &spriteFont.charValues, &spriteFont.charRecs); - TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName); - TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", fileName, numChars); + TraceLog(DEBUG, "[%s] SpriteFont data parsed correctly", fileName); + TraceLog(DEBUG, "[%s] SpriteFont num chars detected: %i", fileName, numChars); spriteFont.numChars = numChars; - spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture + spriteFont.size = spriteFont.charRecs[0].height; - free(imagePixels); UnloadImage(image); } @@ -267,7 +267,8 @@ SpriteFont LoadSpriteFont(const char *fileName) void UnloadSpriteFont(SpriteFont spriteFont) { UnloadTexture(spriteFont.texture); - free(spriteFont.charSet); + free(spriteFont.charValues); + free(spriteFont.charRecs); TraceLog(INFO, "Unloaded sprite font data"); } @@ -298,32 +299,32 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int f float scaleFactor; unsigned char letter; - Character c; + Rectangle rec; - //if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f; - //else scaleFactor = (float)fontSize / spriteFont.charSet[0].h; + //if (fontSize <= spriteFont.charRecs[0].height) scaleFactor = 1.0f; + //else scaleFactor = (float)fontSize / spriteFont.charRecs[0].height; - scaleFactor = (float)fontSize/spriteFont.charSet[0].h; + scaleFactor = (float)fontSize/spriteFont.charRecs[0].height; for(int i = 0; i < length; i++) { if ((unsigned char)text[i] == 0xc2) { letter = (unsigned char)text[i + 1]; - c = spriteFont.charSet[letter - FONT_FIRST_CHAR]; + rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR]; i++; } else if ((unsigned char)text[i] == 0xc3) { letter = (unsigned char)text[i + 1]; - c = spriteFont.charSet[letter - FONT_FIRST_CHAR + 64]; + rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR + 64]; i++; } - else c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR]; + else rec = spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR]; - DrawTexturePro(spriteFont.texture, (Rectangle){ c.x, c.y, c.w, c.h }, (Rectangle){ position.x + offsetX, position.y, c.w*scaleFactor, c.h*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint); + DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + offsetX, position.y, rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint); - offsetX += (c.w*scaleFactor + spacing); + offsetX += (rec.width*scaleFactor + spacing); } } @@ -363,25 +364,19 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int for (int i = 0; i < len; i++) { - textWidth += spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w; + textWidth += spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR].width; } - if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f; - else scaleFactor = (float)fontSize / spriteFont.charSet[0].h; + if (fontSize <= spriteFont.charRecs[0].height) scaleFactor = 1.0f; + else scaleFactor = (float)fontSize / spriteFont.charRecs[0].height; Vector2 vec; vec.x = (float)textWidth * scaleFactor + (len - 1) * spacing; // Adds chars spacing to measure - vec.y = (float)spriteFont.charSet[0].h * scaleFactor; + vec.y = (float)spriteFont.charRecs[0].height * scaleFactor; return vec; } -// Returns the base size for a SpriteFont (chars height) -int GetFontBaseSize(SpriteFont spriteFont) -{ - return spriteFont.charSet[0].h; -} - // Shows current FPS on top-left corner // NOTE: Uses default font void DrawFPS(int posX, int posY) @@ -420,8 +415,8 @@ static bool PixelIsMagenta(Color p) return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255)); } -// Parse image pixel data to obtain character set measures -static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet) +// Parse image pixel data to obtain characters data (measures) +static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) { int charSpacing = 0; int lineSpacing = 0; @@ -429,15 +424,20 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char int x = 0; int y = 0; - Character tempCharSet[MAX_FONTCHARS]; // We allocate a temporal array for charData, once we get the actual charNumber we copy data to a sized array. + // We allocate a temporal arrays for chars data measures, + // once we get the actual number of chars, we copy data to a sized arrays + int tempCharValues[MAX_FONTCHARS]; + Rectangle tempCharRecs[MAX_FONTCHARS]; + + Color *pixels = GetImageData(image); - for(y = 0; y < imgHeight; y++) + for(y = 0; y < image.height; y++) { - for(x = 0; x < imgWidth; x++) + for(x = 0; x < image.width; x++) { - if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break; + if (!PixelIsMagenta(pixels[y*image.width + x])) break; } - if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break; + if (!PixelIsMagenta(pixels[y*image.width + x])) break; } charSpacing = x; @@ -446,7 +446,7 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char int charHeight = 0; int j = 0; - while(!PixelIsMagenta(imgDataPixel[(lineSpacing + j)*imgWidth + charSpacing])) j++; + while(!PixelIsMagenta(pixels[(lineSpacing + j)*image.width + charSpacing])) j++; charHeight = j; @@ -455,21 +455,22 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char int lineToRead = 0; int xPosToRead = charSpacing; - while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < imgHeight) + while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height) { - while((xPosToRead < imgWidth) && - !PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead]))) + while((xPosToRead < image.width) && + !PixelIsMagenta((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]))) { - tempCharSet[index].value = FONT_FIRST_CHAR + index; - tempCharSet[index].x = xPosToRead; - tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing); - tempCharSet[index].h = charHeight; + tempCharValues[index] = FONT_FIRST_CHAR + index; + + tempCharRecs[index].x = xPosToRead; + tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing); + tempCharRecs[index].height = charHeight; int charWidth = 0; - while(!PixelIsMagenta(imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead + charWidth])) charWidth++; + while(!PixelIsMagenta(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth])) charWidth++; - tempCharSet[index].w = charWidth; + tempCharRecs[index].width = charWidth; index++; @@ -479,12 +480,20 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char lineToRead++; xPosToRead = charSpacing; } + + free(pixels); - // We got tempCharSet populated with char data and the number of chars (index) - // Now we move temp data to real charSet (passed as parameter to the function) - (*charSet) = (Character *)malloc(index * sizeof(Character)); // BE CAREFUL! This memory should be freed! + // We got tempCharValues and tempCharsRecs populated with chars data + // Now we move temp data to sized charValues and charRecs arrays (passed as parameter to the function) + // NOTE: This memory should be freed! + (*charRecs) = (Rectangle *)malloc(index*sizeof(Rectangle)); + (*charValues) = (int *)malloc(index*sizeof(int)); - for (int i = 0; i < index; i++) (*charSet)[i] = tempCharSet[i]; + for (int i = 0; i < index; i++) + { + (*charValues)[i] = tempCharValues[i]; + (*charRecs)[i] = tempCharRecs[i]; + } return index; } @@ -528,7 +537,7 @@ static SpriteFont LoadRBMF(const char *fileName) { fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile); - TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight); + TraceLog(DEBUG, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight); spriteFont.numChars = (int)rbmfHeader.numChars; @@ -566,15 +575,16 @@ static SpriteFont LoadRBMF(const char *fileName) free(imagePixels); - TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName); + TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName); spriteFont.texture = LoadTextureFromImage(image); UnloadImage(image); // Unload image data - //TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName); + //TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName); - // Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars - spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data + // Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars + spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); + spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle)); int currentLine = 0; int currentPosX = charsDivisor; @@ -582,13 +592,14 @@ static SpriteFont LoadRBMF(const char *fileName) for (int i = 0; i < spriteFont.numChars; i++) { - spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i; - spriteFont.charSet[i].x = currentPosX; - spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor); - spriteFont.charSet[i].w = (int)rbmfCharWidthData[i]; - spriteFont.charSet[i].h = (int)rbmfHeader.charHeight; + spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i; + + spriteFont.charRecs[i].x = currentPosX; + spriteFont.charRecs[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor); + spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i]; + spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight; - testPosX += (spriteFont.charSet[i].w + charsDivisor); + testPosX += (spriteFont.charRecs[i].width + charsDivisor); if (testPosX > spriteFont.texture.width) { @@ -596,11 +607,13 @@ static SpriteFont LoadRBMF(const char *fileName) currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i]; testPosX = currentPosX; - spriteFont.charSet[i].x = charsDivisor; - spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor); + spriteFont.charRecs[i].x = charsDivisor; + spriteFont.charRecs[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor); } else currentPosX = testPosX; } + + spriteFont.size = spriteFont.charRecs[0].height; TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName); } @@ -614,8 +627,14 @@ static SpriteFont LoadRBMF(const char *fileName) } // Generate a sprite font from TTF data (font size required) +// NOTE: This function is a mess, it should be completely redone! static SpriteFont LoadTTF(const char *fileName, int fontSize) { + // Steps: + + // 1) Generate sprite sheet image with characters from TTF + // 2) Load image as SpriteFont + SpriteFont font; Image image; @@ -631,7 +650,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize) unsigned char *tempBitmap = (unsigned char *)malloc(image.width*image.height*sizeof(unsigned char)); // One channel bitmap returned! - // REFERENCE + // Reference struct /* typedef struct { @@ -693,8 +712,10 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize) print(100,160, 0, "This is a test"); */ +/* font.numChars = 95; - font.charSet = (Character *)malloc(font.numChars*sizeof(Character)); + font.charValues (int *)malloc(font.numChars*sizeof(int)); + font.charRecs = (Character *)malloc(font.numChars*sizeof(Character)); font.texture = LoadTextureFromImage(image); //stbtt_aligned_quad letter; @@ -702,16 +723,16 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize) for (int i = 0; i < font.numChars; i++) { - font.charSet[i].value = i + 32; + font.charValues[i] = i + 32; //stbtt_GetPackedQuad(chardata[0], 512, 512, i, &x, &y, &letter, 0); - font.charSet[i].x = chardata[i + 32].x0; - font.charSet[i].y = chardata[i + 32].y0; - font.charSet[i].w = chardata[i + 32].x1 - chardata[i + 32].x0; - font.charSet[i].h = chardata[i + 32].y1 - chardata[i + 32].y0; + font.charRecs[i].x = chardata[i + 32].x0; + font.charRecs[i].y = chardata[i + 32].y0; + font.charRecs[i].width = chardata[i + 32].x1 - chardata[i + 32].x0; + font.charRecs[i].height = chardata[i + 32].y1 - chardata[i + 32].y0; } - +*/ UnloadImage(image); return font; diff --git a/src/textures.c b/src/textures.c index 694567019..e2eb8b2f2 100644 --- a/src/textures.c +++ b/src/textures.c @@ -32,7 +32,10 @@ #include // Declares malloc() and free() for memory management #include // Required for strcmp(), strrchr(), strncmp() -#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 +#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 + // Required: rlglLoadTexture() rlDeleteTextures(), + // rlglGenerateMipmaps(), some funcs for DrawTexturePro() + #include "utils.h" // rRES data decompression utility function // NOTE: Includes Android fopen function map @@ -397,9 +400,12 @@ void UnloadImage(Image image) // Unload texture from GPU memory void UnloadTexture(Texture2D texture) { - rlDeleteTextures(texture.id); - - TraceLog(INFO, "[TEX ID %i] Unloaded texture data", texture.id); + if (texture.id != 0) + { + rlDeleteTextures(texture.id); + + TraceLog(INFO, "[TEX ID %i] Unloaded texture data", texture.id); + } } // Get pixel data from image in the form of Color struct array @@ -895,6 +901,7 @@ static Image LoadDDS(const char *fileName) TraceLog(DEBUG, "[%s] DDS file pixel format size: %i", fileName, header.ddspf.size); TraceLog(DEBUG, "[%s] DDS file pixel format flags: 0x%x", fileName, header.ddspf.flags); TraceLog(DEBUG, "[%s] DDS file format: 0x%x", fileName, header.ddspf.fourCC); + TraceLog(DEBUG, "[%s] DDS file bit count: 0x%x", fileName, header.ddspf.rgbBitCount); image.width = header.width; image.height = header.height; @@ -959,10 +966,22 @@ static Image LoadDDS(const char *fileName) { image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); fread(image.data, image.width*image.height*4, 1, ddsFile); + + unsigned char blue = 0; + // NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment) + // DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA + // So, we must realign B8G8R8A8 to R8G8B8A8 + for (int i = 0; i < image.width*image.height*4; i += 4) + { + blue = ((unsigned char *)image.data)[i]; + ((unsigned char *)image.data)[i] = ((unsigned char *)image.data)[i + 2]; + ((unsigned char *)image.data)[i + 2] = blue; + } + image.format = UNCOMPRESSED_R8G8B8A8; } - else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0)) + else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0)) // Compressed { int bufsize; @@ -1062,15 +1081,18 @@ static Image LoadPKM(const char *fileName) header.width = ((header.width & 0x00FF) << 8) | ((header.width & 0xFF00) >> 8); header.height = ((header.height & 0x00FF) << 8) | ((header.height & 0xFF00) >> 8); - TraceLog(INFO, "PKM (ETC) image width: %i", header.width); - TraceLog(INFO, "PKM (ETC) image height: %i", header.height); - TraceLog(INFO, "PKM (ETC) image format: %i", header.format); + TraceLog(DEBUG, "PKM (ETC) image width: %i", header.width); + TraceLog(DEBUG, "PKM (ETC) image height: %i", header.height); + TraceLog(DEBUG, "PKM (ETC) image format: %i", header.format); image.width = header.width; image.height = header.height; image.mipmaps = 1; - int size = image.width*image.height*4/8; // Total data size in bytes + int bpp = 4; + if (header.format == 3) bpp = 8; + + int size = image.width*image.height*bpp/8; // Total data size in bytes image.data = (unsigned char*)malloc(size * sizeof(unsigned char));