diff options
| author | Ray <[email protected]> | 2019-05-14 17:57:45 +0200 |
|---|---|---|
| committer | Ray <[email protected]> | 2019-05-14 17:57:45 +0200 |
| commit | 5a27bcaf7115e46a5123e9857007d940998f0650 (patch) | |
| tree | 7179c6a1b4d700c9685dd51cc76cb2b2c90b9609 /examples/src | |
| parent | 423fdd699225ee9686c44a606bf83272b4c77802 (diff) | |
| download | raylib.com-5a27bcaf7115e46a5123e9857007d940998f0650.tar.gz raylib.com-5a27bcaf7115e46a5123e9857007d940998f0650.zip | |
Review examples collection -WIP-
WARNING: Examples list has been reviewed but examples haven't been recompiled yet... that's not trivial...
Diffstat (limited to 'examples/src')
71 files changed, 4343 insertions, 487 deletions
diff --git a/examples/src/audio/audio_module_playing.c b/examples/src/audio/audio_module_playing.c index 671a119..54bfa3d 100644 --- a/examples/src/audio/audio_module_playing.c +++ b/examples/src/audio/audio_module_playing.c @@ -30,11 +30,11 @@ int main() int screenWidth = 800; int screenHeight = 450; - SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X + SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); - InitAudioDevice(); // Initialize audio device + InitAudioDevice(); // Initialize audio device Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE }; @@ -52,7 +52,7 @@ int main() circles[i].color = colors[GetRandomValue(0, 13)]; } - Music xm = LoadMusicStream("resources/mini1111.xm"); + Music xm = LoadMusicStream("resources/chiptun1.mod"); PlayMusicStream(xm); diff --git a/examples/src/audio/audio_music_stream.c b/examples/src/audio/audio_music_stream.c index f9fe23d..26450a8 100644 --- a/examples/src/audio/audio_music_stream.c +++ b/examples/src/audio/audio_music_stream.c @@ -59,6 +59,8 @@ int main() // Get timePlayed scaled to bar dimensions (400 pixels) timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400; + + if (timePlayed > 400) StopMusicStream(music); //---------------------------------------------------------------------------------- // Draw diff --git a/examples/src/audio/audio_raw_stream.c b/examples/src/audio/audio_raw_stream.c index 7eee46f..d7fa5d7 100644 --- a/examples/src/audio/audio_raw_stream.c +++ b/examples/src/audio/audio_raw_stream.c @@ -7,7 +7,7 @@ * This example has been created using raylib 1.6 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2015-2018 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox) +* Copyright (c) 2015-2019 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox) * ********************************************************************************************/ diff --git a/examples/src/core/core_2d_camera.c b/examples/src/core/core_2d_camera.c index 7c35c90..6a0b11a 100644 --- a/examples/src/core/core_2d_camera.c +++ b/examples/src/core/core_2d_camera.c @@ -105,8 +105,8 @@ int main() DrawRectangleRec(player, RED); - DrawRectangle(camera.target.x, -500, 1, screenHeight*4, GREEN); - DrawRectangle(-500, camera.target.y, screenWidth*4, 1, GREEN); + DrawLine(camera.target.x, -screenHeight*10, camera.target.x, screenHeight*10, GREEN); + DrawLine(-screenWidth*10, camera.target.y, screenWidth*10, camera.target.y, GREEN); EndMode2D(); diff --git a/examples/src/core/core_3d_mode.c b/examples/src/core/core_3d_camera_mode.c index 39c0752..a496220 100644 --- a/examples/src/core/core_3d_mode.c +++ b/examples/src/core/core_3d_camera_mode.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - Initialize 3d mode +* raylib [core] example - Initialize 3d camera mode * * 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) @@ -15,13 +15,13 @@ int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; + const int screenWidth = 800; + const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d mode"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera mode"); // Define the camera to look into our 3d world - Camera3D camera; + Camera3D camera = { 0 }; camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) diff --git a/examples/src/core/core_basic_window.c b/examples/src/core/core_basic_window.c index 51caa45..b30f05d 100644 --- a/examples/src/core/core_basic_window.c +++ b/examples/src/core/core_basic_window.c @@ -1,6 +1,16 @@ /******************************************************************************************* * -* raylib [core] example - basic window +* raylib [core] example - Basic window +* +* Welcome to raylib! +* +* To test examples, just press F6 and execute raylib_compile_execute script +* Note that compiled executable is placed in the same folder as .c file +* +* You can find all basic examples on C:\raylib\raylib\examples folder or +* raylib official webpage: www.raylib.com +* +* Enjoy using raylib. :) * * 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) diff --git a/examples/src/core/core_color_select.c b/examples/src/core/core_color_select.c deleted file mode 100644 index 002a693..0000000 --- a/examples/src/core/core_color_select.c +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************************* -* -* raylib [core] example - Color selection by mouse (collision detection) -* -* 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 (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; - - InitWindow(screenWidth, screenHeight, "raylib [core] example - color selection (collision detection)"); - - Color colors[21] = { DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN, - GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW, - GREEN, SKYBLUE, PURPLE, BEIGE }; - - Rectangle colorsRecs[21]; // Rectangles array - - // Fills colorsRecs data (for every rectangle) - for (int i = 0; i < 21; i++) - { - colorsRecs[i].x = 20 + 100*(i%7) + 10*(i%7); - colorsRecs[i].y = 60 + 100*(i/7) + 10*(i/7); - colorsRecs[i].width = 100; - colorsRecs[i].height = 100; - } - - bool selected[21] = { false }; // Selected rectangles indicator - - Vector2 mousePoint; - - 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 - //---------------------------------------------------------------------------------- - mousePoint = GetMousePosition(); - - for (int i = 0; i < 21; i++) // Iterate along all the rectangles - { - if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) - { - colors[i].a = 120; - - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) selected[i] = !selected[i]; - } - else colors[i].a = 255; - } - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - for (int i = 0; i < 21; i++) // Draw all rectangles - { - DrawRectangleRec(colorsRecs[i], colors[i]); - - // Draw four rectangles around selected rectangle - if (selected[i]) - { - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 100, 10, RAYWHITE); // Square top rectangle - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 10, 100, RAYWHITE); // Square left rectangle - DrawRectangle(colorsRecs[i].x + 90, colorsRecs[i].y, 10, 100, RAYWHITE); // Square right rectangle - DrawRectangle(colorsRecs[i].x, colorsRecs[i].y + 90, 100, 10, RAYWHITE); // Square bottom rectangle - } - } - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -}
\ No newline at end of file diff --git a/examples/src/core/core_custom_logging.c b/examples/src/core/core_custom_logging.c new file mode 100644 index 0000000..cf1a601 --- /dev/null +++ b/examples/src/core/core_custom_logging.c @@ -0,0 +1,84 @@ +/******************************************************************************************* +* +* raylib [core] example - Custom logging +* +* This example has been created using raylib 2.1 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Pablo Marcos Oltra (@pamarcos) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Pablo Marcos Oltra (@pamarcos) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen() +#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime() + +// Custom logging funtion +void LogCustom(int msgType, const char *text, va_list args) +{ + char timeStr[64]; + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + + strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info); + printf("[%s] ", timeStr); + + switch (msgType) + { + case LOG_INFO: printf("[INFO] : "); break; + case LOG_ERROR: printf("[ERROR]: "); break; + case LOG_WARNING: printf("[WARN] : "); break; + case LOG_DEBUG: printf("[DEBUG]: "); break; + default: break; + } + + vprintf(text, args); + printf("\n"); +} + +int main(int argc, char* argv[]) +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + // First thing we do is setting our custom logger to ensure everything raylib logs + // will use our own logger instead of its internal one + SetTraceLogCallback(LogCustom); + + InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging"); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Check out the console output to see the custom logger in action!", 60, 200, 20, LIGHTGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/core/core_input_gamepad.c b/examples/src/core/core_input_gamepad.c index 64520a4..e8a1c05 100644 --- a/examples/src/core/core_input_gamepad.c +++ b/examples/src/core/core_input_gamepad.c @@ -66,93 +66,93 @@ int main() DrawTexture(texXboxPad, 0, 0, DARKGRAY); // Draw buttons: xbox home - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_HOME)) DrawCircle(394, 89, 19, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(394, 89, 19, RED); // Draw buttons: basic - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_START)) DrawCircle(436, 150, 9, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_SELECT)) DrawCircle(352, 150, 9, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_X)) DrawCircle(501, 151, 15, BLUE); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_A)) DrawCircle(536, 187, 15, LIME); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_B)) DrawCircle(572, 151, 15, MAROON); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_Y)) DrawCircle(536, 115, 15, GOLD); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(436, 150, 9, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(352, 150, 9, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(501, 151, 15, BLUE); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(536, 187, 15, LIME); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(572, 151, 15, MAROON); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(536, 115, 15, GOLD); // Draw buttons: d-pad DrawRectangle(317, 202, 19, 71, BLACK); DrawRectangle(293, 228, 69, 19, BLACK); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_UP)) DrawRectangle(317, 202, 19, 26, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_LEFT)) DrawRectangle(292, 228, 25, 19, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(317, 202, 19, 26, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(292, 228, 25, 19, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED); // Draw buttons: left-right back - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_LB)) DrawCircle(259, 61, 20, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_RB)) DrawCircle(536, 61, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(259, 61, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(536, 61, 20, RED); // Draw axis: left joystick DrawCircle(259, 152, 39, BLACK); DrawCircle(259, 152, 34, LIGHTGRAY); - DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_X)*20), - 152 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_Y)*20), 25, BLACK); + DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_X)*20), + 152 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK); // Draw axis: right joystick DrawCircle(461, 237, 38, BLACK); DrawCircle(461, 237, 33, LIGHTGRAY); - DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RIGHT_X)*20), - 237 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RIGHT_Y)*20), 25, BLACK); + DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_X)*20), + 237 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK); // Draw axis: left-right triggers DrawRectangle(170, 30, 15, 70, GRAY); DrawRectangle(604, 30, 15, 70, GRAY); - DrawRectangle(170, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LT))/2.0f)*70), RED); - DrawRectangle(604, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RT))/2.0f)*70), RED); + DrawRectangle(170, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_TRIGGER))/2.0f)*70), RED); + DrawRectangle(604, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_TRIGGER))/2.0f)*70), RED); - //DrawText(FormatText("Xbox axis LT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LT)), 10, 40, 10, BLACK); - //DrawText(FormatText("Xbox axis RT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RT)), 10, 60, 10, BLACK); + //DrawText(FormatText("Xbox axis LT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK); + //DrawText(FormatText("Xbox axis RT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK); } else if (IsGamepadName(GAMEPAD_PLAYER1, PS3_NAME_ID)) { DrawTexture(texPs3Pad, 0, 0, DARKGRAY); // Draw buttons: ps - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_PS)) DrawCircle(396, 222, 13, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(396, 222, 13, RED); // Draw buttons: basic - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_SELECT)) DrawRectangle(328, 170, 32, 13, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_START)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_TRIANGLE)) DrawCircle(557, 144, 13, LIME); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_CIRCLE)) DrawCircle(586, 173, 13, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_CROSS)) DrawCircle(557, 203, 13, VIOLET); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_SQUARE)) DrawCircle(527, 173, 13, PINK); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawRectangle(328, 170, 32, 13, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(557, 144, 13, LIME); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(586, 173, 13, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(557, 203, 13, VIOLET); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(527, 173, 13, PINK); // Draw buttons: d-pad DrawRectangle(225, 132, 24, 84, BLACK); DrawRectangle(195, 161, 84, 25, BLACK); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_UP)) DrawRectangle(225, 132, 24, 29, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_LEFT)) DrawRectangle(195, 161, 30, 25, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(225, 132, 24, 29, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(195, 161, 30, 25, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED); // Draw buttons: left-right back buttons - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_L1)) DrawCircle(239, 82, 20, RED); - if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_R1)) DrawCircle(557, 82, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(239, 82, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(557, 82, 20, RED); // Draw axis: left joystick DrawCircle(319, 255, 35, BLACK); DrawCircle(319, 255, 31, LIGHTGRAY); - DrawCircle(319 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_X)*20), - 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_Y)*20), 25, BLACK); + DrawCircle(319 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK); // Draw axis: right joystick DrawCircle(475, 255, 35, BLACK); DrawCircle(475, 255, 31, LIGHTGRAY); - DrawCircle(475 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_RIGHT_X)*20), - 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_RIGHT_Y)*20), 25, BLACK); + DrawCircle(475 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK); // Draw axis: left-right triggers DrawRectangle(169, 48, 15, 70, GRAY); DrawRectangle(611, 48, 15, 70, GRAY); - DrawRectangle(169, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_L2))/2.0f)*70), RED); - DrawRectangle(611, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_R2))/2.0f)*70), RED); + DrawRectangle(169, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_TRIGGER))/2.0f)*70), RED); + DrawRectangle(611, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_TRIGGER))/2.0f)*70), RED); } else { diff --git a/examples/src/core/core_gestures_detection.c b/examples/src/core/core_input_gestures.c index 63a1e6b..ce2ed86 100644 --- a/examples/src/core/core_gestures_detection.c +++ b/examples/src/core/core_input_gestures.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - Gestures Detection +* raylib [core] example - Input Gestures Detection * * This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) @@ -21,7 +21,7 @@ int main() int screenWidth = 800; int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures"); Vector2 touchPosition = { 0, 0 }; Rectangle touchArea = { 220, 10, screenWidth - 230, screenHeight - 20 }; diff --git a/examples/src/core/core_mouse_wheel.c b/examples/src/core/core_input_mouse_wheel.c index 6a5252e..48cf704 100644 --- a/examples/src/core/core_mouse_wheel.c +++ b/examples/src/core/core_input_mouse_wheel.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] examples - Mouse wheel +* raylib [core] examples - Mouse wheel input * * 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) @@ -18,7 +18,7 @@ int main() int screenWidth = 800; int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse wheel"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel"); int boxPositionY = screenHeight/2 - 40; int scrollSpeed = 4; // Scrolling speed in pixels diff --git a/examples/src/core/core_input_multitouch.c b/examples/src/core/core_input_multitouch.c new file mode 100644 index 0000000..5baab27 --- /dev/null +++ b/examples/src/core/core_input_multitouch.c @@ -0,0 +1,89 @@ +/******************************************************************************************* +* +* raylib [core] example - Input multitouch +* +* This example has been created using raylib 2.1 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Berni (@Berni8k) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - input multitouch"); + + Vector2 ballPosition = { -100.0f, -100.0f }; + Color ballColor = BEIGE; + + int touchCounter = 0; + Vector2 touchPosition; + + SetTargetFPS(60); + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + ballPosition = GetMousePosition(); + + ballColor = BEIGE; + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) ballColor = MAROON; + if (IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) ballColor = LIME; + if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) ballColor = DARKBLUE; + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) touchCounter = 10; + if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) touchCounter = 10; + if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) touchCounter = 10; + + if (touchCounter > 0) touchCounter--; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Multitouch + for (int i = 0; i < MAX_TOUCH_POINTS; ++i) + { + touchPosition = GetTouchPosition(i); // Get the touch point + + if ((touchPosition.x >= 0) && (touchPosition.y >= 0)) // Make sure point is not (-1,-1) as this means there is no touch for it + { + // Draw circle and touch index number + DrawCircleV(touchPosition, 34, ORANGE); + DrawText(FormatText("%d", i), touchPosition.x - 10, touchPosition.y - 70, 40, BLACK); + } + } + + // Draw the normal mouse location + DrawCircleV(ballPosition, 30 + (touchCounter*3), ballColor); + + DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY); + DrawText("touch the screen at multiple locations to get multiple balls", 10, 30, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/core/core_loading_thread.c b/examples/src/core/core_loading_thread.c new file mode 100644 index 0000000..1dacd69 --- /dev/null +++ b/examples/src/core/core_loading_thread.c @@ -0,0 +1,147 @@ +/******************************************************************************************* +* +* raylib example - loading thread +* +* NOTE: This example requires linking with pthreads library, +* on MinGW, it can be accomplished passing -static parameter to compiler +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "pthread.h" // POSIX style threads management + +#include <stdatomic.h> // C11 atomic data types + +#include <time.h> // Required for: clock() + +// Using C11 atomics for synchronization +// NOTE: A plain bool (or any plain data type for that matter) can't be used for inter-thread synchronization +static atomic_bool dataLoaded = ATOMIC_VAR_INIT(false); // Data Loaded completion indicator +static void *LoadDataThread(void *arg); // Loading data thread function declaration + +static int dataProgress = 0; // Data progress accumulator + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - loading thread"); + + pthread_t threadId; // Loading data thread id + + enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING; + int framesCounter = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + switch (state) + { + case STATE_WAITING: + { + if (IsKeyPressed(KEY_ENTER)) + { + int error = pthread_create(&threadId, NULL, &LoadDataThread, NULL); + if (error != 0) TraceLog(LOG_ERROR, "Error creating loading thread"); + else TraceLog(LOG_INFO, "Loading thread initialized successfully"); + + state = STATE_LOADING; + } + } break; + case STATE_LOADING: + { + framesCounter++; + if (atomic_load(&dataLoaded)) + { + framesCounter = 0; + state = STATE_FINISHED; + } + } break; + case STATE_FINISHED: + { + if (IsKeyPressed(KEY_ENTER)) + { + // Reset everything to launch again + atomic_store(&dataLoaded, false); + dataProgress = 0; + state = STATE_WAITING; + } + } break; + default: break; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + switch (state) + { + case STATE_WAITING: DrawText("PRESS ENTER to START LOADING DATA", 150, 170, 20, DARKGRAY); break; + case STATE_LOADING: + { + DrawRectangle(150, 200, dataProgress, 60, SKYBLUE); + if ((framesCounter/15)%2) DrawText("LOADING DATA...", 240, 210, 40, DARKBLUE); + + } break; + case STATE_FINISHED: + { + DrawRectangle(150, 200, 500, 60, LIME); + DrawText("DATA LOADED!", 250, 210, 40, GREEN); + + } break; + default: break; + } + + DrawRectangleLines(150, 200, 500, 60, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +// Loading data thread function definition +static void *LoadDataThread(void *arg) +{ + int timeCounter = 0; // Time counted in ms + clock_t prevTime = clock(); // Previous time + + // We simulate data loading with a time counter for 5 seconds + while (timeCounter < 5000) + { + clock_t currentTime = clock() - prevTime; + timeCounter = currentTime*1000/CLOCKS_PER_SEC; + + // We accumulate time over a global variable to be used in + // main thread as a progress bar + dataProgress = timeCounter/10; + } + + // When data has finished loading, we set global variable + atomic_store(&dataLoaded, true); + + return NULL; +} diff --git a/examples/src/core/core_vr_simulator.c b/examples/src/core/core_vr_simulator.c index 3f59e83..65054b7 100644 --- a/examples/src/core/core_vr_simulator.c +++ b/examples/src/core/core_vr_simulator.c @@ -23,7 +23,35 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator"); // Init VR simulator (Oculus Rift CV1 parameters) - InitVrSimulator(GetVrDeviceInfo(HMD_OCULUS_RIFT_CV1)); + InitVrSimulator(); + + VrDeviceInfo hmd = { 0 }; // VR device parameters (head-mounted-device) + + // Oculus Rift CV1 parameters for simulator + hmd.hResolution = 2160; // HMD horizontal resolution in pixels + hmd.vResolution = 1200; // HMD vertical resolution in pixels + hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters + hmd.vScreenSize = 0.0669f; // HMD vertical size in meters + hmd.vScreenCenter = 0.04678f; // HMD screen center in meters + hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters + hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters + hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters + + // NOTE: CV1 uses a Fresnel-hybrid-asymmetric lenses with specific distortion compute shaders. + // Following parameters are an approximation to distortion stereo rendering but results differ from actual device. + hmd.lensDistortionValues[0] = 1.0f; // HMD lens distortion constant parameter 0 + hmd.lensDistortionValues[1] = 0.22f; // HMD lens distortion constant parameter 1 + hmd.lensDistortionValues[2] = 0.24f; // HMD lens distortion constant parameter 2 + hmd.lensDistortionValues[3] = 0.0f; // HMD lens distortion constant parameter 3 + hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 + hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 + hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 + hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 + + // Distortion shader (uses device lens distortion and chroma) + Shader distortion = LoadShader(0, "resources/distortion.fs"); + + SetVrConfiguration(hmd, distortion); // Set Vr device parameters for stereo rendering // Define the camera to look into our 3d world Camera camera; @@ -77,9 +105,11 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseVrSimulator(); // Close VR simulator - - CloseWindow(); // Close window and OpenGL context + UnloadShader(distortion); // Unload distortion shader + + CloseVrSimulator(); // Close VR simulator + + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/src/core/core_window_letterbox.c b/examples/src/core/core_window_letterbox.c new file mode 100644 index 0000000..8c0843d --- /dev/null +++ b/examples/src/core/core_window_letterbox.c @@ -0,0 +1,90 @@ +/******************************************************************************************* +* +* raylib [core] example - window scale letterbox +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Anata (@anatagawa) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Anata (@anatagawa) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define max(a, b) ((a)>(b)? (a) : (b)) +#define min(a, b) ((a)<(b)? (a) : (b)) + +int main() +{ + const int windowWidth = 800; + const int windowHeight = 450; + + // Enable config flags for resizable window and vertical synchro + SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT); + InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox"); + SetWindowMinSize(320, 240); + + int gameScreenWidth = 640; + int gameScreenHeight = 480; + + // Render texture initialization + RenderTexture2D target = LoadRenderTexture(gameScreenWidth, gameScreenHeight); + SetTextureFilter(target.texture, FILTER_BILINEAR); // Texture scale filter to use + + Color colors[10] = { 0 }; + for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 }; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while( !WindowShouldClose() ) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Compute required framebuffer scaling + float scale = min((float)GetScreenWidth()/gameScreenWidth, (float)GetScreenHeight()/gameScreenHeight); + + if (IsKeyPressed(KEY_SPACE)) + { + // Recalculate random colors for the bars + for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 }; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(BLACK); + + // Draw everything in the render texture + BeginTextureMode(target); + + ClearBackground(RAYWHITE); // Clear render texture background color + + for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]); + + DrawText("You can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE); + + EndTextureMode(); + + // Draw RenderTexture2D to window, properly scaled + DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height }, + (Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5, + (float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE); + + EndDrawing(); + //-------------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadRenderTexture(target); // Unload render texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/models/models_animation.c b/examples/src/models/models_animation.c new file mode 100644 index 0000000..a75241b --- /dev/null +++ b/examples/src/models/models_animation.c @@ -0,0 +1,101 @@ +/******************************************************************************************* +* +* raylib [models] example - Load 3d model with animations and play them +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2019 Ramon Santamaria (@raysan5) and @culacant +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.type = CAMERA_PERSPECTIVE; // Camera mode type + + + Model model = LoadModel("resources/guy/guy.iqm"); // Load the animated model mesh and basic data + Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material + SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture + + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + + // Load animation data + int animsCount = 0; + ModelAnimation *anims = LoadModelAnimations("resources/guy/guyanim.iqm", &animsCount); + int animFrameCounter = 0; + + SetCameraMode(camera, CAMERA_FREE); // Set free 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 + //---------------------------------------------------------------------------------- + UpdateCamera(&camera); + + // Play animation when spacebar is held down + if (IsKeyDown(KEY_SPACE)) + { + animFrameCounter++; + UpdateModelAnimation(model, anims[0], animFrameCounter); + if (animFrameCounter >= anims[0].frameCount) animFrameCounter = 0; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE); + + for (int i = 0; i < model.boneCount; i++) + { + DrawCube(anims[0].framePoses[animFrameCounter][i].translation, 0.2f, 0.2f, 0.2f, RED); + } + + DrawGrid(10, 1.0f); // Draw a grid + + EndMode3D(); + + DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON); + DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + // Unload model animations data + for (int i = 0; i < animsCount; i++) UnloadModelAnimation(anims[i]); + + UnloadModel(model); // Unload model + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/models/models_billboard.c b/examples/src/models/models_billboard.c index 8ce6a44..5965571 100644 --- a/examples/src/models/models_billboard.c +++ b/examples/src/models/models_billboard.c @@ -28,7 +28,6 @@ int main() camera.fovy = 45.0f; camera.type = CAMERA_PERSPECTIVE; - Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard Vector3 billPosition = { 0.0f, 2.0f, 0.0f }; // Position where draw billboard @@ -52,11 +51,11 @@ int main() ClearBackground(RAYWHITE); BeginMode3D(camera); - - DrawBillboard(camera, bill, billPosition, 2.0f, WHITE); DrawGrid(10, 1.0f); // Draw a grid - + + DrawBillboard(camera, bill, billPosition, 2.0f, WHITE); + EndMode3D(); DrawFPS(10, 10); diff --git a/examples/src/models/models_cubicmap.c b/examples/src/models/models_cubicmap.c index c8d62c4..ac24188 100644 --- a/examples/src/models/models_cubicmap.c +++ b/examples/src/models/models_cubicmap.c @@ -31,7 +31,7 @@ int main() // NOTE: By default each cube is mapped to one part of texture atlas Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture - model.material.maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position diff --git a/examples/src/models/models_first_person_maze.c b/examples/src/models/models_first_person_maze.c new file mode 100644 index 0000000..093334b --- /dev/null +++ b/examples/src/models/models_first_person_maze.c @@ -0,0 +1,126 @@ +/******************************************************************************************* +* +* raylib [models] example - first person maze +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <stdlib.h> // Required for: free() + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - first person maze"); + + // Define the camera to look into our 3d world + Camera camera = {{ 0.2f, 0.4f, 0.2f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; + + Image imMap = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM) + Texture2D cubicmap = LoadTextureFromImage(imMap); // Convert image to texture to display (VRAM) + Mesh mesh = GenMeshCubicmap(imMap, (Vector3){ 1.0f, 1.0f, 1.0f }); + Model model = LoadModelFromMesh(mesh); + + // NOTE: By default each cube is mapped to one part of texture atlas + Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture + + // Get map image data to be used for collision detection + Color *mapPixels = GetImageData(imMap); + UnloadImage(imMap); // Unload image from RAM + + Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position + Vector3 playerPosition = camera.position; // Set player position + + SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set 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 + //---------------------------------------------------------------------------------- + Vector3 oldCamPos = camera.position; // Store old camera position + + UpdateCamera(&camera); // Update camera + + // Check player collision (we simplify to 2D collision detection) + Vector2 playerPos = { camera.position.x, camera.position.z }; + float playerRadius = 0.1f; // Collision radius (player is modelled as a cilinder for collision) + + int playerCellX = (int)(playerPos.x - mapPosition.x + 0.5f); + int playerCellY = (int)(playerPos.y - mapPosition.z + 0.5f); + + // Out-of-limits security check + if (playerCellX < 0) playerCellX = 0; + else if (playerCellX >= cubicmap.width) playerCellX = cubicmap.width - 1; + + if (playerCellY < 0) playerCellY = 0; + else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1; + + // Check map collisions using image data and player position + // TODO: Improvement: Just check player surrounding cells for collision + for (int y = 0; y < cubicmap.height; y++) + { + for (int x = 0; x < cubicmap.width; x++) + { + if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel + (CheckCollisionCircleRec(playerPos, playerRadius, + (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) + { + // Collision detected, reset camera position + camera.position = oldCamPos; + } + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawModel(model, mapPosition, 1.0f, WHITE); // Draw maze map + //DrawCubeV(playerPosition, (Vector3){ 0.2f, 0.4f, 0.2f }, RED); // Draw player + + EndMode3D(); + + DrawTextureEx(cubicmap, (Vector2){ GetScreenWidth() - cubicmap.width*4 - 20, 20 }, 0.0f, 4.0f, WHITE); + DrawRectangleLines(GetScreenWidth() - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN); + + // Draw player position radar + DrawRectangle(GetScreenWidth() - cubicmap.width*4 - 20 + playerCellX*4, 20 + playerCellY*4, 4, 4, RED); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + free(mapPixels); // Unload color array + + UnloadTexture(cubicmap); // Unload cubicmap texture + UnloadTexture(texture); // Unload map texture + UnloadModel(model); // Unload map model + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/models/models_heightmap.c b/examples/src/models/models_heightmap.c index d131b12..e0475f1 100644 --- a/examples/src/models/models_heightmap.c +++ b/examples/src/models/models_heightmap.c @@ -29,7 +29,7 @@ int main() Mesh mesh = GenMeshHeightmap(image, (Vector3){ 16, 8, 16 }); // Generate heightmap mesh (RAM and VRAM) Model model = LoadModelFromMesh(mesh); // Load model from generated mesh - model.material.maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Define model position UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM diff --git a/examples/src/models/models_material_pbr.c b/examples/src/models/models_material_pbr.c index 9f57634..5c308cf 100644 --- a/examples/src/models/models_material_pbr.c +++ b/examples/src/models/models_material_pbr.c @@ -12,6 +12,8 @@ #include "raylib.h" #include "raymath.h" +#include <stdio.h> + #define RLIGHTS_IMPLEMENTATION #include "rlights.h" @@ -34,19 +36,29 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material"); // Define the camera to look into our 3d world - Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + Camera camera = { 0 }; + camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.type = CAMERA_PERSPECTIVE; // Camera mode type // Load model and PBR material Model model = LoadModel("resources/pbr/trooper.obj"); - model.material = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); + + // Mesh tangents are generated... and uploaded to GPU + // NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO + MeshTangents(&model.meshes[0]); + + model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); // Define lights attributes // NOTE: Shader is passed to every light on creation to define shader bindings internally Light lights[MAX_LIGHTS] = { - CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader), - CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.material.shader), - CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader), - CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader) + CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.materials[0].shader), + CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.materials[0].shader), + CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.materials[0].shader), + CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.materials[0].shader) }; SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode @@ -63,7 +75,7 @@ int main() // Send to material PBR shader camera view position float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; - SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, 3); + SetShaderValue(model.materials[0].shader, model.materials[0].shader.locs[LOC_VECTOR_VIEW], cameraPos, UNIFORM_VEC3); //---------------------------------------------------------------------------------- // Draw @@ -72,13 +84,13 @@ int main() ClearBackground(RAYWHITE); - Begin3dMode(camera); + BeginMode3D(camera); DrawModel(model, Vector3Zero(), 1.0f, WHITE); DrawGrid(10, 1.0f); - End3dMode(); + EndMode3D(); DrawFPS(10, 10); @@ -113,7 +125,7 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler"); mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler"); mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler"); - mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler"); + mat.shader.locs[LOC_MAP_OCCLUSION] = GetShaderLocation(mat.shader, "occlusion.sampler"); //mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler"); //mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler"); mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap"); @@ -121,7 +133,7 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT"); // Set view matrix location - mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix"); + mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "matModel"); mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view"); mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos"); @@ -142,20 +154,24 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) #define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS); + printf("Loaded shader: cubemap\n"); Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); + printf("Loaded shader: irradiance\n"); Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); + printf("Loaded shader: prefilter\n"); Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); + printf("Loaded shader: brdf\n"); // Setup required shader locations - SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, 1); - SetShaderValuei(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, 1); - SetShaderValuei(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, 1); + SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT); + SetShaderValue(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT); + SetShaderValue(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT); - Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); + Texture2D texHDR = LoadTexture("resources/dresden_square.hdr"); Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE); mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE); mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE); - mat.maps[MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, cubemap, BRDF_SIZE); + mat.maps[MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, BRDF_SIZE); UnloadTexture(cubemap); UnloadTexture(texHDR); @@ -173,14 +189,14 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR); // Enable sample usage in shader for assigned textures - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1]){ 1 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1]){ 1 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1]){ 1 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1]){ 1 }, 1); + SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, UNIFORM_INT); + SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1]){ 1 }, UNIFORM_INT); + SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1]){ 1 }, UNIFORM_INT); + SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1]){ 1 }, UNIFORM_INT); + SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1]){ 1 }, UNIFORM_INT); int renderModeLoc = GetShaderLocation(mat.shader, "renderMode"); - SetShaderValuei(mat.shader, renderModeLoc, (int[1]){ 0 }, 1); + SetShaderValue(mat.shader, renderModeLoc, (int[1]){ 0 }, UNIFORM_INT); // Set up material properties color mat.maps[MAP_ALBEDO].color = albedo; @@ -192,4 +208,4 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) mat.maps[MAP_HEIGHT].value = 0.5f; return mat; -}
\ No newline at end of file +} diff --git a/examples/src/models/models_mesh_generation.c b/examples/src/models/models_mesh_generation.c index c02bd91..2b4b75a 100644 --- a/examples/src/models/models_mesh_generation.c +++ b/examples/src/models/models_mesh_generation.c @@ -11,7 +11,7 @@ #include "raylib.h" -#define NUM_MODELS 7 // We generate 7 parametric 3d shapes +#define NUM_MODELS 8 // We generate 8 parametric 3d shapes int main() { @@ -36,9 +36,10 @@ int main() models[4] = LoadModelFromMesh(GenMeshCylinder(1, 2, 16)); models[5] = LoadModelFromMesh(GenMeshTorus(0.25f, 4.0f, 16, 32)); models[6] = LoadModelFromMesh(GenMeshKnot(1.0f, 2.0f, 16, 128)); + models[7] = LoadModelFromMesh(GenMeshPoly(5, 2.0f)); // Set checked texture as default diffuse component for all models material - for (int i = 0; i < NUM_MODELS; i++) models[i].material.maps[MAP_DIFFUSE].texture = texture; + for (int i = 0; i < NUM_MODELS; i++) models[i].materials[0].maps[MAP_DIFFUSE].texture = texture; // Define the camera to look into our 3d world Camera camera = {{ 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; @@ -64,6 +65,17 @@ int main() { currentModel = (currentModel + 1)%NUM_MODELS; // Cycle between the textures } + + if (IsKeyPressed(KEY_RIGHT)) + { + currentModel++; + if (currentModel >= NUM_MODELS) currentModel = 0; + } + else if (IsKeyPressed(KEY_LEFT)) + { + currentModel--; + if (currentModel < 0) currentModel = NUM_MODELS - 1; + } //---------------------------------------------------------------------------------- // Draw @@ -93,6 +105,7 @@ int main() case 4: DrawText("CYLINDER", 680, 10, 20, DARKBLUE); break; case 5: DrawText("TORUS", 680, 10, 20, DARKBLUE); break; case 6: DrawText("KNOT", 680, 10, 20, DARKBLUE); break; + case 7: DrawText("POLY", 680, 10, 20, DARKBLUE); break; default: break; } diff --git a/examples/src/models/models_mesh_picking.c b/examples/src/models/models_mesh_picking.c index e150fe9..4202882 100644 --- a/examples/src/models/models_mesh_picking.c +++ b/examples/src/models/models_mesh_picking.c @@ -13,7 +13,7 @@ #include "raylib.h" #include "raymath.h" -#define FLT_MAX 3.40282347E+38F // Maximum value of a float, defined in <float.h> +#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111 int main() { @@ -25,20 +25,21 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking"); // Define the camera to look into our 3d world - Camera camera; - camera.position = (Vector3){ 10.0f, 8.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 2.3f, 0.0f }; // Camera looking at point + Camera camera = { 0 }; + camera.position = (Vector3){ 20.0f, 20.0f, 20.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 8.0f, 0.0f }; // Camera looking at point camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y + camera.type = CAMERA_PERSPECTIVE; // Camera mode type - Ray ray; // Picking ray + Ray ray = { 0 }; // Picking ray - Model tower = LoadModel("resources/tower.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/tower.png"); // Load model texture - tower.material.maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture + Model tower = LoadModel("resources/models/turret.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/turret_diffuse.png"); // Load model texture + tower.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position - BoundingBox towerBBox = CalculateBoundingBox(tower.mesh); + BoundingBox towerBBox = MeshBoundingBox(tower.meshes[0]); // Get mesh bounding box bool hitMeshBBox = false; bool hitTriangle = false; @@ -61,7 +62,7 @@ int main() UpdateCamera(&camera); // Update camera // Display information about closest hit - RayHitInfo nearestHit; + RayHitInfo nearestHit = { 0 }; char *hitObjectName = "None"; nearestHit.distance = FLT_MAX; nearestHit.hit = false; @@ -94,15 +95,16 @@ int main() } else hitTriangle = false; - RayHitInfo meshHitInfo; + RayHitInfo meshHitInfo = { 0 }; // Check ray collision against bounding box first, before trying the full ray-mesh test if (CheckCollisionRayBox(ray, towerBBox)) { hitMeshBBox = true; - // Check ray collision against mesh - meshHitInfo = GetCollisionRayMesh(ray, &tower.mesh); + // Check ray collision against model + // NOTE: It considers model.transform matrix! + meshHitInfo = GetCollisionRayModel(ray, &tower); if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) { @@ -111,7 +113,9 @@ int main() hitObjectName = "Mesh"; } - } hitMeshBBox = false; + } + + hitMeshBBox = false; //---------------------------------------------------------------------------------- // Draw @@ -120,10 +124,12 @@ int main() ClearBackground(RAYWHITE); - Begin3dMode(camera); + BeginMode3D(camera); // Draw the tower - DrawModel(tower, towerPos, 1.0, WHITE); + // WARNING: If scale is different than 1.0f, + // not considered by GetCollisionRayModel() + DrawModel(tower, towerPos, 1.0f, WHITE); // Draw the test triangle DrawLine3D(ta, tb, PURPLE); @@ -149,9 +155,9 @@ int main() DrawRay(ray, MAROON); - DrawGrid(100, 1.0f); + DrawGrid(10, 10.0f); - End3dMode(); + EndMode3D(); // Draw some debug GUI text DrawText(FormatText("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK); @@ -176,6 +182,8 @@ int main() } DrawText("Use Mouse to Move Camera", 10, 430, 10, GRAY); + + DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawFPS(10, 10); diff --git a/examples/src/models/models_obj_loading.c b/examples/src/models/models_obj_loading.c index 70f9216..74e7d08 100644 --- a/examples/src/models/models_obj_loading.c +++ b/examples/src/models/models_obj_loading.c @@ -21,11 +21,16 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading"); // Define the camera to look into our 3d world - Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; - - Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture - dwarf.material.maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture + Camera camera = { 0 }; + camera.position = (Vector3){ 8.0f, 8.0f, 8.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.5f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.type = CAMERA_PERSPECTIVE; // Camera mode type + + Model model = LoadModel("resources/models/castle.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/castle_diffuse.png"); // Load model texture + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -45,17 +50,17 @@ int main() ClearBackground(RAYWHITE); - Begin3dMode(camera); + BeginMode3D(camera); - DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture + DrawModel(model, position, 0.2f, WHITE); // Draw 3d model with texture DrawGrid(10, 1.0f); // Draw a grid DrawGizmo(position); // Draw gizmo - End3dMode(); - - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); + EndMode3D(); + + DrawText("(c) Castle 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawFPS(10, 10); @@ -66,7 +71,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- UnloadTexture(texture); // Unload texture - UnloadModel(dwarf); // Unload model + UnloadModel(model); // Unload model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/src/models/models_obj_viewer.c b/examples/src/models/models_obj_viewer.c new file mode 100644 index 0000000..7d38744 --- /dev/null +++ b/examples/src/models/models_obj_viewer.c @@ -0,0 +1,127 @@ +/******************************************************************************************* +* +* raylib [models] example - OBJ models viewer +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <string.h> // Required for: strcpy() + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib example - obj viewer"); + + // Define the camera to look into our 3d world + Camera camera = {{ 30.0f, 30.0f, 30.0f }, { 0.0f, 10.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; + + Model model = LoadModel("resources/models/turret.obj"); // Load default model obj + Texture2D texture = LoadTexture("resources/models/turret_diffuse.png"); // Load default model texture + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model + + Vector3 position = { 0.0, 0.0, 0.0 }; // Set model position + BoundingBox bounds = MeshBoundingBox(model.meshes[0]); // Set model bounds + bool selected = false; // Selected object flag + + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode + + char objFilename[64] = "turret.obj"; + + 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 (IsFileDropped()) + { + int count = 0; + char **droppedFiles = GetDroppedFiles(&count); + + if (count == 1) + { + if (IsFileExtension(droppedFiles[0], ".obj")) + { + for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]); + model.meshes = LoadMeshes(droppedFiles[0], &model.meshCount); + bounds = MeshBoundingBox(model.meshes[0]); + } + else if (IsFileExtension(droppedFiles[0], ".png")) + { + UnloadTexture(texture); + texture = LoadTexture(droppedFiles[0]); + model.materials[0].maps[MAP_DIFFUSE].texture = texture; + } + + strcpy(objFilename, GetFileName(droppedFiles[0])); + } + + ClearDroppedFiles(); // Clear internal buffers + } + + UpdateCamera(&camera); + + // Select model on mouse click + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + // Check collision between ray and box + if (CheckCollisionRayBox(GetMouseRay(GetMousePosition(), camera), bounds)) selected = !selected; + else selected = false; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawModel(model, position, 1.0f, WHITE); // Draw 3d model with texture + + DrawGrid(20.0, 10.0); // Draw a grid + + if (selected) DrawBoundingBox(bounds, GREEN); + + EndMode3D(); + + DrawText("Free camera default controls:", 10, 20, 10, DARKGRAY); + DrawText("- Mouse Wheel to Zoom in-out", 20, 40, 10, GRAY); + DrawText("- Mouse Wheel Pressed to Pan", 20, 60, 10, GRAY); + DrawText("- Alt + Mouse Wheel Pressed to Rotate", 20, 80, 10, GRAY); + DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 20, 100, 10, GRAY); + + DrawText("Drag & drop .obj/.png to load mesh/texture.", 10, GetScreenHeight() - 20, 10, DARKGRAY); + DrawText(FormatText("Current file: %s", objFilename), 250, GetScreenHeight() - 20, 10, GRAY); + if (selected) DrawText("MODEL SELECTED", GetScreenWidth() - 110, 10, 10, GREEN); + + DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(model); // Unload model + + ClearDroppedFiles(); // Clear internal buffers + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/models/models_orthographic_projection.c b/examples/src/models/models_orthographic_projection.c new file mode 100644 index 0000000..3ad32b6 --- /dev/null +++ b/examples/src/models/models_orthographic_projection.c @@ -0,0 +1,99 @@ +/******************************************************************************************* +* +* raylib [models] example - Show the difference between perspective and orthographic projection +* +* This program is heavily based on the geometric objects example +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Max Danielsson (@autious) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Max Danielsson (@autious) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define FOVY_PERSPECTIVE 45.0f +#define WIDTH_ORTHOGRAPHIC 10.0f + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes"); + + // Define the camera to look into our 3d world + Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, FOVY_PERSPECTIVE, CAMERA_PERSPECTIVE }; + + 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_SPACE)) + { + if (camera.type == CAMERA_PERSPECTIVE) + { + camera.fovy = WIDTH_ORTHOGRAPHIC; + camera.type = CAMERA_ORTHOGRAPHIC; + } + else + { + camera.fovy = FOVY_PERSPECTIVE; + camera.type = CAMERA_PERSPECTIVE; + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawCube((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, RED); + DrawCubeWires((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, GOLD); + DrawCubeWires((Vector3){-4.0f, 0.0f, -2.0f}, 3.0f, 6.0f, 2.0f, MAROON); + + DrawSphere((Vector3){-1.0f, 0.0f, -2.0f}, 1.0f, GREEN); + DrawSphereWires((Vector3){1.0f, 0.0f, 2.0f}, 2.0f, 16, 16, LIME); + + DrawCylinder((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, SKYBLUE); + DrawCylinderWires((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, DARKBLUE); + DrawCylinderWires((Vector3){4.5f, -1.0f, 2.0f}, 1.0f, 1.0f, 2.0f, 6, BROWN); + + DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD); + DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK); + + DrawGrid(10, 1.0f); // Draw a grid + + EndMode3D(); + + DrawText("Press Spacebar to switch camera type", 10, GetScreenHeight() - 30, 20, DARKGRAY); + + if (camera.type == CAMERA_ORTHOGRAPHIC) DrawText("ORTHOGRAPHIC", 10, 40, 20, BLACK); + else if (camera.type == CAMERA_PERSPECTIVE) DrawText("PERSPECTIVE", 10, 40, 20, BLACK); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/models/models_rlgl_solar_system.c b/examples/src/models/models_rlgl_solar_system.c new file mode 100644 index 0000000..7193d6f --- /dev/null +++ b/examples/src/models/models_rlgl_solar_system.c @@ -0,0 +1,168 @@ +/******************************************************************************************* +* +* raylib [models] example - rlgl module usage with push/pop matrix transformations +* +* This example uses [rlgl] module funtionality (pseudo-OpenGL 1.1 style coding) +* +* This example has been created using raylib 2.2 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2018 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "rlgl.h" + +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +void DrawSphereBasic(Color color); // Draw sphere without any matrix transformation + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + const float sunRadius = 4.0f; + const float earthRadius = 0.6f; + const float earthOrbitRadius = 8.0f; + const float moonRadius = 0.16f; + const float moonOrbitRadius = 1.5f; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - rlgl module usage with push/pop matrix transformations"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 16.0f, 16.0f, 16.0f }; + camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; + camera.fovy = 45.0f; + camera.type = CAMERA_PERSPECTIVE; + + SetCameraMode(camera, CAMERA_FREE); + + float rotationSpeed = 0.2f; // General system rotation speed + + float earthRotation = 0.0f; // Rotation of earth around itself (days) in degrees + float earthOrbitRotation = 0.0f; // Rotation of earth around the Sun (years) in degrees + float moonRotation = 0.0f; // Rotation of moon around itself + float moonOrbitRotation = 0.0f; // Rotation of moon around earth in degrees + + 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); + + earthRotation += (5.0f*rotationSpeed); + earthOrbitRotation += (365/360.0f*(5.0f*rotationSpeed)*rotationSpeed); + moonRotation += (2.0f*rotationSpeed); + moonOrbitRotation += (8.0f*rotationSpeed); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + rlPushMatrix(); + rlScalef(sunRadius, sunRadius, sunRadius); // Scale Sun + DrawSphereBasic(GOLD); // Draw the Sun + rlPopMatrix(); + + rlPushMatrix(); + rlRotatef(earthOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Earth orbit around Sun + rlTranslatef(earthOrbitRadius, 0.0f, 0.0f); // Translation for Earth orbit + rlRotatef(-earthOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Earth orbit around Sun inverted + + rlPushMatrix(); + rlRotatef(earthRotation, 0.25, 1.0, 0.0); // Rotation for Earth itself + rlScalef(earthRadius, earthRadius, earthRadius);// Scale Earth + + DrawSphereBasic(BLUE); // Draw the Earth + rlPopMatrix(); + + rlRotatef(moonOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Moon orbit around Earth + rlTranslatef(moonOrbitRadius, 0.0f, 0.0f); // Translation for Moon orbit + rlRotatef(-moonOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Moon orbit around Earth inverted + rlRotatef(moonRotation, 0.0f, 1.0f, 0.0f); // Rotation for Moon itself + rlScalef(moonRadius, moonRadius, moonRadius); // Scale Moon + + DrawSphereBasic(LIGHTGRAY); // Draw the Moon + rlPopMatrix(); + + // Some reference elements (not affected by previous matrix transformations) + DrawCircle3D((Vector3){ 0.0f, 0.0f, 0.0f }, earthOrbitRadius, (Vector3){ 1, 0, 0 }, 90.0f, Fade(RED, 0.5f)); + DrawGrid(20, 1.0f); + + EndMode3D(); + + DrawText("EARTH ORBITING AROUND THE SUN!", 400, 10, 20, MAROON); + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//-------------------------------------------------------------------------------------------- +// Module Functions Definitions (local) +//-------------------------------------------------------------------------------------------- + +// Draw sphere without any matrix transformation +// NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f +void DrawSphereBasic(Color color) +{ + int rings = 16; + int slices = 16; + + rlBegin(RL_TRIANGLES); + rlColor4ub(color.r, color.g, color.b, color.a); + + for (int i = 0; i < (rings + 2); i++) + { + for (int j = 0; j < slices; j++) + { + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices))); + + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*(i))), + cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), + sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); + } + } + rlEnd(); +} diff --git a/examples/src/models/models_skybox.c b/examples/src/models/models_skybox.c index 6f6002b..759c79c 100644 --- a/examples/src/models/models_skybox.c +++ b/examples/src/models/models_skybox.c @@ -21,7 +21,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing"); // Define the camera to look into our 3d world - Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; + Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 4.0f, 1.0f, 4.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; // Load skybox model Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); @@ -29,19 +29,19 @@ int main() // Load skybox shader and set required locations // NOTE: Some locations are automatically set at shader loading - skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs"); - SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, 1); + skybox.materials[0].shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs"); + SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, UNIFORM_INT); // Load cubemap shader and setup required shader locations Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs"); - SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, 1); + SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT); // Load HDR panorama (sphere) texture Texture2D texHDR = LoadTexture("resources/dresden_square.hdr"); // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture // NOTE: New texture is generated rendering to texture, shader computes the sphre->cube coordinates mapping - skybox.material.maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, texHDR, 512); + skybox.materials[0].maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, texHDR, 512); UnloadTexture(texHDR); // Texture not required anymore, cubemap already generated UnloadShader(shdrCubemap); // Unload cubemap generation shader, not required anymore diff --git a/examples/src/models/models_yaw_pitch_roll.c b/examples/src/models/models_yaw_pitch_roll.c index 652f168..658be08 100644 --- a/examples/src/models/models_yaw_pitch_roll.c +++ b/examples/src/models/models_yaw_pitch_roll.c @@ -5,9 +5,9 @@ * This example has been created using raylib 1.8 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Example based on Berni work on Raspberry Pi +* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5) * -* Copyright (c) 2017 Ramon Santamaria (@raysan5) +* Copyright (c) 2017 Berni (@Berni8k) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -37,10 +37,10 @@ int main() RenderTexture2D framebuffer = LoadRenderTexture(192, 192); // Model loading - Model model = LoadModel("resources/plane.obj"); // Load OBJ model - model.material.maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png"); // Set map diffuse texture + Model model = LoadModel("resources/plane.obj"); // Load OBJ model + model.materials[0].maps[MAP_DIFFUSE].texture = LoadTexture("resources/plane_diffuse.png"); // Set map diffuse texture - GenTextureMipmaps(&model.material.maps[MAP_DIFFUSE].texture); + GenTextureMipmaps(&model.materials[0].maps[MAP_DIFFUSE].texture); Camera camera = { 0 }; camera.position = (Vector3){ 0.0f, 60.0f, -120.0f };// Camera position perspective diff --git a/examples/src/physac/physics_demo.c b/examples/src/physac/physics_demo.c index 1b54d51..a92bb9e 100644 --- a/examples/src/physac/physics_demo.c +++ b/examples/src/physac/physics_demo.c @@ -7,16 +7,18 @@ * * Use the following line to compile: * -* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread -* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition +* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / +* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm / +* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition * -* Copyright (c) 2017 Victor Fisac +* Copyright (c) 2016-2018 Victor Fisac * ********************************************************************************************/ #include "raylib.h" #define PHYSAC_IMPLEMENTATION +#define PHYSAC_NO_THREADS #include "physac.h" int main() @@ -32,6 +34,7 @@ int main() // Physac logo drawing position int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoY = 15; + bool needsReset = false; // Initialize physics and default physics bodies InitPhysics(); @@ -52,15 +55,25 @@ int main() { // Update //---------------------------------------------------------------------------------- - if (IsKeyPressed('R')) // Reset physics input - { - ResetPhysics(); + // Delay initialization of variables due to physics reset async + RunPhysicsStep(); + if (needsReset) + { floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2, screenHeight }, 500, 100, 10); floor->enabled = false; circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2, screenHeight/2 }, 45, 10); circle->enabled = false; + + needsReset = false; + } + + // Reset physics input + if (IsKeyPressed('R')) + { + ResetPhysics(); + needsReset = true; } // Physics body creation inputs @@ -127,4 +140,3 @@ int main() return 0; } - diff --git a/examples/src/physac/physics_friction.c b/examples/src/physac/physics_friction.c index 9472729..337a126 100644 --- a/examples/src/physac/physics_friction.c +++ b/examples/src/physac/physics_friction.c @@ -7,16 +7,18 @@ * * Use the following line to compile: * -* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread -* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition +* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / +* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm / +* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition * -* Copyright (c) 2017 Victor Fisac +* Copyright (c) 2016-2018 Victor Fisac * ********************************************************************************************/ #include "raylib.h" #define PHYSAC_IMPLEMENTATION +#define PHYSAC_NO_THREADS #include "physac.h" int main() @@ -71,6 +73,8 @@ int main() { // Update //---------------------------------------------------------------------------------- + RunPhysicsStep(); + if (IsKeyPressed('R')) // Reset physics input { // Reset dynamic physics bodies position, velocity and rotation @@ -141,4 +145,3 @@ int main() return 0; } - diff --git a/examples/src/physac/physics_movement.c b/examples/src/physac/physics_movement.c index 4b2c9ab..e799eaa 100644 --- a/examples/src/physac/physics_movement.c +++ b/examples/src/physac/physics_movement.c @@ -7,16 +7,18 @@ * * Use the following line to compile: * -* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread -* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition +* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / +* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm / +* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition * -* Copyright (c) 2017 Victor Fisac +* Copyright (c) 2016-2018 Victor Fisac * ********************************************************************************************/ #include "raylib.h" #define PHYSAC_IMPLEMENTATION +#define PHYSAC_NO_THREADS #include "physac.h" #define VELOCITY 0.5f @@ -64,6 +66,8 @@ int main() { // Update //---------------------------------------------------------------------------------- + RunPhysicsStep(); + if (IsKeyPressed('R')) // Reset physics input { // Reset movement physics body position, velocity and rotation @@ -127,4 +131,3 @@ int main() return 0; } - diff --git a/examples/src/physac/physics_restitution.c b/examples/src/physac/physics_restitution.c index 2be8f42..3231d0c 100644 --- a/examples/src/physac/physics_restitution.c +++ b/examples/src/physac/physics_restitution.c @@ -7,16 +7,18 @@ * * Use the following line to compile: * -* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread -* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition +* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / +* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm / +* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition * -* Copyright (c) 2017 Victor Fisac +* Copyright (c) 2016-2018 Victor Fisac * ********************************************************************************************/ #include "raylib.h" #define PHYSAC_IMPLEMENTATION +#define PHYSAC_NO_THREADS #include "physac.h" int main() @@ -50,6 +52,9 @@ int main() circleC->restitution = 1; SetTargetFPS(60); + + // Restitution demo needs a very tiny physics time step for a proper simulation + SetPhysicsTimeStep(1.0/60.0/100 * 1000); //-------------------------------------------------------------------------------------- // Main game loop @@ -57,6 +62,8 @@ int main() { // Update //---------------------------------------------------------------------------------- + RunPhysicsStep(); + if (IsKeyPressed('R')) // Reset physics input { // Reset circles physics bodies position and velocity @@ -120,4 +127,3 @@ int main() return 0; } - diff --git a/examples/src/physac/physics_shatter.c b/examples/src/physac/physics_shatter.c index 6b474cd..7478522 100644 --- a/examples/src/physac/physics_shatter.c +++ b/examples/src/physac/physics_shatter.c @@ -7,17 +7,19 @@ * * Use the following line to compile: * -* gcc -o $(NAME_PART).exe $(FILE_NAME) -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread -* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition +* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / +* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm / +* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition * -* Copyright (c) 2017 Victor Fisac +* Copyright (c) 2016-2018 Victor Fisac * ********************************************************************************************/ #include "raylib.h" #define PHYSAC_IMPLEMENTATION -#include "physac.h" +#define PHYSAC_NO_THREADS +#include "physac.h" int main() { @@ -32,14 +34,15 @@ int main() // Physac logo drawing position int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoY = 15; + bool needsReset = false; // Initialize physics and default physics bodies InitPhysics(); SetPhysicsGravity(0, 0); // Create random polygon physics body to shatter - PhysicsBody body = CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10); - + CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -47,13 +50,21 @@ int main() while (!WindowShouldClose()) // Detect window close button or ESC key { // Update + RunPhysicsStep(); + //---------------------------------------------------------------------------------- + // Delay initialization of variables due to physics reset asynchronous + if (needsReset) + { + // Create random polygon physics body to shatter + CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10); + needsReset = false; + } + if (IsKeyPressed('R')) // Reset physics input { ResetPhysics(); - - // Create random polygon physics body to shatter - body = CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10); + needsReset = true; } if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) // Physics shatter input @@ -112,4 +123,3 @@ int main() return 0; } - diff --git a/examples/src/shaders/shaders_custom_uniform.c b/examples/src/shaders/shaders_custom_uniform.c index a0f6fd2..74b9e77 100644 --- a/examples/src/shaders/shaders_custom_uniform.c +++ b/examples/src/shaders/shaders_custom_uniform.c @@ -18,6 +18,12 @@ #include "raylib.h" +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + int main() { // Initialization @@ -30,16 +36,22 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [shaders] example - custom uniform variable"); // Define the camera to look into our 3d world - Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; - - Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) - dwarf.material.maps[MAP_DIFFUSE].texture = texture; // Set dwarf model diffuse texture - - Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + Camera camera = { 0 }; + camera.position = (Vector3){ 8.0f, 8.0f, 8.0f }; + camera.target = (Vector3){ 0.0f, 1.5f, 0.0f }; + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; + camera.fovy = 45.0f; + camera.type = CAMERA_PERSPECTIVE; + + Model model = LoadModel("resources/models/barracks.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/barracks_diffuse.png"); // Load model texture (diffuse map) + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture + + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - Shader shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/swirl.fs"); // Load postpro shader + // Load postprocessing shader + // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/swirl.fs", GLSL_VERSION)); // Get variable (uniform) location on the shader to connect with the program // NOTE: If uniform variable could not be found in the shader, function returns -1 @@ -67,7 +79,7 @@ int main() swirlCenter[1] = screenHeight - mousePosition.y; // Send new value to the shader to be used on drawing - SetShaderValue(shader, swirlCenterLoc, swirlCenter, 2); + SetShaderValue(shader, swirlCenterLoc, swirlCenter, UNIFORM_VEC2); UpdateCamera(&camera); // Update camera //---------------------------------------------------------------------------------- @@ -78,19 +90,21 @@ int main() ClearBackground(RAYWHITE); - BeginTextureMode(target); // Enable drawing to texture + BeginTextureMode(target); // Enable drawing to texture + + ClearBackground(RAYWHITE); // Clear texture background - Begin3dMode(camera); + BeginMode3D(camera); // Begin 3d mode drawing - DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture + DrawModel(model, position, 0.5f, WHITE); // Draw 3d model with texture DrawGrid(10, 1.0f); // Draw a grid - End3dMode(); + EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED); - EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) + EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) BeginShaderMode(shader); @@ -99,8 +113,9 @@ int main() EndShaderMode(); - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); - + // Draw some 2d text over drawn texture + DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY); + DrawFPS(10, 10); EndDrawing(); @@ -111,7 +126,7 @@ int main() //-------------------------------------------------------------------------------------- UnloadShader(shader); // Unload shader UnloadTexture(texture); // Unload texture - UnloadModel(dwarf); // Unload model + UnloadModel(model); // Unload model UnloadRenderTexture(target); // Unload render texture CloseWindow(); // Close window and OpenGL context diff --git a/examples/src/shaders/shaders_julia_set.c b/examples/src/shaders/shaders_julia_set.c new file mode 100644 index 0000000..c4dac6d --- /dev/null +++ b/examples/src/shaders/shaders_julia_set.c @@ -0,0 +1,179 @@ +/******************************************************************************************* +* +* raylib [shaders] example - julia sets +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. +* +* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3). +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by eggmund (@eggmund) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 eggmund (@eggmund) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "raymath.h" + +// A few good julia sets +const float POINTS_OF_INTEREST[6][2] = +{ + { -0.348827, 0.607167 }, + { -0.786268, 0.169728 }, + { -0.8, 0.156 }, + { 0.285, 0.0 }, + { -0.835, -0.2321 }, + { -0.70176, -0.3842 }, +}; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets"); + + // Load julia set shader + // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, "resources/shaders/glsl330/julia_shader.fs"); + + // c constant to use in z^2 + c + float c[2] = { POINTS_OF_INTEREST[0][0], POINTS_OF_INTEREST[0][1] }; + + // Offset and zoom to draw the julia set at. (centered on screen and 1.6 times smaller) + float offset[2] = { -(float)screenWidth/2, -(float)screenHeight/2 }; + float zoom = 1.6f; + + // Get variable (uniform) locations on the shader to connect with the program + // NOTE: If uniform variable could not be found in the shader, function returns -1 + int cLoc = GetShaderLocation(shader, "c"); + int zoomLoc = GetShaderLocation(shader, "zoom"); + int offsetLoc = GetShaderLocation(shader, "offset"); + + // Tell the shader what the screen dimensions, zoom, offset and c are + float screenDims[2] = { (float)screenWidth, (float)screenHeight }; + SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, UNIFORM_VEC2); + + SetShaderValue(shader, cLoc, c, UNIFORM_VEC2); + SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT); + SetShaderValue(shader, offsetLoc, offset, UNIFORM_VEC2); + + // Create a RenderTexture2D to be used for render to texture + RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); + + int incrementSpeed = 3; // Multiplier of speed to change c value + bool showControls = true; // Show controls + bool pause = false; // Pause animation + + SetTargetFPS(60); // Set the window to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + // Press [1 - 6] to reset c to a point of interest + if (IsKeyPressed(KEY_ONE) || + IsKeyPressed(KEY_TWO) || + IsKeyPressed(KEY_THREE) || + IsKeyPressed(KEY_FOUR) || + IsKeyPressed(KEY_FIVE) || + IsKeyPressed(KEY_SIX)) + { + if (IsKeyPressed(KEY_ONE)) c[0] = POINTS_OF_INTEREST[0][0], c[1] = POINTS_OF_INTEREST[0][1]; + else if (IsKeyPressed(KEY_TWO)) c[0] = POINTS_OF_INTEREST[1][0], c[1] = POINTS_OF_INTEREST[1][1]; + else if (IsKeyPressed(KEY_THREE)) c[0] = POINTS_OF_INTEREST[2][0], c[1] = POINTS_OF_INTEREST[2][1]; + else if (IsKeyPressed(KEY_FOUR)) c[0] = POINTS_OF_INTEREST[3][0], c[1] = POINTS_OF_INTEREST[3][1]; + else if (IsKeyPressed(KEY_FIVE)) c[0] = POINTS_OF_INTEREST[4][0], c[1] = POINTS_OF_INTEREST[4][1]; + else if (IsKeyPressed(KEY_SIX)) c[0] = POINTS_OF_INTEREST[5][0], c[1] = POINTS_OF_INTEREST[5][1]; + + SetShaderValue(shader, cLoc, c, UNIFORM_VEC2); + } + + if (IsKeyPressed(KEY_P)) pause = !pause; // Pause animation (c change) + if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls + + if (!pause) + { + if (IsKeyDown(KEY_RIGHT)) incrementSpeed++; + else if (IsKeyDown(KEY_LEFT)) incrementSpeed--; + + // Use mouse wheel to change zoom + zoom -= (float)GetMouseWheelMove()/10.f; + SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT); + + // Use mouse button to change offset + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + // TODO: Logic is not correct, the idea is getting zoom focus to pointed area + Vector2 mousePos = GetMousePosition(); + + offset[0] = mousePos.x -(float)screenWidth; + offset[1] = mousePos.y -(float)screenHeight; + + SetShaderValue(shader, offsetLoc, offset, UNIFORM_VEC2); + } + + // Increment c value with time + float amount = GetFrameTime()*incrementSpeed*0.0005f; + c[0] += amount; + c[1] += amount; + + SetShaderValue(shader, cLoc, c, UNIFORM_VEC2); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(BLACK); // Clear the screen of the previous frame. + + // Using a render texture to draw Julia set + BeginTextureMode(target); // Enable drawing to texture + ClearBackground(BLACK); // Clear the render texture + + // Draw a rectangle in shader mode + // NOTE: This acts as a canvas for the shader to draw on + BeginShaderMode(shader); + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK); + EndShaderMode(); + EndTextureMode(); + + // Draw the saved texture (rendered julia set) + DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, Vector2Zero(), WHITE); + + // Draw information + //DrawText( FormatText("cx: %f\ncy: %f\nspeed: %d", c[0], c[1], incrementSpeed), 10, 10, 10, RAYWHITE); + + if (showControls) + { + DrawText("Press keys [1 - 6] to change point of interest", 10, GetScreenHeight() - 60, 10, RAYWHITE); + DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, GetScreenHeight() - 45, 10, RAYWHITE); + DrawText("Press KEY_P to pause movement animation", 10, GetScreenHeight() - 30, 10, RAYWHITE); + DrawText("Press KEY_F1 to toggle these controls", 10, GetScreenHeight() - 15, 10, RAYWHITE); + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); // Unload shader + UnloadRenderTexture(target); // Unload render texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/shaders/shaders_model_shader.c b/examples/src/shaders/shaders_model_shader.c index b0ad1fd..2717c19 100644 --- a/examples/src/shaders/shaders_model_shader.c +++ b/examples/src/shaders/shaders_model_shader.c @@ -12,12 +12,18 @@ * 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-2017 Ramon Santamaria (@raysan5) +* Copyright (c) 2014 Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + int main() { // Initialization @@ -30,19 +36,26 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader"); // Define the camera to look into our 3d world - Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; - - Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture - Shader shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/grayscale.fs"); // Load model shader + Camera camera = { 0 }; + camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; + camera.target = (Vector3){ 0.0f, 1.0f, -1.0f }; + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; + camera.fovy = 45.0f; + camera.type = CAMERA_PERSPECTIVE; + + Model model = LoadModel("resources/models/watermill.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/watermill_diffuse.png"); // Load model texture + + // Load shader for model + // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION)); - dwarf.material.shader = shader; // Set shader effect to 3d model - dwarf.material.maps[MAP_DIFFUSE].texture = texture; // Bind texture to model + model.materials[0].shader = shader; // Set shader effect to 3d model + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode + SetCameraMode(camera, CAMERA_FREE); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -61,15 +74,15 @@ int main() ClearBackground(RAYWHITE); - Begin3dMode(camera); + BeginMode3D(camera); - DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture + DrawModel(model, position, 0.2f, WHITE); // Draw 3d model with texture DrawGrid(10, 1.0f); // Draw a grid - End3dMode(); + EndMode3D(); - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); + DrawText("(c) Watermill 3D model by Alberto Cano", screenWidth - 210, screenHeight - 20, 10, GRAY); DrawText(FormatText("Camera position: (%.2f, %.2f, %.2f)", camera.position.x, camera.position.y, camera.position.z), 600, 20, 10, BLACK); DrawText(FormatText("Camera target: (%.2f, %.2f, %.2f)", camera.target.x, camera.target.y, camera.target.z), 600, 40, 10, GRAY); @@ -84,7 +97,7 @@ int main() //-------------------------------------------------------------------------------------- UnloadShader(shader); // Unload shader UnloadTexture(texture); // Unload texture - UnloadModel(dwarf); // Unload model + UnloadModel(model); // Unload model CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/src/shaders/shaders_palette_switch.c b/examples/src/shaders/shaders_palette_switch.c new file mode 100644 index 0000000..197ae54 --- /dev/null +++ b/examples/src/shaders/shaders_palette_switch.c @@ -0,0 +1,147 @@ +/******************************************************************************************* +* +* raylib [shaders] example - Color palette switch +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. +* +* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example +* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders +* raylib comes with shaders ready for both versions, check raylib/shaders install folder +* +* This example has been created using raylib 2.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Marco Lizza (@MarcoLizza) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Marco Lizza (@MarcoLizza) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +#define MAX_PALETTES 3 +#define COLORS_PER_PALETTE 8 +#define VALUES_PER_COLOR 3 + +static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE*VALUES_PER_COLOR] = { + { // 3-BIT RGB + 0, 0, 0, + 255, 0, 0, + 0, 255, 0, + 0, 0, 255, + 0, 255, 255, + 255, 0, 255, + 255, 255, 0, + 255, 255, 255, + }, + { // AMMO-8 (GameBoy-like) + 4, 12, 6, + 17, 35, 24, + 30, 58, 41, + 48, 93, 66, + 77, 128, 97, + 137, 162, 87, + 190, 220, 127, + 238, 255, 204, + }, + { // RKBV (2-strip film) + 21, 25, 26, + 138, 76, 88, + 217, 98, 117, + 230, 184, 193, + 69, 107, 115, + 75, 151, 166, + 165, 189, 194, + 255, 245, 247, + } +}; + +static const char *paletteText[] = { + "3-BIT RGB", + "AMMO-8 (GameBoy-like)", + "RKBV (2-strip film)" +}; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - color palette switch"); + + // Load shader to be used on some parts drawing + // NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version + // NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/palette-switch.fs", GLSL_VERSION)); + + // Get variable (uniform) location on the shader to connect with the program + // NOTE: If uniform variable could not be found in the shader, function returns -1 + int paletteLoc = GetShaderLocation(shader, "palette"); + + int currentPalette = 0; + int lineHeight = screenHeight/COLORS_PER_PALETTE; + + 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_RIGHT)) currentPalette++; + else if (IsKeyPressed(KEY_LEFT)) currentPalette--; + + if (currentPalette >= MAX_PALETTES) currentPalette = 0; + else if (currentPalette < 0) currentPalette = MAX_PALETTES - 1; + + // Send new value to the shader to be used on drawing. + // NOTE: We are sending RGB triplets w/o the alpha channel + SetShaderValueV(shader, paletteLoc, palettes[currentPalette], UNIFORM_IVEC3, COLORS_PER_PALETTE); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginShaderMode(shader); + + for (int i = 0; i < COLORS_PER_PALETTE; i++) + { + // Draw horizontal screen-wide rectangles with increasing "palette index" + // The used palette index is encoded in the RGB components of the pixel + DrawRectangle(0, lineHeight*i, GetScreenWidth(), lineHeight, (Color){ i, i, i, 255 }); + } + + EndShaderMode(); + + DrawText("< >", 10, 10, 30, DARKBLUE); + DrawText("CURRENT PALETTE:", 60, 15, 20, RAYWHITE); + DrawText(paletteText[currentPalette], 300, 15, 20, RED); + + DrawFPS(700, 15); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); // Unload shader + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/shaders/shaders_postprocessing.c b/examples/src/shaders/shaders_postprocessing.c index 4aac5f9..7c14641 100644 --- a/examples/src/shaders/shaders_postprocessing.c +++ b/examples/src/shaders/shaders_postprocessing.c @@ -20,10 +20,8 @@ #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 - #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl330/base.vs" #else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB #define GLSL_VERSION 100 - #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl100/base.vs" #endif #define MAX_POSTPRO_SHADERS 12 @@ -72,31 +70,32 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader"); // Define the camera to look into our 3d world - Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + Camera camera = {{ 2.0f, 3.0f, 2.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; - Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) - dwarf.material.maps[MAP_DIFFUSE].texture = texture; // Set dwarf model diffuse texture + Model model = LoadModel("resources/models/church.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/models/church_diffuse.png"); // Load model texture (diffuse map) + model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set model diffuse texture - Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position // Load all postpro shaders // NOTE 1: All postpro shader use the base vertex shader (DEFAULT_VERTEX_SHADER) // NOTE 2: We load the correct shader depending on GLSL version Shader shaders[MAX_POSTPRO_SHADERS]; - shaders[FX_GRAYSCALE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION)); - shaders[FX_POSTERIZATION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION)); - shaders[FX_DREAM_VISION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION)); - shaders[FX_PIXELIZER] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION)); - shaders[FX_CROSS_HATCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION)); - shaders[FX_CROSS_STITCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION)); - shaders[FX_PREDATOR_VIEW] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION)); - shaders[FX_SCANLINES] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION)); - shaders[FX_FISHEYE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION)); - shaders[FX_SOBEL] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION)); - shaders[FX_BLOOM] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION)); - shaders[FX_BLUR] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION)); + // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + shaders[FX_GRAYSCALE] = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION)); + shaders[FX_POSTERIZATION] = LoadShader(0, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION)); + shaders[FX_DREAM_VISION] = LoadShader(0, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION)); + shaders[FX_PIXELIZER] = LoadShader(0, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION)); + shaders[FX_CROSS_HATCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION)); + shaders[FX_CROSS_STITCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION)); + shaders[FX_PREDATOR_VIEW] = LoadShader(0, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION)); + shaders[FX_SCANLINES] = LoadShader(0, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION)); + shaders[FX_FISHEYE] = LoadShader(0, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION)); + shaders[FX_SOBEL] = LoadShader(0, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION)); + shaders[FX_BLOOM] = LoadShader(0, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION)); + shaders[FX_BLUR] = LoadShader(0, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION)); int currentShader = FX_GRAYSCALE; @@ -129,17 +128,19 @@ int main() ClearBackground(RAYWHITE); - BeginTextureMode(target); // Enable drawing to texture + BeginTextureMode(target); // Enable drawing to texture - Begin3dMode(camera); + ClearBackground(RAYWHITE); // Clear texture background - DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture + BeginMode3D(camera); // Begin 3d mode drawing + + DrawModel(model, position, 0.1f, WHITE); // Draw 3d model with texture DrawGrid(10, 1.0f); // Draw a grid - End3dMode(); + EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode - EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) + EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) // Render previously generated texture using selected postpro shader BeginShaderMode(shaders[currentShader]); @@ -149,9 +150,10 @@ int main() EndShaderMode(); + // Draw 2d shapes and text over drawn texture DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f)); - DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY); + DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK); DrawText(postproShaderText[currentShader], 330, 15, 20, RED); @@ -170,11 +172,11 @@ int main() for (int i = 0; i < MAX_POSTPRO_SHADERS; i++) UnloadShader(shaders[i]); UnloadTexture(texture); // Unload texture - UnloadModel(dwarf); // Unload model + UnloadModel(model); // Unload model UnloadRenderTexture(target); // Unload render texture CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -}
\ No newline at end of file +} diff --git a/examples/src/shaders/shaders_raymarching.c b/examples/src/shaders/shaders_raymarching.c new file mode 100644 index 0000000..f68222b --- /dev/null +++ b/examples/src/shaders/shaders_raymarching.c @@ -0,0 +1,112 @@ +/******************************************************************************************* +* +* raylib [shaders] example - Raymarching shapes generation +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. +* +* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example +* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders +* raylib comes with shaders ready for both versions, check raylib/shaders install folder +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2018 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes"); + + Camera camera = { 0 }; + camera.position = (Vector3){ 2.5f, 2.5f, 3.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.0f, 0.7f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 65.0f; // Camera field-of-view Y + + SetCameraMode(camera, CAMERA_FREE); // Set camera mode + + // Load raymarching shader + // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/raymarching.fs", GLSL_VERSION)); + + // Get shader locations for required uniforms + int viewEyeLoc = GetShaderLocation(shader, "viewEye"); + int viewCenterLoc = GetShaderLocation(shader, "viewCenter"); + int viewUpLoc = GetShaderLocation(shader, "viewUp"); + int deltaTimeLoc = GetShaderLocation(shader, "deltaTime"); + int runTimeLoc = GetShaderLocation(shader, "runTime"); + int resolutionLoc = GetShaderLocation(shader, "resolution"); + + float resolution[2] = { screenWidth, screenHeight }; + SetShaderValue(shader, resolutionLoc, resolution, UNIFORM_VEC2); + + float runTime = 0.0f; + + 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 camera + + float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; + float cameraTarget[3] = { camera.target.x, camera.target.y, camera.target.z }; + float cameraUp[3] = { camera.up.x, camera.up.y, camera.up.z }; + + float deltaTime = GetFrameTime(); + runTime += deltaTime; + + // Set shader required uniform values + SetShaderValue(shader, viewEyeLoc, cameraPos, UNIFORM_VEC3); + SetShaderValue(shader, viewCenterLoc, cameraTarget, UNIFORM_VEC3); + SetShaderValue(shader, viewUpLoc, cameraUp, UNIFORM_VEC3); + SetShaderValue(shader, deltaTimeLoc, &deltaTime, UNIFORM_FLOAT); + SetShaderValue(shader, runTimeLoc, &runTime, UNIFORM_FLOAT); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // We only draw a white full-screen rectangle, + // frame is generated in shader using raymarching + BeginShaderMode(shader); + DrawRectangle(0, 0, screenWidth, screenHeight, WHITE); + EndShaderMode(); + + DrawText("(c) Raymarching shader by Iñigo Quilez. MIT License.", screenWidth - 280, screenHeight - 20, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); // Unload shader + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shaders/shaders_shapes_textures.c b/examples/src/shaders/shaders_shapes_textures.c index e8c36a1..5ee5d56 100644 --- a/examples/src/shaders/shaders_shapes_textures.c +++ b/examples/src/shaders/shaders_shapes_textures.c @@ -18,6 +18,12 @@ #include "raylib.h" +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + int main() { // Initialization @@ -29,9 +35,10 @@ int main() Texture2D fudesumi = LoadTexture("resources/fudesumi.png"); - // NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version - Shader shader = LoadShader("resources/shaders/glsl330/base.vs", - "resources/shaders/glsl330/grayscale.fs"); + // Load shader to be used on some parts drawing + // NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version + // NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION)); SetTargetFPS(60); //-------------------------------------------------------------------------------------- diff --git a/examples/src/shaders/shaders_texture_drawing.c b/examples/src/shaders/shaders_texture_drawing.c new file mode 100644 index 0000000..3a54009 --- /dev/null +++ b/examples/src/shaders/shaders_texture_drawing.c @@ -0,0 +1,79 @@ +/******************************************************************************************* +* +* raylib [textures] example - Texture drawing +* +* This example illustrates how to draw on a blank texture using a shader +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Michał Ciesielski and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Michał Ciesielski and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture drawing"); + + Image imBlank = GenImageColor(1024, 1024, BLANK); + Texture2D texture = LoadTextureFromImage(imBlank); // Load blank texture to fill on shader + UnloadImage(imBlank); + + // NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version + Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/cubes_panning.fs", GLSL_VERSION)); + + float time = 0.0f; + int timeLoc = GetShaderLocation(shader, "uTime"); + SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + time = GetTime(); + SetShaderValue(shader, timeLoc, &time, UNIFORM_FLOAT); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginShaderMode(shader); // Enable our custom shader for next shapes/textures drawings + DrawTexture(texture, 0, 0, WHITE); // Drawing BLANK texture, all magic happens on shader + EndShaderMode(); // Disable our custom shader, return to default shader + + DrawText("BACKGROUND is PAINTED and ANIMATED on SHADER!", 10, 10, 20, MAROON); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/shaders/shaders_texture_waves.c b/examples/src/shaders/shaders_texture_waves.c new file mode 100644 index 0000000..bc677c7 --- /dev/null +++ b/examples/src/shaders/shaders_texture_waves.c @@ -0,0 +1,115 @@ +/******************************************************************************************* +* +* raylib [shaders] example - Texture Waves +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. +* +* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example +* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders +* raylib comes with shaders ready for both versions, check raylib/shaders install folder +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Anata (@anatagawa) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Anata (@anatagawa) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +// ------------------------------------------------------------------------------------------------------------- +// Main Entry point +// ------------------------------------------------------------------------------------------------------------- +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture waves"); + + // Load space texture to apply shaders + Texture2D space = LoadTexture("resources/space.png"); + + // Load shader and setup location points and values + Shader wave = LoadShader(0, FormatText("resources/shaders/glsl%i/wave.fs", GLSL_VERSION)); + + float screenSizeLoc = GetShaderLocation(wave, "size"); + float secondsLoc = GetShaderLocation(wave, "secondes"); + float freqXLoc = GetShaderLocation(wave, "freqX"); + float freqYLoc = GetShaderLocation(wave, "freqY"); + float ampXLoc = GetShaderLocation(wave, "ampX"); + float ampYLoc = GetShaderLocation(wave, "ampY"); + float speedXLoc = GetShaderLocation(wave, "speedX"); + float speedYLoc = GetShaderLocation(wave, "speedY"); + + float screenSize[2] = { 800, 450 }; + + // Shader uniform values that can be updated at any time + float freqX = 25.0f; + float freqY = 25.0f; + float ampX = 5.0f; + float ampY = 5.0f; + float speedX = 8.0f; + float speedY = 8.0f; + + SetShaderValue(wave, screenSizeLoc, &screenSize, UNIFORM_VEC2); + SetShaderValue(wave, freqXLoc, &freqX, UNIFORM_FLOAT); + SetShaderValue(wave, freqYLoc, &freqY, UNIFORM_FLOAT); + SetShaderValue(wave, ampXLoc, &X, UNIFORM_FLOAT); + SetShaderValue(wave, ampYLoc, &Y, UNIFORM_FLOAT); + SetShaderValue(wave, speedXLoc, &speedX, UNIFORM_FLOAT); + SetShaderValue(wave, speedYLoc, &speedY, UNIFORM_FLOAT); + + float seconds = 0.0f; + + SetTargetFPS(60); + // ------------------------------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + seconds += GetFrameTime(); + + SetShaderValue(wave, secondsLoc, &seconds, UNIFORM_FLOAT); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginShaderMode(wave); + + DrawTexture(space, 0, 0, WHITE); + DrawTexture(space, space.width, 0, WHITE); + + EndShaderMode(); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(wave); // Unload shader + UnloadTexture(space); // Unload texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/shapes/shapes_basic_shapes.c b/examples/src/shapes/shapes_basic_shapes.c index 4b7cc26..67eea9d 100644 --- a/examples/src/shapes/shapes_basic_shapes.c +++ b/examples/src/shapes/shapes_basic_shapes.c @@ -39,26 +39,27 @@ int main() DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY); - DrawLine(18, 42, screenWidth - 18, 42, BLACK); - DrawCircle(screenWidth/4, 120, 35, DARKBLUE); - DrawCircleGradient(screenWidth/4, 220, 60, GREEN, SKYBLUE); - DrawCircleLines(screenWidth/4, 340, 80, DARKBLUE); DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED); + DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD); - DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); DrawTriangle((Vector2){screenWidth/4*3, 80}, (Vector2){screenWidth/4*3 - 60, 150}, (Vector2){screenWidth/4*3 + 60, 150}, VIOLET); + DrawPoly((Vector2){screenWidth/4*3, 320}, 6, 80, 0, BROWN); + + DrawCircleGradient(screenWidth/4, 220, 60, GREEN, SKYBLUE); + + // NOTE: We draw all LINES based shapes together to optimize internal drawing, + // this way, all LINES are rendered in a single draw pass + DrawLine(18, 42, screenWidth - 18, 42, BLACK); + DrawCircleLines(screenWidth/4, 340, 80, DARKBLUE); DrawTriangleLines((Vector2){screenWidth/4*3, 160}, (Vector2){screenWidth/4*3 - 20, 230}, (Vector2){screenWidth/4*3 + 20, 230}, DARKBLUE); - - DrawPoly((Vector2){screenWidth/4*3, 320}, 6, 80, 0, BROWN); - EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/examples/src/shapes/shapes_bouncing_ball.c b/examples/src/shapes/shapes_bouncing_ball.c new file mode 100644 index 0000000..6b27c9d --- /dev/null +++ b/examples/src/shapes/shapes_bouncing_ball.c @@ -0,0 +1,76 @@ +/******************************************************************************************* +* +* raylib [shapes] example - bouncing ball +* +* 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) 2013 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //--------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - bouncing ball"); + + Vector2 ballPosition = { GetScreenWidth()/2, GetScreenHeight()/2 }; + Vector2 ballSpeed = { 5.0f, 4.0f }; + int ballRadius = 20; + + bool pause = 0; + int framesCounter = 0; + + SetTargetFPS(60); + //---------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //----------------------------------------------------- + if (IsKeyPressed(KEY_SPACE)) pause = !pause; + + if (!pause) + { + ballPosition.x += ballSpeed.x; + ballPosition.y += ballSpeed.y; + + // Check walls collision for bouncing + if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f; + if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -1.0f; + } + else framesCounter++; + //----------------------------------------------------- + + // Draw + //----------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawCircleV(ballPosition, ballRadius, MAROON); + DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, LIGHTGRAY); + + // On pause, we draw a blinking message + if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //----------------------------------------------------- + } + + // De-Initialization + //--------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //---------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_collision_area.c b/examples/src/shapes/shapes_collision_area.c new file mode 100644 index 0000000..e61623a --- /dev/null +++ b/examples/src/shapes/shapes_collision_area.c @@ -0,0 +1,108 @@ +/******************************************************************************************* +* +* raylib [shapes] example - collision area +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include <stdlib.h> // Required for abs() + +int main() +{ + // Initialization + //--------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision area"); + + // Box A: Moving box + Rectangle boxA = { 10, GetScreenHeight()/2 - 50, 200, 100 }; + int boxASpeedX = 4; + + // Box B: Mouse moved box + Rectangle boxB = { GetScreenWidth()/2 - 30, GetScreenHeight()/2 - 30, 60, 60 }; + + Rectangle boxCollision = { 0 }; // Collision rectangle + + int screenUpperLimit = 40; // Top menu limits + + bool pause = false; // Movement pause + bool collision = false; // Collision detection + + SetTargetFPS(60); + //---------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //----------------------------------------------------- + // Move box if not paused + if (!pause) boxA.x += boxASpeedX; + + // Bounce box on x screen limits + if (((boxA.x + boxA.width) >= GetScreenWidth()) || (boxA.x <= 0)) boxASpeedX *= -1; + + // Update player-controlled-box (box02) + boxB.x = GetMouseX() - boxB.width/2; + boxB.y = GetMouseY() - boxB.height/2; + + // Make sure Box B does not go out of move area limits + if ((boxB.x + boxB.width) >= GetScreenWidth()) boxB.x = GetScreenWidth() - boxB.width; + else if (boxB.x <= 0) boxB.x = 0; + + if ((boxB.y + boxB.height) >= GetScreenHeight()) boxB.y = GetScreenHeight() - boxB.height; + else if (boxB.y <= screenUpperLimit) boxB.y = screenUpperLimit; + + // Check boxes collision + collision = CheckCollisionRecs(boxA, boxB); + + // Get collision rectangle (only on collision) + if (collision) boxCollision = GetCollisionRec(boxA, boxB); + + // Pause Box A movement + if (IsKeyPressed(KEY_SPACE)) pause = !pause; + //----------------------------------------------------- + + // Draw + //----------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawRectangle(0, 0, screenWidth, screenUpperLimit, collision? RED : BLACK); + + DrawRectangleRec(boxA, GOLD); + DrawRectangleRec(boxB, BLUE); + + if (collision) + { + // Draw collision area + DrawRectangleRec(boxCollision, LIME); + + // Draw collision message + DrawText("COLLISION!", GetScreenWidth()/2 - MeasureText("COLLISION!", 20)/2, screenUpperLimit/2 - 10, 20, BLACK); + + // Draw collision area + DrawText(FormatText("Collision Area: %i", (int)boxCollision.width*(int)boxCollision.height), GetScreenWidth()/2 - 100, screenUpperLimit + 10, 20, BLACK); + } + + DrawFPS(10, 10); + + EndDrawing(); + //----------------------------------------------------- + } + + // De-Initialization + //--------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //---------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_colors_palette.c b/examples/src/shapes/shapes_colors_palette.c index dcab862..d6ac30a 100644 --- a/examples/src/shapes/shapes_colors_palette.c +++ b/examples/src/shapes/shapes_colors_palette.c @@ -1,26 +1,53 @@ /******************************************************************************************* * -* raylib [shapes] example - Draw raylib custom color palette +* raylib [shapes] example - Colors palette * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 2.5 (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) 2014-2019 Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" +#define MAX_COLORS_COUNT 21 // Number of colors available + int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - colors palette"); + + Color colors[MAX_COLORS_COUNT] = { + DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN, + GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW, + GREEN, SKYBLUE, PURPLE, BEIGE }; + + const char *colorNames[MAX_COLORS_COUNT] = { + "DARKGRAY", "MAROON", "ORANGE", "DARKGREEN", "DARKBLUE", "DARKPURPLE", + "DARKBROWN", "GRAY", "RED", "GOLD", "LIME", "BLUE", "VIOLET", "BROWN", + "LIGHTGRAY", "PINK", "YELLOW", "GREEN", "SKYBLUE", "PURPLE", "BEIGE" }; + + Rectangle colorsRecs[MAX_COLORS_COUNT] = { 0 }; // Rectangles array + + // Fills colorsRecs data (for every rectangle) + for (int i = 0; i < MAX_COLORS_COUNT; i++) + { + colorsRecs[i].x = 20 + 100*(i%7) + 10*(i%7); + colorsRecs[i].y = 80 + 100*(i/7) + 10*(i/7); + colorsRecs[i].width = 100; + colorsRecs[i].height = 100; + } + + int colorState[MAX_COLORS_COUNT] = { 0 }; // Color state: 0-DEFAULT, 1-MOUSE_HOVER - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib color palette"); - - SetTargetFPS(60); + Vector2 mousePoint; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -28,7 +55,13 @@ int main() { // Update //---------------------------------------------------------------------------------- - // TODO: Update your variables here + mousePoint = GetMousePosition(); + + for (int i = 0; i < MAX_COLORS_COUNT; i++) + { + if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) colorState[i] = 1; + else colorState[i] = 0; + } //---------------------------------------------------------------------------------- // Draw @@ -36,53 +69,22 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + DrawText("raylib colors palette", 28, 42, 20, BLACK); + DrawText("press SPACE to see all colors", GetScreenWidth() - 180, GetScreenHeight() - 40, 10, GRAY); - DrawText("raylib color palette", 28, 42, 20, BLACK); - - DrawRectangle(26, 80, 100, 100, DARKGRAY); - DrawRectangle(26, 188, 100, 100, GRAY); - DrawRectangle(26, 296, 100, 100, LIGHTGRAY); - DrawRectangle(134, 80, 100, 100, MAROON); - DrawRectangle(134, 188, 100, 100, RED); - DrawRectangle(134, 296, 100, 100, PINK); - DrawRectangle(242, 80, 100, 100, ORANGE); - DrawRectangle(242, 188, 100, 100, GOLD); - DrawRectangle(242, 296, 100, 100, YELLOW); - DrawRectangle(350, 80, 100, 100, DARKGREEN); - DrawRectangle(350, 188, 100, 100, LIME); - DrawRectangle(350, 296, 100, 100, GREEN); - DrawRectangle(458, 80, 100, 100, DARKBLUE); - DrawRectangle(458, 188, 100, 100, BLUE); - DrawRectangle(458, 296, 100, 100, SKYBLUE); - DrawRectangle(566, 80, 100, 100, DARKPURPLE); - DrawRectangle(566, 188, 100, 100, VIOLET); - DrawRectangle(566, 296, 100, 100, PURPLE); - DrawRectangle(674, 80, 100, 100, DARKBROWN); - DrawRectangle(674, 188, 100, 100, BROWN); - DrawRectangle(674, 296, 100, 100, BEIGE); - - - DrawText("DARKGRAY", 65, 166, 10, BLACK); - DrawText("GRAY", 93, 274, 10, BLACK); - DrawText("LIGHTGRAY", 61, 382, 10, BLACK); - DrawText("MAROON", 186, 166, 10, BLACK); - DrawText("RED", 208, 274, 10, BLACK); - DrawText("PINK", 204, 382, 10, BLACK); - DrawText("ORANGE", 295, 166, 10, BLACK); - DrawText("GOLD", 310, 274, 10, BLACK); - DrawText("YELLOW", 300, 382, 10, BLACK); - DrawText("DARKGREEN", 382, 166, 10, BLACK); - DrawText("LIME", 420, 274, 10, BLACK); - DrawText("GREEN", 410, 382, 10, BLACK); - DrawText("DARKBLUE", 498, 166, 10, BLACK); - DrawText("BLUE", 526, 274, 10, BLACK); - DrawText("SKYBLUE", 505, 382, 10, BLACK); - DrawText("DARKPURPLE", 592, 166, 10, BLACK); - DrawText("VIOLET", 621, 274, 10, BLACK); - DrawText("PURPLE", 620, 382, 10, BLACK); - DrawText("DARKBROWN", 705, 166, 10, BLACK); - DrawText("BROWN", 733, 274, 10, BLACK); - DrawText("BEIGE", 737, 382, 10, BLACK); + for (int i = 0; i < MAX_COLORS_COUNT; i++) // Draw all rectangles + { + DrawRectangleRec(colorsRecs[i], Fade(colors[i], colorState[i]? 0.6f : 1.0f)); + + if (IsKeyDown(KEY_SPACE) || colorState[i]) + { + DrawRectangle(colorsRecs[i].x, colorsRecs[i].y + colorsRecs[i].height - 26, colorsRecs[i].width, 20, BLACK); + DrawRectangleLinesEx(colorsRecs[i], 6, Fade(BLACK, 0.3f)); + DrawText(colorNames[i], colorsRecs[i].x + colorsRecs[i].width - MeasureText(colorNames[i], 10) - 12, + colorsRecs[i].y + colorsRecs[i].height - 20, 10, colors[i]); + } + } EndDrawing(); //---------------------------------------------------------------------------------- @@ -90,7 +92,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/src/shapes/shapes_draw_circle_sector.c b/examples/src/shapes/shapes_draw_circle_sector.c new file mode 100644 index 0000000..597b85a --- /dev/null +++ b/examples/src/shapes/shapes_draw_circle_sector.c @@ -0,0 +1,81 @@ +/******************************************************************************************* +* +* raylib [shapes] example - draw circle sector (with gui options) +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include <raylib.h> + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw circle sector"); + + Vector2 center = {(GetScreenWidth() - 300)/2, GetScreenHeight()/2 }; + + float outerRadius = 180.f; + int startAngle = 0; + int endAngle = 180; + int segments = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // NOTE: All variables update happens inside GUI control functions + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f)); + DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); + + DrawCircleSector(center, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.3)); + DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.6)); + + // Draw GUI controls + //------------------------------------------------------------------------------ + startAngle = GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", startAngle, 0, 720, true ); + endAngle = GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", endAngle, 0, 720, true); + + outerRadius = GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", outerRadius, 0, 200, true); + segments = GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", segments, 0, 100, true); + //------------------------------------------------------------------------------ + + DrawText(FormatText("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 600, 200, 10, (segments >= 4)? MAROON : DARKGRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_draw_rectangle_rounded.c b/examples/src/shapes/shapes_draw_rectangle_rounded.c new file mode 100644 index 0000000..e36e273 --- /dev/null +++ b/examples/src/shapes/shapes_draw_rectangle_rounded.c @@ -0,0 +1,89 @@ +/******************************************************************************************* +* +* raylib [shapes] example - draw rectangle rounded (with gui options) +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include <raylib.h> + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw rectangle rounded"); + + float roundness = 0.2f; + int width = 200; + int height = 100; + int segments = 0; + int lineThick = 1; + + bool drawRect = false; + bool drawRoundedRect = true; + bool drawRoundedLines = false; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + Rectangle rec = { (GetScreenWidth() - width - 250)/2, (GetScreenHeight() - height)/2, width, height }; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawLine(560, 0, 560, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f)); + DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); + + if (drawRect) DrawRectangleRec(rec, Fade(GOLD, 0.6)); + if (drawRoundedRect) DrawRectangleRounded(rec, roundness, segments, Fade(MAROON, 0.2)); + if (drawRoundedLines) DrawRectangleRoundedLines(rec,roundness, segments, lineThick, Fade(MAROON, 0.4)); + + // Draw GUI controls + //------------------------------------------------------------------------------ + width = GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", width, 0, GetScreenWidth() - 300, true ); + height = GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", height, 0, GetScreenHeight() - 50, true); + roundness = GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", roundness, 0.0f, 1.0f, true); + lineThick = GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", lineThick, 0, 20, true); + segments = GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", segments, 0, 60, true); + + drawRoundedRect = GuiCheckBox((Rectangle){ 640, 320, 20, 20 }, "DrawRoundedRect", drawRoundedRect); + drawRoundedLines = GuiCheckBox((Rectangle){ 640, 350, 20, 20 }, "DrawRoundedLines", drawRoundedLines); + drawRect = GuiCheckBox((Rectangle){ 640, 380, 20, 20}, "DrawRect", drawRect); + //------------------------------------------------------------------------------ + + DrawText(FormatText("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 640, 280, 10, (segments >= 4)? MAROON : DARKGRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/shapes/shapes_draw_ring.c b/examples/src/shapes/shapes_draw_ring.c new file mode 100644 index 0000000..44a3ec5 --- /dev/null +++ b/examples/src/shapes/shapes_draw_ring.c @@ -0,0 +1,94 @@ +/******************************************************************************************* +* +* raylib [shapes] example - draw ring (with gui options) +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include <raylib.h> + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw ring"); + + Vector2 center = {(GetScreenWidth() - 300)/2, GetScreenHeight()/2 }; + + float innerRadius = 80.0f; + float outerRadius = 190.0f; + + int startAngle = 0; + int endAngle = 360; + int segments = 0; + + bool drawRing = true; + bool drawRingLines = false; + bool drawCircleLines = false; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // NOTE: All variables update happens inside GUI control functions + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f)); + DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); + + if (drawRing) DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.3)); + if (drawRingLines) DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, segments, Fade(BLACK, 0.4)); + if (drawCircleLines) DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, segments, Fade(BLACK, 0.4)); + + // Draw GUI controls + //------------------------------------------------------------------------------ + startAngle = GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", startAngle, -450, 450, true); + endAngle = GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", endAngle, -450, 450, true); + + innerRadius = GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", innerRadius, 0, 100, true); + outerRadius = GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", outerRadius, 0, 200, true); + + segments = GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", segments, 0, 100, true); + + drawRing = GuiCheckBox((Rectangle){ 600, 320, 20, 20 }, "Draw Ring", drawRing); + drawRingLines = GuiCheckBox((Rectangle){ 600, 350, 20, 20 }, "Draw RingLines", drawRingLines); + drawCircleLines = GuiCheckBox((Rectangle){ 600, 380, 20, 20 }, "Draw CircleLines", drawCircleLines); + //------------------------------------------------------------------------------ + + DrawText(FormatText("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 600, 270, 10, (segments >= 4)? MAROON : DARKGRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_easings_ball_anim.c b/examples/src/shapes/shapes_easings_ball_anim.c new file mode 100644 index 0000000..4477203 --- /dev/null +++ b/examples/src/shapes/shapes_easings_ball_anim.c @@ -0,0 +1,110 @@ +/******************************************************************************************* +* +* raylib [shapes] example - easings ball anim +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "easings.h" // Required for easing functions + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings ball anim"); + + // Ball variable value to be animated with easings + int ballPositionX = -100; + int ballRadius = 20; + float ballAlpha = 0.0f; + + int state = 0; + int framesCounter = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (state == 0) // Move ball position X with easing + { + framesCounter++; + ballPositionX = EaseElasticOut(framesCounter, -100, screenWidth/2 + 100, 120); + + if (framesCounter >= 120) + { + framesCounter = 0; + state = 1; + } + } + else if (state == 1) // Increase ball radius with easing + { + framesCounter++; + ballRadius = EaseElasticIn(framesCounter, 20, 500, 200); + + if (framesCounter >= 200) + { + framesCounter = 0; + state = 2; + } + } + else if (state == 2) // Change ball alpha with easing (background color blending) + { + framesCounter++; + ballAlpha = EaseCubicOut(framesCounter, 0.0f, 1.0f, 200); + + if (framesCounter >= 200) + { + framesCounter = 0; + state = 3; + } + } + else if (state == 3) // Reset state to play again + { + if (IsKeyPressed(KEY_ENTER)) + { + // Reset required variables to play again + ballPositionX = -100; + ballRadius = 20; + ballAlpha = 0.0f; + state = 0; + } + } + + if (IsKeyPressed(KEY_R)) framesCounter = 0; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (state >= 2) DrawRectangle(0, 0, screenWidth, screenHeight, GREEN); + DrawCircle(ballPositionX, 200, ballRadius, Fade(RED, 1.0f - ballAlpha)); + + if (state == 3) DrawText("PRESS [ENTER] TO PLAY AGAIN!", 240, 200, 20, BLACK); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_easings_box_anim.c b/examples/src/shapes/shapes_easings_box_anim.c new file mode 100644 index 0000000..c74cb2a --- /dev/null +++ b/examples/src/shapes/shapes_easings_box_anim.c @@ -0,0 +1,136 @@ +/******************************************************************************************* +* +* raylib [shapes] example - easings box anim +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "easings.h" // Required for easing functions + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings box anim"); + + // Box variables to be animated with easings + Rectangle rec = { GetScreenWidth()/2, -100, 100, 100 }; + float rotation = 0.0f; + float alpha = 1.0f; + + int state = 0; + int framesCounter = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + switch (state) + { + case 0: // Move box down to center of screen + { + framesCounter++; + + // NOTE: Remember that 3rd parameter of easing function refers to + // desired value variation, do not confuse it with expected final value! + rec.y = EaseElasticOut(framesCounter, -100, GetScreenHeight()/2 + 100, 120); + + if (framesCounter >= 120) + { + framesCounter = 0; + state = 1; + } + } break; + case 1: // Scale box to an horizontal bar + { + framesCounter++; + rec.height = EaseBounceOut(framesCounter, 100, -90, 120); + rec.width = EaseBounceOut(framesCounter, 100, GetScreenWidth(), 120); + + if (framesCounter >= 120) + { + framesCounter = 0; + state = 2; + } + } break; + case 2: // Rotate horizontal bar rectangle + { + framesCounter++; + rotation = EaseQuadOut(framesCounter, 0.0f, 270.0f, 240); + + if (framesCounter >= 240) + { + framesCounter = 0; + state = 3; + } + } break; + case 3: // Increase bar size to fill all screen + { + framesCounter++; + rec.height = EaseCircOut(framesCounter, 10, GetScreenWidth(), 120); + + if (framesCounter >= 120) + { + framesCounter = 0; + state = 4; + } + } break; + case 4: // Fade out animation + { + framesCounter++; + alpha = EaseSineOut(framesCounter, 1.0f, -1.0f, 160); + + if (framesCounter >= 160) + { + framesCounter = 0; + state = 5; + } + } break; + default: break; + } + + // Reset animation at any moment + if (IsKeyPressed(KEY_SPACE)) + { + rec = (Rectangle){ GetScreenWidth()/2, -100, 100, 100 }; + rotation = 0.0f; + alpha = 1.0f; + state = 0; + framesCounter = 0; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawRectanglePro(rec, (Vector2){ rec.width/2, rec.height/2 }, rotation, Fade(BLACK, alpha)); + + DrawText("PRESS [SPACE] TO RESET BOX ANIMATION!", 10, GetScreenHeight() - 25, 20, LIGHTGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_easings_rectangle_array.c b/examples/src/shapes/shapes_easings_rectangle_array.c new file mode 100644 index 0000000..27bad5c --- /dev/null +++ b/examples/src/shapes/shapes_easings_rectangle_array.c @@ -0,0 +1,118 @@ +/******************************************************************************************* +* +* raylib [shapes] example - easings rectangle array +* +* NOTE: This example requires 'easings.h' library, provided on raylib/src. Just copy +* the library to same directory as example or make sure it's available on include path. +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "easings.h" // Required for easing functions + +#define RECS_WIDTH 50 +#define RECS_HEIGHT 50 + +#define MAX_RECS_X 800/RECS_WIDTH +#define MAX_RECS_Y 450/RECS_HEIGHT + +#define PLAY_TIME_IN_FRAMES 240 // At 60 fps = 4 seconds + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings rectangle array"); + + Rectangle recs[MAX_RECS_X*MAX_RECS_Y]; + + for (int y = 0; y < MAX_RECS_Y; y++) + { + for (int x = 0; x < MAX_RECS_X; x++) + { + recs[y*MAX_RECS_X + x].x = RECS_WIDTH/2 + RECS_WIDTH*x; + recs[y*MAX_RECS_X + x].y = RECS_HEIGHT/2 + RECS_HEIGHT*y; + recs[y*MAX_RECS_X + x].width = RECS_WIDTH; + recs[y*MAX_RECS_X + x].height = RECS_HEIGHT; + } + } + + float rotation = 0.0f; + int framesCounter = 0; + int state = 0; // Rectangles animation state: 0-Playing, 1-Finished + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (state == 0) + { + framesCounter++; + + for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++) + { + recs[i].height = EaseCircOut(framesCounter, RECS_HEIGHT, -RECS_HEIGHT, PLAY_TIME_IN_FRAMES); + recs[i].width = EaseCircOut(framesCounter, RECS_WIDTH, -RECS_WIDTH, PLAY_TIME_IN_FRAMES); + + if (recs[i].height < 0) recs[i].height = 0; + if (recs[i].width < 0) recs[i].width = 0; + + if ((recs[i].height == 0) && (recs[i].width == 0)) state = 1; // Finish playing + + rotation = EaseLinearIn(framesCounter, 0.0f, 360.0f, PLAY_TIME_IN_FRAMES); + } + } + else if ((state == 1) && IsKeyPressed(KEY_SPACE)) + { + // When animation has finished, press space to restart + framesCounter = 0; + + for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++) + { + recs[i].height = RECS_HEIGHT; + recs[i].width = RECS_WIDTH; + } + + state = 0; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (state == 0) + { + for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++) + { + DrawRectanglePro(recs[i], (Vector2){ recs[i].width/2, recs[i].height/2 }, rotation, RED); + } + } + else if (state == 1) DrawText("PRESS [SPACE] TO PLAY AGAIN!", 240, 200, 20, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_following_eyes.c b/examples/src/shapes/shapes_following_eyes.c new file mode 100644 index 0000000..e99a7e0 --- /dev/null +++ b/examples/src/shapes/shapes_following_eyes.c @@ -0,0 +1,104 @@ +/******************************************************************************************* +* +* raylib [shapes] example - following eyes +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <math.h> // Required for: atan2f() + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - following eyes"); + + Vector2 scleraLeftPosition = { GetScreenWidth()/2 - 100, GetScreenHeight()/2 }; + Vector2 scleraRightPosition = { GetScreenWidth()/2 + 100, GetScreenHeight()/2 }; + float scleraRadius = 80; + + Vector2 irisLeftPosition = { GetScreenWidth()/2 - 100, GetScreenHeight()/2 }; + Vector2 irisRightPosition = { GetScreenWidth()/2 + 100, GetScreenHeight()/2}; + float irisRadius = 24; + + float angle; + float dx, dy, dxx, dyy; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + irisLeftPosition = GetMousePosition(); + irisRightPosition = GetMousePosition(); + + // Check not inside the left eye sclera + if (!CheckCollisionPointCircle(irisLeftPosition, scleraLeftPosition, scleraRadius - 20)) + { + dx = irisLeftPosition.x - scleraLeftPosition.x; + dy = irisLeftPosition.y - scleraLeftPosition.y; + + angle = atan2f(dy, dx); + + dxx = (scleraRadius - irisRadius)*cosf(angle); + dyy = (scleraRadius - irisRadius)*sinf(angle); + + irisLeftPosition.x = scleraLeftPosition.x + dxx; + irisLeftPosition.y = scleraLeftPosition.y + dyy; + } + + // Check not inside the right eye sclera + if (!CheckCollisionPointCircle(irisRightPosition, scleraRightPosition, scleraRadius - 20)) + { + dx = irisRightPosition.x - scleraRightPosition.x; + dy = irisRightPosition.y - scleraRightPosition.y; + + angle = atan2f(dy, dx); + + dxx = (scleraRadius - irisRadius)*cosf(angle); + dyy = (scleraRadius - irisRadius)*sinf(angle); + + irisRightPosition.x = scleraRightPosition.x + dxx; + irisRightPosition.y = scleraRightPosition.y + dyy; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawCircleV(scleraLeftPosition, scleraRadius, LIGHTGRAY); + DrawCircleV(irisLeftPosition, irisRadius, BROWN); + DrawCircleV(irisLeftPosition, 10, BLACK); + + DrawCircleV(scleraRightPosition, scleraRadius, LIGHTGRAY); + DrawCircleV(irisRightPosition, irisRadius, DARKGREEN); + DrawCircleV(irisRightPosition, 10, BLACK); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/shapes/shapes_logo_raylib_anim.c b/examples/src/shapes/shapes_logo_raylib_anim.c index c6d3796..9be1d96 100644 --- a/examples/src/shapes/shapes_logo_raylib_anim.c +++ b/examples/src/shapes/shapes_logo_raylib_anim.c @@ -2,7 +2,7 @@ * * raylib [shapes] example - raylib logo animation * -* This example has been created using raylib 1.4 (www.raylib.com) +* This example has been created using raylib 2.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2014 Ramon Santamaria (@raysan5) @@ -140,7 +140,7 @@ int main() DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); - DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); + DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); } else if (state == 4) { diff --git a/examples/src/shapes/shapes_rectangle_scaling.c b/examples/src/shapes/shapes_rectangle_scaling.c new file mode 100644 index 0000000..036a1dd --- /dev/null +++ b/examples/src/shapes/shapes_rectangle_scaling.c @@ -0,0 +1,94 @@ +/******************************************************************************************* +* +* raylib [shapes] example - rectangle scaling by mouse +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define MOUSE_SCALE_MARK_SIZE 12 + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle scaling mouse"); + + Rectangle rec = { 100, 100, 200, 80 }; + + Vector2 mousePosition = { 0 }; + + bool mouseScaleReady = false; + bool mouseScaleMode = false; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + mousePosition = GetMousePosition(); + + if (CheckCollisionPointRec(mousePosition, rec) && + CheckCollisionPointRec(mousePosition, (Rectangle){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE })) + { + mouseScaleReady = true; + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) mouseScaleMode = true; + } + else mouseScaleReady = false; + + if (mouseScaleMode) + { + mouseScaleReady = true; + + rec.width = (mousePosition.x - rec.x); + rec.height = (mousePosition.y - rec.y); + + if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE; + if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE; + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) mouseScaleMode = false; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Scale rectangle dragging from bottom-right corner!", 10, 10, 20, GRAY); + + DrawRectangleRec(rec, Fade(GREEN, 0.5f)); + + if (mouseScaleReady) + { + DrawRectangleLinesEx(rec, 1, RED); + DrawTriangle((Vector2){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height }, + (Vector2){ rec.x + rec.width, rec.y + rec.height }, + (Vector2){ rec.x + rec.width, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE }, RED); + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/text/text_bmfont_ttf.c b/examples/src/text/text_bmfont_ttf.c index f71f5dd..ca26b2c 100644 --- a/examples/src/text/text_bmfont_ttf.c +++ b/examples/src/text/text_bmfont_ttf.c @@ -20,17 +20,20 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont and ttf sprite fonts loading"); - const char msgBm[64] = "THIS IS AN AngelCode SPRITE FONT"; - const char msgTtf[64] = "THIS SPRITE FONT has been GENERATED from a TTF"; + // Define characters to draw + // NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally + const char msg[256] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ"; // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) - Font fontBm = LoadFont("resources/bmfont.fnt"); // BMFont (AngelCode) - Font fontTtf = LoadFont("resources/pixantiqua.ttf"); // TTF font - - Vector2 fontPosition; - - fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.baseSize, 0).x/2; - fontPosition.y = screenHeight/2 - fontBm.baseSize/2 - 80; + + // BMFont (AngelCode) : Font data and image atlas have been generated using external program + Font fontBm = LoadFont("resources/pixantiqua.fnt"); + + // TTF font : Font data and atlas are generated directly from TTF + // NOTE: We define a font base size of 32 pixels tall and up-to 250 characters + Font fontTtf = LoadFontEx("resources/pixantiqua.ttf", 32, 0, 250); + + bool useTtf = false; SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -40,7 +43,8 @@ int main() { // Update //---------------------------------------------------------------------------------- - // TODO: Update variables here... + if (IsKeyDown(KEY_SPACE)) useTtf = true; + else useTtf = false; //---------------------------------------------------------------------------------- // Draw @@ -48,9 +52,19 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); - - DrawTextEx(fontBm, msgBm, fontPosition, fontBm.baseSize, 0, MAROON); - DrawTextEx(fontTtf, msgTtf, (Vector2){ 75.0f, 240.0f }, fontTtf.baseSize*0.8f, 2, LIME); + + DrawText("Press SPACE to use TTF generated font", 20, 20, 20, LIGHTGRAY); + + if (!useTtf) + { + DrawTextEx(fontBm, msg, (Vector2){ 20.0f, 100.0f }, fontBm.baseSize, 2, MAROON); + DrawText("Using BMFont (Angelcode) imported", 20, GetScreenHeight() - 30, 20, GRAY); + } + else + { + DrawTextEx(fontTtf, msg, (Vector2){ 20.0f, 100.0f }, fontTtf.baseSize, 2, LIME); + DrawText("Using TTF font generated", 20, GetScreenHeight() - 30, 20, GRAY); + } EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/src/text/text_bmfont_unordered.c b/examples/src/text/text_bmfont_unordered.c deleted file mode 100644 index a514761..0000000 --- a/examples/src/text/text_bmfont_unordered.c +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************************* -* -* raylib [text] example - BMFont unordered chars loading and drawing -* -* This example has been created using raylib 1.4 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2016 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - int screenWidth = 800; - int screenHeight = 450; - - InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont unordered loading and drawing"); - - // NOTE: Using chars outside the [32..127] limits! - // NOTE: If a character is not found in the font, it just renders a space - const char msg[256] = "ASCII extended characters:\n¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ\nÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæ\nçèéêëìíîïðñòóôõö÷øùúûüýþÿ"; - - // NOTE: Loaded font has an unordered list of characters (chars in the range 32..255) - Font font = LoadFont("resources/pixantiqua.fnt"); // BMFont (AngelCode) - - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - // TODO: Update variables here... - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - DrawText("Font name: PixAntiqua", 40, 50, 20, GRAY); - DrawText(FormatText("Font base size: %i", font.baseSize), 40, 80, 20, GRAY); - DrawText(FormatText("Font chars number: %i", font.charsCount), 40, 110, 20, GRAY); - - DrawTextEx(font, msg, (Vector2){ 40, 180 }, font.baseSize, 0, MAROON); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - UnloadFont(font); // AngelCode Font unloading - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -}
\ No newline at end of file diff --git a/examples/src/text/text_font_sdf.c b/examples/src/text/text_font_sdf.c new file mode 100644 index 0000000..755b642 --- /dev/null +++ b/examples/src/text/text_font_sdf.c @@ -0,0 +1,125 @@ +/******************************************************************************************* +* +* raylib [text] example - TTF loading and usage +* +* This example has been created using raylib 1.3.0 (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 [text] example - SDF fonts"); + + // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + + const char msg[50] = "Signed Distance Fields"; + + // Default font generation from TTF font + Font fontDefault = { 0 }; + fontDefault.baseSize = 16; + fontDefault.charsCount = 95; + // Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array) + fontDefault.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 95, FONT_DEFAULT); + // Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default) + Image atlas = GenImageFontAtlas(fontDefault.chars, 95, 16, 4, 0); + fontDefault.texture = LoadTextureFromImage(atlas); + UnloadImage(atlas); + + // SDF font generation from TTF font + Font fontSDF = { 0 }; + fontSDF.baseSize = 16; + fontSDF.charsCount = 95; + // Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95) + fontSDF.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 0, FONT_SDF); + // Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm) + atlas = GenImageFontAtlas(fontSDF.chars, 95, 16, 0, 1); + fontSDF.texture = LoadTextureFromImage(atlas); + UnloadImage(atlas); + + // Load SDF required shader (we use default vertex shader) + Shader shader = LoadShader(0, "resources/shaders/sdf.fs"); + SetTextureFilter(fontSDF.texture, FILTER_BILINEAR); // Required for SDF font + + Vector2 fontPosition = { 40, screenHeight/2 - 50 }; + Vector2 textSize = { 0.0f }; + float fontSize = 16.0f; + int currentFont = 0; // 0 - fontDefault, 1 - fontSDF + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + fontSize += GetMouseWheelMove()*8.0f; + + if (fontSize < 6) fontSize = 6; + + if (IsKeyDown(KEY_SPACE)) currentFont = 1; + else currentFont = 0; + + if (currentFont == 0) textSize = MeasureTextEx(fontDefault, msg, fontSize, 0); + else textSize = MeasureTextEx(fontSDF, msg, fontSize, 0); + + fontPosition.x = GetScreenWidth()/2 - textSize.x/2; + fontPosition.y = GetScreenHeight()/2 - textSize.y/2 + 80; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (currentFont == 1) + { + // NOTE: SDF fonts require a custom SDf shader to compute fragment color + BeginShaderMode(shader); // Activate SDF font shader + DrawTextEx(fontSDF, msg, fontPosition, fontSize, 0, BLACK); + EndShaderMode(); // Activate our default shader for next drawings + + DrawTexture(fontSDF.texture, 10, 10, BLACK); + } + else + { + DrawTextEx(fontDefault, msg, fontPosition, fontSize, 0, BLACK); + DrawTexture(fontDefault.texture, 10, 10, BLACK); + } + + if (currentFont == 1) DrawText("SDF!", 320, 20, 80, RED); + else DrawText("default font", 315, 40, 30, GRAY); + + DrawText("FONT SIZE: 16.0", GetScreenWidth() - 240, 20, 20, DARKGRAY); + DrawText(FormatText("RENDER SIZE: %02.02f", fontSize), GetScreenWidth() - 240, 50, 20, DARKGRAY); + DrawText("Use MOUSE WHEEL to SCALE TEXT!", GetScreenWidth() - 240, 90, 10, DARKGRAY); + + DrawText("PRESS SPACE to USE SDF FONT VERSION!", 340, GetScreenHeight() - 30, 20, MAROON); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadFont(fontDefault); // Default font unloading + UnloadFont(fontSDF); // SDF font unloading + + UnloadShader(shader); // Unload SDF shader + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/text/text_rectangle_bounds.c b/examples/src/text/text_rectangle_bounds.c new file mode 100644 index 0000000..d4cd240 --- /dev/null +++ b/examples/src/text/text_rectangle_bounds.c @@ -0,0 +1,120 @@ +/******************************************************************************************* +* +* raylib [text] example - Draw text inside a rectangle +* +* This example has been created using raylib 2.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [text] example - draw text inside a rectangle"); + + char text[] = "Text cannot escape\tthis container\t...word wrap also works when active so here's\ + a long text for testing.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\ + tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet risus nullam eget felis eget."; + + bool resizing = false; + bool wordWrap = true; + + Rectangle container = { 25, 25, screenWidth - 50, screenHeight - 250}; + Rectangle resizer = { container.x + container.width - 17, container.y + container.height - 17, 14, 14 }; + + // Minimum width and heigh for the container rectangle + const int minWidth = 60; + const int minHeight = 60; + const int maxWidth = screenWidth - 50; + const int maxHeight = screenHeight - 160; + + Vector2 lastMouse = { 0, 0 }; // Stores last mouse coordinates + Color borderColor = MAROON; // Container border color + Font font = GetFontDefault(); // Get default system font + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsKeyPressed(KEY_SPACE)) wordWrap = !wordWrap; + + Vector2 mouse = GetMousePosition(); + + // Check if the mouse is inside the container and toggle border color + if (CheckCollisionPointRec(mouse, container)) borderColor = Fade(MAROON, 0.4f); + else if (!resizing) borderColor = MAROON; + + // Container resizing logic + if (resizing) + { + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) resizing = false; + + int width = container.width + (mouse.x - lastMouse.x); + container.width = (width > minWidth)? ((width < maxWidth)? width : maxWidth) : minWidth; + + int height = container.height + (mouse.y - lastMouse.y); + container.height = (height > minHeight)? ((height < maxHeight)? height : maxHeight) : minHeight; + } + else + { + // Check if we're resizing + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mouse, resizer)) resizing = true; + } + + // Move resizer rectangle properly + resizer.x = container.x + container.width - 17; + resizer.y = container.y + container.height - 17; + + lastMouse = mouse; // Update mouse + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawRectangleLinesEx(container, 3, borderColor); // Draw container border + + // Draw text in container (add some padding) + DrawTextRec(font, text, + (Rectangle){ container.x + 4, container.y + 4, container.width - 4, container.height - 4 }, + 20.0f, 2.0f, wordWrap, GRAY); + + DrawRectangleRec(resizer, borderColor); // Draw the resize box + + // Draw info + DrawText("Word Wrap: ", 313, screenHeight-115, 20, BLACK); + if (wordWrap) DrawText("ON", 447, screenHeight - 115, 20, RED); + else DrawText("OFF", 447, screenHeight - 115, 20, BLACK); + DrawText("Press [SPACE] to toggle word wrap", 218, screenHeight - 91, 20, GRAY); + + DrawRectangle(0, screenHeight - 54, screenWidth, 54, GRAY); + DrawText("Click hold & drag the to resize the container", 155, screenHeight - 38, 20, RAYWHITE); + DrawRectangleRec((Rectangle){ 382, screenHeight - 34, 12, 12 }, MAROON); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/text/text_unicode.c b/examples/src/text/text_unicode.c new file mode 100644 index 0000000..6b456a7 --- /dev/null +++ b/examples/src/text/text_unicode.c @@ -0,0 +1,323 @@ +/******************************************************************************************* +* +* raylib [text] example - Using unicode with raylib +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2019 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <stdio.h> +#include <string.h> + +#define SIZEOF(A) (sizeof(A)/sizeof(A[0])) +#define EMOJI_PER_WIDTH 8 +#define EMOJI_PER_HEIGHT 4 + +// String containing 180 emoji codepoints separated by a '\0' char +const char *const emojiCodepoints = "\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00" + "\xF0\x9F\x98\x8B\x00\xF0\x9F\x98\x8E\x00\xF0\x9F\x98\x8D\x00\xF0\x9F\x98\x98\x00\xF0\x9F\x98\x97\x00\xF0\x9F\x98\x99\x00\xF0\x9F\x98\x9A\x00\xF0\x9F\x99\x82\x00" + "\xF0\x9F\xA4\x97\x00\xF0\x9F\xA4\xA9\x00\xF0\x9F\xA4\x94\x00\xF0\x9F\xA4\xA8\x00\xF0\x9F\x98\x90\x00\xF0\x9F\x98\x91\x00\xF0\x9F\x98\xB6\x00\xF0\x9F\x99\x84\x00" + "\xF0\x9F\x98\x8F\x00\xF0\x9F\x98\xA3\x00\xF0\x9F\x98\xA5\x00\xF0\x9F\x98\xAE\x00\xF0\x9F\xA4\x90\x00\xF0\x9F\x98\xAF\x00\xF0\x9F\x98\xAA\x00\xF0\x9F\x98\xAB\x00" + "\xF0\x9F\x98\xB4\x00\xF0\x9F\x98\x8C\x00\xF0\x9F\x98\x9B\x00\xF0\x9F\x98\x9D\x00\xF0\x9F\xA4\xA4\x00\xF0\x9F\x98\x92\x00\xF0\x9F\x98\x95\x00\xF0\x9F\x99\x83\x00" + "\xF0\x9F\xA4\x91\x00\xF0\x9F\x98\xB2\x00\xF0\x9F\x99\x81\x00\xF0\x9F\x98\x96\x00\xF0\x9F\x98\x9E\x00\xF0\x9F\x98\x9F\x00\xF0\x9F\x98\xA4\x00\xF0\x9F\x98\xA2\x00" + "\xF0\x9F\x98\xAD\x00\xF0\x9F\x98\xA6\x00\xF0\x9F\x98\xA9\x00\xF0\x9F\xA4\xAF\x00\xF0\x9F\x98\xAC\x00\xF0\x9F\x98\xB0\x00\xF0\x9F\x98\xB1\x00\xF0\x9F\x98\xB3\x00" + "\xF0\x9F\xA4\xAA\x00\xF0\x9F\x98\xB5\x00\xF0\x9F\x98\xA1\x00\xF0\x9F\x98\xA0\x00\xF0\x9F\xA4\xAC\x00\xF0\x9F\x98\xB7\x00\xF0\x9F\xA4\x92\x00\xF0\x9F\xA4\x95\x00" + "\xF0\x9F\xA4\xA2\x00\xF0\x9F\xA4\xAE\x00\xF0\x9F\xA4\xA7\x00\xF0\x9F\x98\x87\x00\xF0\x9F\xA4\xA0\x00\xF0\x9F\xA4\xAB\x00\xF0\x9F\xA4\xAD\x00\xF0\x9F\xA7\x90\x00" + "\xF0\x9F\xA4\x93\x00\xF0\x9F\x98\x88\x00\xF0\x9F\x91\xBF\x00\xF0\x9F\x91\xB9\x00\xF0\x9F\x91\xBA\x00\xF0\x9F\x92\x80\x00\xF0\x9F\x91\xBB\x00\xF0\x9F\x91\xBD\x00" + "\xF0\x9F\x91\xBE\x00\xF0\x9F\xA4\x96\x00\xF0\x9F\x92\xA9\x00\xF0\x9F\x98\xBA\x00\xF0\x9F\x98\xB8\x00\xF0\x9F\x98\xB9\x00\xF0\x9F\x98\xBB\x00\xF0\x9F\x98\xBD\x00" + "\xF0\x9F\x99\x80\x00\xF0\x9F\x98\xBF\x00\xF0\x9F\x8C\xBE\x00\xF0\x9F\x8C\xBF\x00\xF0\x9F\x8D\x80\x00\xF0\x9F\x8D\x83\x00\xF0\x9F\x8D\x87\x00\xF0\x9F\x8D\x93\x00" + "\xF0\x9F\xA5\x9D\x00\xF0\x9F\x8D\x85\x00\xF0\x9F\xA5\xA5\x00\xF0\x9F\xA5\x91\x00\xF0\x9F\x8D\x86\x00\xF0\x9F\xA5\x94\x00\xF0\x9F\xA5\x95\x00\xF0\x9F\x8C\xBD\x00" + "\xF0\x9F\x8C\xB6\x00\xF0\x9F\xA5\x92\x00\xF0\x9F\xA5\xA6\x00\xF0\x9F\x8D\x84\x00\xF0\x9F\xA5\x9C\x00\xF0\x9F\x8C\xB0\x00\xF0\x9F\x8D\x9E\x00\xF0\x9F\xA5\x90\x00" + "\xF0\x9F\xA5\x96\x00\xF0\x9F\xA5\xA8\x00\xF0\x9F\xA5\x9E\x00\xF0\x9F\xA7\x80\x00\xF0\x9F\x8D\x96\x00\xF0\x9F\x8D\x97\x00\xF0\x9F\xA5\xA9\x00\xF0\x9F\xA5\x93\x00" + "\xF0\x9F\x8D\x94\x00\xF0\x9F\x8D\x9F\x00\xF0\x9F\x8D\x95\x00\xF0\x9F\x8C\xAD\x00\xF0\x9F\xA5\xAA\x00\xF0\x9F\x8C\xAE\x00\xF0\x9F\x8C\xAF\x00\xF0\x9F\xA5\x99\x00" + "\xF0\x9F\xA5\x9A\x00\xF0\x9F\x8D\xB3\x00\xF0\x9F\xA5\x98\x00\xF0\x9F\x8D\xB2\x00\xF0\x9F\xA5\xA3\x00\xF0\x9F\xA5\x97\x00\xF0\x9F\x8D\xBF\x00\xF0\x9F\xA5\xAB\x00" + "\xF0\x9F\x8D\xB1\x00\xF0\x9F\x8D\x98\x00\xF0\x9F\x8D\x9D\x00\xF0\x9F\x8D\xA0\x00\xF0\x9F\x8D\xA2\x00\xF0\x9F\x8D\xA5\x00\xF0\x9F\x8D\xA1\x00\xF0\x9F\xA5\x9F\x00" + "\xF0\x9F\xA5\xA1\x00\xF0\x9F\x8D\xA6\x00\xF0\x9F\x8D\xAA\x00\xF0\x9F\x8E\x82\x00\xF0\x9F\x8D\xB0\x00\xF0\x9F\xA5\xA7\x00\xF0\x9F\x8D\xAB\x00\xF0\x9F\x8D\xAF\x00" + "\xF0\x9F\x8D\xBC\x00\xF0\x9F\xA5\x9B\x00\xF0\x9F\x8D\xB5\x00\xF0\x9F\x8D\xB6\x00\xF0\x9F\x8D\xBE\x00\xF0\x9F\x8D\xB7\x00\xF0\x9F\x8D\xBB\x00\xF0\x9F\xA5\x82\x00" + "\xF0\x9F\xA5\x83\x00\xF0\x9F\xA5\xA4\x00\xF0\x9F\xA5\xA2\x00\xF0\x9F\x91\x81\x00\xF0\x9F\x91\x85\x00\xF0\x9F\x91\x84\x00\xF0\x9F\x92\x8B\x00\xF0\x9F\x92\x98\x00" + "\xF0\x9F\x92\x93\x00\xF0\x9F\x92\x97\x00\xF0\x9F\x92\x99\x00\xF0\x9F\x92\x9B\x00\xF0\x9F\xA7\xA1\x00\xF0\x9F\x92\x9C\x00\xF0\x9F\x96\xA4\x00\xF0\x9F\x92\x9D\x00" + "\xF0\x9F\x92\x9F\x00\xF0\x9F\x92\x8C\x00\xF0\x9F\x92\xA4\x00\xF0\x9F\x92\xA2\x00\xF0\x9F\x92\xA3\x00"; + +struct { + char *text; + char *language; +} const messages[] = { // Array containing all of the emojis messages + {"\x46\x61\x6C\x73\x63\x68\x65\x73\x20\xC3\x9C\x62\x65\x6E\x20\x76\x6F\x6E\x20\x58\x79\x6C\x6F\x70\x68\x6F\x6E\x6D\x75\x73\x69\x6B\x20\x71\x75\xC3\xA4\x6C" + "\x74\x20\x6A\x65\x64\x65\x6E\x20\x67\x72\xC3\xB6\xC3\x9F\x65\x72\x65\x6E\x20\x5A\x77\x65\x72\x67", "German"}, + {"\x42\x65\x69\xC3\x9F\x20\x6E\x69\x63\x68\x74\x20\x69\x6E\x20\x64\x69\x65\x20\x48\x61\x6E\x64\x2C\x20\x64\x69\x65\x20\x64\x69\x63\x68\x20\x66\xC3\xBC\x74" + "\x74\x65\x72\x74\x2E", "German"}, + {"\x41\x75\xC3\x9F\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\xC3\x9C\x62\x65\x6C\x20\x65\x72\x66\x6F\x72\x64\x65\x72\x6E\x20\x61\x75\xC3\x9F" + "\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\x4D\x69\x74\x74\x65\x6C\x2E", "German"}, + {"\xD4\xBF\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB4\x20\xD5\xA1\xD5\xBA\xD5\xA1\xD5\xAF\xD5\xAB\x20\xD5\xB8\xD6\x82\xD5\xBF\xD5\xA5\xD5\xAC\x20\xD6\x87\x20\xD5\xAB" + "\xD5\xB6\xD5\xAE\xD5\xAB\x20\xD5\xA1\xD5\xB6\xD5\xB0\xD5\xA1\xD5\xB6\xD5\xA3\xD5\xAB\xD5\xBD\xD5\xBF\x20\xD5\xB9\xD5\xA8\xD5\xB6\xD5\xA5\xD6\x80", "Armenian"}, + {"\xD4\xB5\xD6\x80\xD5\xA2\x20\xD5\xB8\xD6\x80\x20\xD5\xAF\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\xD5\xA8\x20\xD5\xA5\xD5\xAF\xD5\xA1\xD6\x82\x20\xD5\xA1\xD5\xB6\xD5" + "\xBF\xD5\xA1\xD5\xBC\x2C\x20\xD5\xAE\xD5\xA1\xD5\xBC\xD5\xA5\xD6\x80\xD5\xA8\x20\xD5\xA1\xD5\xBD\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\x2E\x2E\x2E\x20\xC2\xAB\xD4\xBF" + "\xD5\xB8\xD5\xBF\xD5\xA8\x20\xD5\xB4\xD5\xA5\xD6\x80\xD5\xB8\xD5\xB6\xD6\x81\xD5\xAB\xD6\x81\x20\xD5\xA7\x3A\xC2\xBB", "Armenian"}, + {"\xD4\xB3\xD5\xA1\xD5\xBC\xD5\xA8\xD5\x9D\x20\xD5\xA3\xD5\xA1\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB6\x2C\x20\xD5\xB1\xD5\xAB\xD6\x82\xD5\xB6\xD5\xA8\xD5\x9D\x20\xD5" + "\xB1\xD5\xB4\xD5\xBC\xD5\xA1\xD5\xB6", "Armenian"}, + {"\x4A\x65\xC5\xBC\x75\x20\x6B\x6C\xC4\x85\x74\x77\x2C\x20\x73\x70\xC5\x82\xC3\xB3\x64\xC5\xBA\x20\x46\x69\x6E\x6F\x6D\x20\x63\x7A\xC4\x99\xC5\x9B\xC4\x87" + "\x20\x67\x72\x79\x20\x68\x61\xC5\x84\x62\x21", "Polish"}, + {"\x44\x6F\x62\x72\x79\x6D\x69\x20\x63\x68\xC4\x99\x63\x69\x61\x6D\x69\x20\x6A\x65\x73\x74\x20\x70\x69\x65\x6B\xC5\x82\x6F\x20\x77\x79\x62\x72\x75\x6B\x6F" + "\x77\x61\x6E\x65\x2E", "Polish"}, + {"\xC3\x8E\xC8\x9B\x69\x20\x6D\x75\x6C\xC8\x9B\x75\x6D\x65\x73\x63\x20\x63\xC4\x83\x20\x61\x69\x20\x61\x6C\x65\x73\x20\x72\x61\x79\x6C\x69\x62\x2E\x0A\xC8\x98" + "\x69\x20\x73\x70\x65\x72\x20\x73\xC4\x83\x20\x61\x69\x20\x6F\x20\x7A\x69\x20\x62\x75\x6E\xC4\x83\x21", "Romanian"}, + {"\xD0\xAD\xD1\x85\x2C\x20\xD1\x87\xD1\x83\xD0\xB6\xD0\xB0\xD0\xBA\x2C\x20\xD0\xBE\xD0\xB1\xD1\x89\xD0\xB8\xD0\xB9\x20\xD1\x81\xD1\x8A\xD1\x91\xD0\xBC\x20" + "\xD1\x86\xD0\xB5\xD0\xBD\x20\xD1\x88\xD0\xBB\xD1\x8F\xD0\xBF\x20\x28\xD1\x8E\xD1\x84\xD1\x82\xD1\x8C\x29\x20\xD0\xB2\xD0\xB4\xD1\x80\xD1\x8B\xD0\xB7\xD0\xB3\x21", "Russian"}, + {"\xD0\xAF\x20\xD0\xBB\xD1\x8E\xD0\xB1\xD0\xBB\xD1\x8E\x20\x72\x61\x79\x6C\x69\x62\x21", "Russian"}, + {"\xD0\x9C\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2C\x20\xD1\x81\xD0\xBA\xD1\x80\xD1\x8B\xD0\xB2\xD0\xB0\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\x20\xD1\x82\xD0\xB0\xD0\xB8" + "\x0A\xD0\x98\x20\xD1\x87\xD1\x83\xD0\xB2\xD1\x81\xD1\x82\xD0\xB2\xD0\xB0\x20\xD0\xB8\x20\xD0\xBC\xD0\xB5\xD1\x87\xD1\x82\xD1\x8B\x20\xD1\x81\xD0\xB2\xD0\xBE\xD0\xB8\x20" + "\xE2\x80\x93\x0A\xD0\x9F\xD1\x83\xD1\x81\xD0\xBA\xD0\xB0\xD0\xB9\x20\xD0\xB2\x20\xD0\xB4\xD1\x83\xD1\x88\xD0\xB5\xD0\xB2\xD0\xBD\xD0\xBE\xD0\xB9\x20\xD0\xB3\xD0\xBB\xD1" + "\x83\xD0\xB1\xD0\xB8\xD0\xBD\xD0\xB5\x0A\xD0\x98\x20\xD0\xB2\xD1\x81\xD1\x85\xD0\xBE\xD0\xB4\xD1\x8F\xD1\x82\x20\xD0\xB8\x20\xD0\xB7\xD0\xB0\xD0\xB9\xD0\xB4\xD1\x83\xD1" + "\x82\x20\xD0\xBE\xD0\xBD\xD0\xB5\x0A\xD0\x9A\xD0\xB0\xD0\xBA\x20\xD0\xB7\xD0\xB2\xD0\xB5\xD0\xB7\xD0\xB4\xD1\x8B\x20\xD1\x8F\xD1\x81\xD0\xBD\xD1\x8B\xD0\xB5\x20\xD0\xB2" + "\x20\xD0\xBD\xD0\xBE\xD1\x87\xD0\xB8\x2D\x0A\xD0\x9B\xD1\x8E\xD0\xB1\xD1\x83\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\xD0\xBC\xD0\xB8\x20\xE2\x80\x93\x20\xD0\xB8\x20\xD0\xBC" + "\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2E", "Russian"}, + {"\x56\x6F\x69\x78\x20\x61\x6D\x62\x69\x67\x75\xC3\xAB\x20\x64\xE2\x80\x99\x75\x6E\x20\x63\xC5\x93\x75\x72\x20\x71\x75\x69\x20\x61\x75\x20\x7A\xC3\xA9\x70" + "\x68\x79\x72\x20\x70\x72\xC3\xA9\x66\xC3\xA8\x72\x65\x20\x6C\x65\x73\x20\x6A\x61\x74\x74\x65\x73\x20\x64\x65\x20\x6B\x69\x77\x69", "French"}, + {"\x42\x65\x6E\x6A\x61\x6D\xC3\xAD\x6E\x20\x70\x69\x64\x69\xC3\xB3\x20\x75\x6E\x61\x20\x62\x65\x62\x69\x64\x61\x20\x64\x65\x20\x6B\x69\x77\x69\x20\x79\x20" + "\x66\x72\x65\x73\x61\x3B\x20\x4E\x6F\xC3\xA9\x2C\x20\x73\x69\x6E\x20\x76\x65\x72\x67\xC3\xBC\x65\x6E\x7A\x61\x2C\x20\x6C\x61\x20\x6D\xC3\xA1\x73\x20\x65\x78" + "\x71\x75\x69\x73\x69\x74\x61\x20\x63\x68\x61\x6D\x70\x61\xC3\xB1\x61\x20\x64\x65\x6C\x20\x6D\x65\x6E\xC3\xBA\x2E", "Spanish"}, + {"\xCE\xA4\xCE\xB1\xCF\x87\xCE\xAF\xCF\x83\xCF\x84\xCE\xB7\x20\xCE\xB1\xCE\xBB\xCF\x8E\xCF\x80\xCE\xB7\xCE\xBE\x20\xCE\xB2\xCE\xB1\xCF\x86\xCE\xAE\xCF\x82\x20" + "\xCF\x88\xCE\xB7\xCE\xBC\xCE\xAD\xCE\xBD\xCE\xB7\x20\xCE\xB3\xCE\xB7\x2C\x20\xCE\xB4\xCF\x81\xCE\xB1\xCF\x83\xCE\xBA\xCE\xB5\xCE\xBB\xCE\xAF\xCE\xB6\xCE\xB5\xCE" + "\xB9\x20\xCF\x85\xCF\x80\xCE\xAD\xCF\x81\x20\xCE\xBD\xCF\x89\xCE\xB8\xCF\x81\xCE\xBF\xCF\x8D\x20\xCE\xBA\xCF\x85\xCE\xBD\xCF\x8C\xCF\x82", "Greek"}, + {"\xCE\x97\x20\xCE\xBA\xCE\xB1\xCE\xBB\xCF\x8D\xCF\x84\xCE\xB5\xCF\x81\xCE\xB7\x20\xCE\xAC\xCE\xBC\xCF\x85\xCE\xBD\xCE\xB1\x20\xCE\xB5\xCE\xAF\xCE\xBD" + "\xCE\xB1\xCE\xB9\x20\xCE\xB7\x20\xCE\xB5\xCF\x80\xCE\xAF\xCE\xB8\xCE\xB5\xCF\x83\xCE\xB7\x2E", "Greek"}, + {"\xCE\xA7\xCF\x81\xCF\x8C\xCE\xBD\xCE\xB9\xCE\xB1\x20\xCE\xBA\xCE\xB1\xCE\xB9\x20\xCE\xB6\xCE\xB1\xCE\xBC\xCE\xAC\xCE\xBD\xCE\xB9\xCE\xB1\x21", "Greek"}, + {"\xCE\xA0\xCF\x8E\xCF\x82\x20\xCF\x84\xCE\xB1\x20\xCF\x80\xCE\xB1\xCF\x82\x20\xCF\x83\xCE\xAE\xCE\xBC\xCE\xB5\xCF\x81\xCE\xB1\x3B", "Greek"}, + + {"\xE6\x88\x91\xE8\x83\xBD\xE5\x90\x9E\xE4\xB8\x8B\xE7\x8E\xBB\xE7\x92\x83\xE8\x80\x8C\xE4\xB8\x8D\xE4\xBC\xA4\xE8\xBA\xAB\xE4\xBD\x93\xE3\x80\x82", "Chinese"}, + {"\xE4\xBD\xA0\xE5\x90\x83\xE4\xBA\x86\xE5\x90\x97\xEF\xBC\x9F", "Chinese"}, + {"\xE4\xB8\x8D\xE4\xBD\x9C\xE4\xB8\x8D\xE6\xAD\xBB\xE3\x80\x82", "Chinese"}, + {"\xE6\x9C\x80\xE8\xBF\x91\xE5\xA5\xBD\xE5\x90\x97\xEF\xBC\x9F", "Chinese"}, + {"\xE5\xA1\x9E\xE7\xBF\x81\xE5\xA4\xB1\xE9\xA9\xAC\xEF\xBC\x8C\xE7\x84\x89\xE7\x9F\xA5\xE9\x9D\x9E\xE7\xA6\x8F\xE3\x80\x82", "Chinese"}, + {"\xE5\x8D\x83\xE5\x86\x9B\xE6\x98\x93\xE5\xBE\x97\x2C\x20\xE4\xB8\x80\xE5\xB0\x86\xE9\x9A\xBE\xE6\xB1\x82", "Chinese"}, + {"\xE4\xB8\x87\xE4\xBA\x8B\xE5\xBC\x80\xE5\xA4\xB4\xE9\x9A\xBE\xE3\x80\x82", "Chinese"}, + {"\xE9\xA3\x8E\xE6\x97\xA0\xE5\xB8\xB8\xE9\xA1\xBA\xEF\xBC\x8C\xE5\x85\xB5\xE6\x97\xA0\xE5\xB8\xB8\xE8\x83\x9C\xE3\x80\x82", "Chinese"}, + {"\xE6\xB4\xBB\xE5\x88\xB0\xE8\x80\x81\xEF\xBC\x8C\xE5\xAD\xA6\xE5\x88\xB0\xE8\x80\x81\xE3\x80\x82", "Chinese"}, + {"\xE4\xB8\x80\xE8\xA8\x80\xE6\x97\xA2\xE5\x87\xBA\xEF\xBC\x8C\xE9\xA9\xB7\xE9\xA9\xAC\xE9\x9A\xBE\xE8\xBF\xBD\xE3\x80\x82", "Chinese"}, + {"\xE8\xB7\xAF\xE9\x81\xA5\xE7\x9F\xA5\xE9\xA9\xAC\xE5\x8A\x9B\xEF\xBC\x8C\xE6\x97\xA5\xE4\xB9\x85\xE8\xA7\x81\xE4\xBA\xBA\xE5\xBF\x83", "Chinese"}, + {"\xE6\x9C\x89\xE7\x90\x86\xE8\xB5\xB0\xE9\x81\x8D\xE5\xA4\xA9\xE4\xB8\x8B\xEF\xBC\x8C\xE6\x97\xA0\xE7\x90\x86\xE5\xAF\xB8\xE6\xAD\xA5\xE9\x9A\xBE\xE8\xA1\x8C\xE3\x80\x82", "Chinese"}, + + {"\xE7\x8C\xBF\xE3\x82\x82\xE6\x9C\xA8\xE3\x81\x8B\xE3\x82\x89\xE8\x90\xBD\xE3\x81\xA1\xE3\x82\x8B", "Japanese"}, + {"\xE4\xBA\x80\xE3\x81\xAE\xE7\x94\xB2\xE3\x82\x88\xE3\x82\x8A\xE5\xB9\xB4\xE3\x81\xAE\xE5\x8A\x9F", "Japanese"}, + {"\xE3\x81\x86\xE3\x82\x89\xE3\x82\x84\xE3\x81\xBE\xE3\x81\x97\x20\x20\xE6\x80\x9D\xE3\x81\xB2\xE5\x88\x87\xE3\x82\x8B\xE6\x99\x82\x20\x20\xE7\x8C\xAB\xE3\x81\xAE\xE6\x81\x8B", "Japanese"}, + {"\xE8\x99\x8E\xE7\xA9\xB4\xE3\x81\xAB\xE5\x85\xA5\xE3\x82\x89\xE3\x81\x9A\xE3\x82\x93\xE3\x81\xB0\xE8\x99\x8E\xE5\xAD\x90\xE3\x82\x92\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82", "Japanese"}, + {"\xE4\xBA\x8C\xE5\x85\x8E\xE3\x82\x92\xE8\xBF\xBD\xE3\x81\x86\xE8\x80\x85\xE3\x81\xAF\xE4\xB8\x80\xE5\x85\x8E\xE3\x82\x92\xE3\x82\x82\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82", "Japanese"}, + {"\xE9\xA6\xAC\xE9\xB9\xBF\xE3\x81\xAF\xE6\xAD\xBB\xE3\x81\xAA\xE3\x81\xAA\xE3\x81\x8D\xE3\x82\x83\xE6\xB2\xBB\xE3\x82\x89\xE3\x81\xAA\xE3\x81\x84\xE3\x80\x82", "Japanese"}, + {"\xE6\x9E\xAF\xE9\x87\x8E\xE8\xB7\xAF\xE3\x81\xAB\xE3\x80\x80\xE5\xBD\xB1\xE3\x81\x8B\xE3\x81\x95\xE3\x81\xAA\xE3\x82\x8A\xE3\x81\xA6\xE3\x80\x80\xE3\x82\x8F\xE3\x81\x8B\xE3\x82\x8C\xE3\x81\x91\xE3\x82\x8A", "Japanese"}, + {"\xE7\xB9\xB0\xE3\x82\x8A\xE8\xBF\x94\xE3\x81\x97\xE9\xBA\xA6\xE3\x81\xAE\xE7\x95\x9D\xE7\xB8\xAB\xE3\x81\xB5\xE8\x83\xA1\xE8\x9D\xB6\xE5\x93\x89", "Japanese"}, + + {"\xEC\x95\x84\xEB\x93\x9D\xED\x95\x9C\x20\xEB\xB0\x94\xEB\x8B\xA4\x20\xEC\x9C\x84\xEC\x97\x90\x20\xEA\xB0\x88\xEB\xA7\xA4\xEA\xB8\xB0\x20\xEB\x91\x90\xEC\x97\x87\x20" + "\xEB\x82\xA0\xEC\x95\x84\x20\xEB\x8F\x88\xEB\x8B\xA4\x2E\x0A\xEB\x84\x88\xED\x9B\x8C\xEB\x84\x88\xED\x9B\x8C\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E" + "\x20\xEB\xAA\xA8\xEB\xA5\xB4\xEB\x8A\x94\x20\xEB\x82\x98\xEB\x9D\xBC\x20\xEA\xB8\x80\xEC\x9E\x90\xEB\x8B\xA4\x2E\x0A\xEB\x84\x90\xEB\x94\xB0\xEB\x9E\x80\x20\xED\x95\x98" + "\xEB\x8A\x98\x20\xEB\xB3\xB5\xED\x8C\x90\xEC\x97\x90\x20\xEB\x82\x98\xEB\x8F\x84\x20\xEA\xB0\x99\xEC\x9D\xB4\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E", "Korean"}, + {"\xEC\xA0\x9C\x20\xEB\x88\x88\xEC\x97\x90\x20\xEC\x95\x88\xEA\xB2\xBD\xEC\x9D\xB4\xEB\x8B\xA4", "Korean"}, + {"\xEA\xBF\xA9\x20\xEB\xA8\xB9\xEA\xB3\xA0\x20\xEC\x95\x8C\x20\xEB\xA8\xB9\xEB\x8A\x94\xEB\x8B\xA4", "Korean"}, + {"\xEB\xA1\x9C\xEB\xA7\x88\xEB\x8A\x94\x20\xED\x95\x98\xEB\xA3\xA8\xEC\x95\x84\xEC\xB9\xA8\xEC\x97\x90\x20\xEC\x9D\xB4\xEB\xA3\xA8\xEC\x96\xB4\xEC\xA7\x84\x20\xEA\xB2\x83\xEC\x9D\xB4" + "\x20\xEC\x95\x84\xEB\x8B\x88\xEB\x8B\xA4", "Korean"}, + {"\xEA\xB3\xA0\xEC\x83\x9D\x20\xEB\x81\x9D\xEC\x97\x90\x20\xEB\x82\x99\xEC\x9D\xB4\x20\xEC\x98\xA8\xEB\x8B\xA4", "Korean"}, + {"\xEA\xB0\x9C\xEC\xB2\x9C\xEC\x97\x90\xEC\x84\x9C\x20\xEC\x9A\xA9\x20\xEB\x82\x9C\xEB\x8B\xA4", "Korean"}, + {"\xEC\x95\x88\xEB\x85\x95\xED\x95\x98\xEC\x84\xB8\xEC\x9A\x94\x3F", "Korean"}, + {"\xEB\xA7\x8C\xEB\x82\x98\xEC\x84\x9C\x20\xEB\xB0\x98\xEA\xB0\x91\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4", "Korean"}, + {"\xED\x95\x9C\xEA\xB5\xAD\xEB\xA7\x90\x20\xED\x95\x98\xEC\x8B\xA4\x20\xEC\xA4\x84\x20\xEC\x95\x84\xEC\x84\xB8\xEC\x9A\x94\x3F", "Korean"}, +}; + +//-------------------------------------------------------------------------------------- +// Module functions declaration +//-------------------------------------------------------------------------------------- +static void RandomizeEmoji(void); // Fills the emoji array with random emojis + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +// Arrays that holds the random emojis +struct { + int index; // Index inside `emojiCodepoints` + int message; // Message index + Color color; // Emoji color +} emoji[EMOJI_PER_WIDTH*EMOJI_PER_HEIGHT] = { 0 }; + +static int hovered = -1, selected = -1; + +//-------------------------------------------------------------------------------------- +// Main entry point +//-------------------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT); + InitWindow(screenWidth, screenHeight, "raylib - unicode test"); + + // Load the font resources + // NOTE: fontAsian is for asian languages, + // fontEmoji is the emojis and fontDefault is used for everything else + Font fontDefault = LoadFont("resources/dejavu.fnt"); + Font fontAsian = LoadFont("resources/notoCJK.fnt"); + Font fontEmoji = LoadFont("resources/emoji.fnt"); + + Vector2 hoveredPos = { 0.0f, 0.0f }; + Vector2 selectedPos = { 0.0f, 0.0f }; + + // Set a random set of emojis when starting up + RandomizeEmoji(); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + // Add a new set of emojis when SPACE is pressed + if (IsKeyPressed(KEY_SPACE)) RandomizeEmoji(); + + // Set the selected emoji and copy its text to clipboard + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && (hovered != -1) && (hovered != selected)) + { + selected = hovered; + selectedPos = hoveredPos; + SetClipboardText(messages[emoji[selected].message].text); + } + + Vector2 mouse = GetMousePosition(); + Vector2 pos = { 28.8f, 10.0f }; + hovered = -1; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw random emojis in the background + //------------------------------------------------------------------------------ + for (int i = 0; i < SIZEOF(emoji); ++i) + { + const char *txt = &emojiCodepoints[emoji[i].index]; + Rectangle emojiRect = { pos.x, pos.y, fontEmoji.baseSize, fontEmoji.baseSize }; + + if (!CheckCollisionPointRec(mouse, emojiRect)) + { + DrawTextEx(fontEmoji, txt, pos, fontEmoji.baseSize, 1.0, selected == i ? emoji[i].color : Fade(LIGHTGRAY, 0.4f)); + } + else + { + DrawTextEx(fontEmoji, txt, pos, fontEmoji.baseSize, 1.0, emoji[i].color ); + hovered = i; + hoveredPos = pos; + } + + if ((i != 0) && (i%EMOJI_PER_WIDTH == 0)) { pos.y += fontEmoji.baseSize + 24.25f; pos.x = 28.8f; } + else pos.x += fontEmoji.baseSize + 28.8f; + } + //------------------------------------------------------------------------------ + + // Draw the message when a emoji is selected + //------------------------------------------------------------------------------ + if (selected != -1) + { + const int message = emoji[selected].message; + const int horizontalPadding = 20, verticalPadding = 30; + Font *font = &fontDefault; + + // Set correct font for asian languages + if (TextIsEqual(messages[message].language, "Chinese") || + TextIsEqual(messages[message].language, "Korean") || + TextIsEqual(messages[message].language, "Japanese")) font = &fontAsian; + + // Calculate size for the message box (approximate the height and width) + Vector2 sz = MeasureTextEx(*font, messages[message].text, font->baseSize, 1.0f); + if (sz.x > 300) { sz.y *= sz.x/300; sz.x = 300; } + else if (sz.x < 160) sz.x = 160; + + Rectangle msgRect = { selectedPos.x - 38.8f, selectedPos.y, 2 * horizontalPadding + sz.x, 2 * verticalPadding + sz.y }; + msgRect.y -= msgRect.height; + + // Coordinates for the chat bubble triangle + Vector2 a = { selectedPos.x, msgRect.y + msgRect.height }, b = {a.x + 8, a.y + 10}, c= { a.x + 10, a.y }; + + // Don't go outside the screen + if (msgRect.x < 10) msgRect.x += 28; + if (msgRect.y < 10) + { + msgRect.y = selectedPos.y + 84; + a.y = msgRect.y; + c.y = a.y; + b.y = a.y - 10; + + // Swap values so we can actually render the triangle :( + Vector2 tmp = a; + a = b; + b = tmp; + } + if (msgRect.x + msgRect.width > screenWidth) msgRect.x -= (msgRect.x + msgRect.width) - screenWidth + 10; + + // Draw chat bubble + DrawRectangleRec(msgRect, emoji[selected].color); + DrawTriangle(a, b, c, emoji[selected].color); + + // Draw the main text message + Rectangle textRect = { msgRect.x + horizontalPadding/2, msgRect.y + verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; + DrawTextRec(*font, messages[message].text, textRect, font->baseSize, 1.0f, true, WHITE); + + // Draw the info text below the main message + int size = strlen(messages[message].text); + unsigned int len = TextCountCodepoints(messages[message].text); + const char *info = TextFormat("%s %u characters %i bytes", messages[message].language, len, size); + sz = MeasureTextEx(GetFontDefault(), info, 10, 1.0f); + Vector2 pos = { textRect.x + textRect.width - sz.x, msgRect.y + msgRect.height - sz.y - 2 }; + DrawText(info, pos.x, pos.y, 10, RAYWHITE); + } + //------------------------------------------------------------------------------ + + // Draw the info text + DrawText("These emojis have something to tell you, click each to find out!", (screenWidth - 650)/2, screenHeight - 40, 20, GRAY); + DrawText("Each emoji is a unicode character from a font, not a texture... Press [SPACEBAR] to refresh", (screenWidth - 484)/2, screenHeight - 16, 10, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadFont(fontDefault); // Unload font resource + UnloadFont(fontAsian); // Unload font resource + UnloadFont(fontEmoji); // Unload font resource + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +// Fills the emoji array with random emoji (only those emojis present in fontEmoji) +static void RandomizeEmoji(void) +{ + hovered = selected = -1; + int start = GetRandomValue(45, 360); + + for (int i = 0; i < SIZEOF(emoji); ++i) + { + // 0-179 emoji codepoints (from emoji char array) each 4bytes + null char + emoji[i].index = GetRandomValue(0, 179)*5; + + // Generate a random color for this emoji + Vector3 hsv = {(start*(i + 1))%360, 0.6f, 0.85f}; + emoji[i].color = Fade(ColorFromHSV(hsv), 0.8f); + + // Set a random message for this emoji + emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1); + } +} diff --git a/examples/src/text/text_writing_anim.c b/examples/src/text/text_writing_anim.c index 5563b56..b2aba69 100644 --- a/examples/src/text/text_writing_anim.c +++ b/examples/src/text/text_writing_anim.c @@ -2,7 +2,7 @@ * * raylib [text] example - Text Writing Animation * -* This example has been created using raylib 1.4 (www.raylib.com) +* This example has been created using raylib 2.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2016 Ramon Santamaria (@raysan5) @@ -44,7 +44,7 @@ int main() ClearBackground(RAYWHITE); - DrawText(SubText(message, 0, framesCounter/10), 210, 160, 20, MAROON); + DrawText(TextSubtext(message, 0, framesCounter/10), 210, 160, 20, MAROON); DrawText("PRESS [ENTER] to RESTART!", 240, 260, 20, LIGHTGRAY); DrawText("PRESS [SPACE] to SPEED UP!", 239, 300, 20, LIGHTGRAY); diff --git a/examples/src/textures/textures_background_scrolling.c b/examples/src/textures/textures_background_scrolling.c new file mode 100644 index 0000000..2be0810 --- /dev/null +++ b/examples/src/textures/textures_background_scrolling.c @@ -0,0 +1,87 @@ +/******************************************************************************************* +* +* raylib [textures] example - Background scrolling +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - background scrolling"); + + // NOTE: Be careful, background width must be equal or bigger than screen width + // if not, texture should be draw more than two times for scrolling effect + Texture2D background = LoadTexture("resources/cyberpunk_street_background.png"); + Texture2D midground = LoadTexture("resources/cyberpunk_street_midground.png"); + Texture2D foreground = LoadTexture("resources/cyberpunk_street_foreground.png"); + + float scrollingBack = 0; + float scrollingMid = 0; + float scrollingFore = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + scrollingBack -= 0.1f; + scrollingMid -= 0.5f; + scrollingFore -= 1.0f; + + // NOTE: Texture is scaled twice its size, so it sould be considered on scrolling + if (scrollingBack <= -background.width*2) scrollingBack = 0; + if (scrollingMid <= -midground.width*2) scrollingMid = 0; + if (scrollingFore <= -foreground.width*2) scrollingFore = 0; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(GetColor(0x052c46ff)); + + // Draw background image twice + // NOTE: Texture is scaled twice its size + DrawTextureEx(background, (Vector2){ scrollingBack, 20 }, 0.0f, 2.0f, WHITE); + DrawTextureEx(background, (Vector2){ background.width*2 + scrollingBack, 20 }, 0.0f, 2.0f, WHITE); + + // Draw midground image twice + DrawTextureEx(midground, (Vector2){ scrollingMid, 20 }, 0.0f, 2.0f, WHITE); + DrawTextureEx(midground, (Vector2){ midground.width*2 + scrollingMid, 20 }, 0.0f, 2.0f, WHITE); + + // Draw foreground image twice + DrawTextureEx(foreground, (Vector2){ scrollingFore, 70 }, 0.0f, 2.0f, WHITE); + DrawTextureEx(foreground, (Vector2){ foreground.width*2 + scrollingFore, 70 }, 0.0f, 2.0f, WHITE); + + DrawText("BACKGROUND SCROLLING & PARALLAX", 10, 10, 20, RED); + DrawText("(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)", screenWidth - 330, screenHeight - 20, 10, RAYWHITE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(background); // Unload background texture + UnloadTexture(midground); // Unload midground texture + UnloadTexture(foreground); // Unload foreground texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/textures/textures_bunnymark.c b/examples/src/textures/textures_bunnymark.c new file mode 100644 index 0000000..7607883 --- /dev/null +++ b/examples/src/textures/textures_bunnymark.c @@ -0,0 +1,116 @@ +/******************************************************************************************* +* +* raylib [textures] example - Bunnymark +* +* This example has been created using raylib 1.6 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include <stdlib.h> // Required for: malloc(), free() + +#define MAX_BUNNIES 100000 // 100K bunnies limit + +// This is the maximum amount of elements (quads) per batch +// NOTE: This value is defined in [rlgl] module and can be changed there +#define MAX_BATCH_ELEMENTS 8192 + +typedef struct Bunny { + Vector2 position; + Vector2 speed; + Color color; +} Bunny; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark"); + + Texture2D texBunny = LoadTexture("resources/wabbit_alpha.png"); + + Bunny *bunnies = (Bunny *)malloc(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array + + int bunniesCount = 0; // Bunnies counter + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + // Create more bunnies + for (int i = 0; i < 100; i++) + { + bunnies[bunniesCount].position = GetMousePosition(); + bunnies[bunniesCount].speed.x = (float)GetRandomValue(-250, 250)/60.0f; + bunnies[bunniesCount].speed.y = (float)GetRandomValue(-250, 250)/60.0f; + bunnies[bunniesCount].color = (Color){ GetRandomValue(50, 240), + GetRandomValue(80, 240), + GetRandomValue(100, 240), 255 }; + bunniesCount++; + } + } + + // Update bunnies + for (int i = 0; i < bunniesCount; i++) + { + bunnies[i].position.x += bunnies[i].speed.x; + bunnies[i].position.y += bunnies[i].speed.y; + + if (((bunnies[i].position.x + texBunny.width/2) > GetScreenWidth()) || + ((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; + if (((bunnies[i].position.y + texBunny.height/2) > GetScreenHeight()) || + ((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + for (int i = 0; i < bunniesCount; i++) + { + // NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS), + // a draw call is launched and buffer starts being filled again; + // before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU... + // Process of sending data is costly and it could happen that GPU data has not been completely + // processed for drawing while new data is tried to be sent (updating current in-use buffers) + // it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies + DrawTexture(texBunny, bunnies[i].position.x, bunnies[i].position.y, bunnies[i].color); + } + + DrawRectangle(0, 0, screenWidth, 40, BLACK); + DrawText(FormatText("bunnies: %i", bunniesCount), 120, 10, 20, GREEN); + DrawText(FormatText("batched draw calls: %i", 1 + bunniesCount/MAX_BATCH_ELEMENTS), 320, 10, 20, MAROON); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + free(bunnies); // Unload bunnies data array + + UnloadTexture(texBunny); // Unload bunny texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/textures/textures_image_processing.c b/examples/src/textures/textures_image_processing.c index 58b746e..6d33d95 100644 --- a/examples/src/textures/textures_image_processing.c +++ b/examples/src/textures/textures_image_processing.c @@ -51,7 +51,7 @@ int main() // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) Image image = LoadImage("resources/parrots.png"); // Loaded in CPU memory (RAM) - ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); // Format image to RGBA 32bit (required for texture update) + ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); // Format image to RGBA 32bit (required for texture update) <-- ISSUE Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM) int currentProcess = NONE; @@ -59,7 +59,7 @@ int main() Rectangle selectRecs[NUM_PROCESSES]; - for (int i = 0; i < NUM_PROCESSES; i++) selectRecs[i] = (Rectangle){ 40, 50 + 32*i, 150, 30 }; + for (int i = 0; i < NUM_PROCESSES; i++) selectRecs[i] = (Rectangle){ 40.0f, (float)(50 + 32*i), 150.0f, 30.0f }; SetTargetFPS(60); //--------------------------------------------------------------------------------------- @@ -121,18 +121,9 @@ int main() // Draw rectangles for (int i = 0; i < NUM_PROCESSES; i++) { - if (i == currentProcess) - { - DrawRectangleRec(selectRecs[i], SKYBLUE); - DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE); - DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[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(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2, selectRecs[i].y + 11, 10, DARKGRAY); - } + DrawRectangleRec(selectRecs[i], (i == currentProcess) ? SKYBLUE : LIGHTGRAY); + DrawRectangleLines((int)selectRecs[i].x, (int) selectRecs[i].y, (int) selectRecs[i].width, (int) selectRecs[i].height, (i == currentProcess) ? BLUE : GRAY); + DrawText( processText[i], (int)( selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) selectRecs[i].y + 11, 10, (i == currentProcess) ? DARKBLUE : DARKGRAY); } DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE); diff --git a/examples/src/textures/textures_image_text.c b/examples/src/textures/textures_image_text.c new file mode 100644 index 0000000..ce91fbf --- /dev/null +++ b/examples/src/textures/textures_image_text.c @@ -0,0 +1,83 @@ +/******************************************************************************************* +* +* raylib [texture] example - Image text drawing using TTF generated spritefont +* +* This example has been created using raylib 1.8 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2017 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing"); + + // TTF Font loading with custom generation parameters + Font font = LoadFontEx("resources/KAISG.ttf", 64, 0, 0); + + Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM) + + // Draw over image using custom font + ImageDrawTextEx(&parrots, (Vector2){ 20.0f, 20.0f }, font, "[Parrots font drawing]", (float)font.baseSize, 0.0f, RED); + + Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM) + UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM + + Vector2 position = { (float)(screenWidth/2 - texture.width/2), (float)(screenHeight/2 - texture.height/2 - 20) }; + + bool showFont = false; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsKeyDown(KEY_SPACE)) showFont = true; + else showFont = false; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (!showFont) + { + // Draw texture with text already drawn inside + DrawTextureV(texture, position, WHITE); + + // Draw text directly using sprite font + DrawTextEx(font, "[Parrots font drawing]", (Vector2){ position.x + 20, + position.y + 20 + 280 }, (float)font.baseSize, 0.0f, WHITE); + } + else DrawTexture(font.texture, screenWidth/2 - font.texture.width/2, 50, BLACK); + + DrawText("PRESS SPACE to SEE USED SPRITEFONT ", 290, 420, 10, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(texture); // Texture unloading + + UnloadFont(font); // Unload custom spritefont + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/textures/textures_npatch_drawing.c b/examples/src/textures/textures_npatch_drawing.c new file mode 100644 index 0000000..0514efe --- /dev/null +++ b/examples/src/textures/textures_npatch_drawing.c @@ -0,0 +1,109 @@ +/******************************************************************************************* +* +* raylib [textures] example - N-patch drawing +* +* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Jorge A. Gomes (@overdev) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2018 Jorge A. Gomes (@overdev) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - N-patch drawing"); + + // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) + Texture2D nPatchTexture = LoadTexture("resources/ninepatch_button.png"); + + Vector2 mousePosition = { 0 }; + Vector2 origin = { 0.0f, 0.0f }; + + // Position and size of the n-patches + Rectangle dstRec1 = { 480.0f, 160.0f, 32.0f, 32.0f }; + Rectangle dstRec2 = { 160.0f, 160.0f, 32.0f, 32.0f }; + Rectangle dstRecH = { 160.0f, 93.0f, 32.0f, 32.0f }; + Rectangle dstRecV = { 92.0f, 160.0f, 32.0f, 32.0f }; + + // A 9-patch (NPT_9PATCH) changes its sizes in both axis + NPatchInfo ninePatchInfo1 = { (Rectangle){ 0.0f, 0.0f, 64.0f, 64.0f }, 12, 40, 12, 12, NPT_9PATCH }; + NPatchInfo ninePatchInfo2 = { (Rectangle){ 0.0f, 128.0f, 64.0f, 64.0f }, 16, 16, 16, 16, NPT_9PATCH }; + + // A horizontal 3-patch (NPT_3PATCH_HORIZONTAL) changes its sizes along the x axis only + NPatchInfo h3PatchInfo = { (Rectangle){ 0.0f, 64.0f, 64.0f, 64.0f }, 8, 8, 8, 8, NPT_3PATCH_HORIZONTAL }; + + // A vertical 3-patch (NPT_3PATCH_VERTICAL) changes its sizes along the y axis only + NPatchInfo v3PatchInfo = { (Rectangle){ 0.0f, 192.0f, 64.0f, 64.0f }, 6, 6, 6, 6, NPT_3PATCH_VERTICAL }; + + SetTargetFPS(60); + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + mousePosition = GetMousePosition(); + + // Resize the n-patches based on mouse position + dstRec1.width = mousePosition.x - dstRec1.x; + dstRec1.height = mousePosition.y - dstRec1.y; + dstRec2.width = mousePosition.x - dstRec2.x; + dstRec2.height = mousePosition.y - dstRec2.y; + dstRecH.width = mousePosition.x - dstRecH.x; + dstRecV.height = mousePosition.y - dstRecV.y; + + // Set a minimum width and/or height + if (dstRec1.width < 1.0f) dstRec1.width = 1.0f; + if (dstRec1.width > 300.0f) dstRec1.width = 300.0f; + if (dstRec1.height < 1.0f) dstRec1.height = 1.0f; + if (dstRec2.width < 1.0f) dstRec2.width = 1.0f; + if (dstRec2.width > 300.0f) dstRec2.width = 300.0f; + if (dstRec2.height < 1.0f) dstRec2.height = 1.0f; + if (dstRecH.width < 1.0f) dstRecH.width = 1.0f; + if (dstRecV.height < 1.0f) dstRecV.height = 1.0f; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw the n-patches + DrawTextureNPatch(nPatchTexture, ninePatchInfo2, dstRec2, origin, 0.0f, WHITE); + DrawTextureNPatch(nPatchTexture, ninePatchInfo1, dstRec1, origin, 0.0f, WHITE); + DrawTextureNPatch(nPatchTexture, h3PatchInfo, dstRecH, origin, 0.0f, WHITE); + DrawTextureNPatch(nPatchTexture, v3PatchInfo, dstRecV, origin, 0.0f, WHITE); + + // Draw the source texture + DrawRectangleLines(5, 88, 74, 266, BLUE); + DrawTexture(nPatchTexture, 10, 93, WHITE); + DrawText("TEXTURE", 15, 360, 10, DARKGRAY); + + DrawText("Move the mouse to stretch or shrink the n-patches", 10, 20, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(nPatchTexture); // Texture unloading + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/src/textures/textures_raw_data.c b/examples/src/textures/textures_raw_data.c index b038792..481bd66 100644 --- a/examples/src/textures/textures_raw_data.c +++ b/examples/src/textures/textures_raw_data.c @@ -32,8 +32,8 @@ int main() UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data // Generate a checked texture by code (1024x1024 pixels) - int width = 1024; - int height = 1024; + int width = 960; + int height = 480; // Dynamic memory allocation to store pixels data (Color type) Color *pixels = (Color *)malloc(width*height*sizeof(Color)); @@ -42,8 +42,8 @@ int main() { for (int x = 0; x < width; x++) { - if (((x/32+y/32)/1)%2 == 0) pixels[y*height + x] = ORANGE; - else pixels[y*height + x] = GOLD; + if (((x/32+y/32)/1)%2 == 0) pixels[y*width + x] = ORANGE; + else pixels[y*width + x] = GOLD; } } @@ -73,9 +73,9 @@ int main() DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.5f)); DrawTexture(fudesumi, 430, -30, WHITE); - DrawText("CHECKED TEXTURE ", 84, 100, 30, BROWN); - DrawText("GENERATED by CODE", 72, 164, 30, BROWN); - DrawText("and RAW IMAGE LOADING", 46, 226, 30, BROWN); + DrawText("CHECKED TEXTURE ", 84, 85, 30, BROWN); + DrawText("GENERATED by CODE", 72, 148, 30, BROWN); + DrawText("and RAW IMAGE LOADING", 46, 210, 30, BROWN); DrawText("(c) Fudesumi sprite by Eiden Marsal", 310, screenHeight - 20, 10, BROWN); diff --git a/examples/src/textures/textures_sprite_button.c b/examples/src/textures/textures_sprite_button.c new file mode 100644 index 0000000..bbd5732 --- /dev/null +++ b/examples/src/textures/textures_sprite_button.c @@ -0,0 +1,97 @@ +/******************************************************************************************* +* +* raylib [textures] example - sprite button +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2019 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define NUM_FRAMES 3 // Number of frames (rectangles) for the button sprite texture + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite button"); + + InitAudioDevice(); // Initialize audio device + + Sound fxButton = LoadSound("resources/buttonfx.wav"); // Load button sound + Texture2D button = LoadTexture("resources/button.png"); // Load button texture + + // Define frame rectangle for drawing + int frameHeight = button.height/NUM_FRAMES; + Rectangle sourceRec = { 0, 0, button.width, frameHeight }; + + // Define button bounds on screen + Rectangle btnBounds = { screenWidth/2 - button.width/2, screenHeight/2 - button.height/NUM_FRAMES/2, button.width, frameHeight }; + + int btnState = 0; // Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED + bool btnAction = false; // Button action should be activated + + Vector2 mousePoint = { 0.0f, 0.0f }; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + mousePoint = GetMousePosition(); + btnAction = false; + + // Check button state + if (CheckCollisionPointRec(mousePoint, btnBounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) btnState = 2; + else btnState = 1; + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) btnAction = true; + } + else btnState = 0; + + if (btnAction) + { + PlaySound(fxButton); + + // TODO: Any desired action + } + + // Calculate button frame rectangle to draw depending on button state + sourceRec.y = btnState*frameHeight; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawTextureRec(button, sourceRec, (Vector2){ btnBounds.x, btnBounds.y }, WHITE); // Draw button frame + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(button); // Unload button texture + UnloadSound(fxButton); // Unload sound + + CloseAudioDevice(); // Close audio device + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/textures/textures_sprite_explosion.c b/examples/src/textures/textures_sprite_explosion.c new file mode 100644 index 0000000..aa10a76 --- /dev/null +++ b/examples/src/textures/textures_sprite_explosion.c @@ -0,0 +1,120 @@ +/******************************************************************************************* +* +* raylib [textures] example - sprite explosion +* +* This example has been created using raylib 2.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2019 Anata and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define NUM_FRAMES 8 +#define NUM_LINES 6 + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite explosion"); + + InitAudioDevice(); + + // Load explosion sound + Sound fxBoom = LoadSound("resources/boom.wav"); + + // Load explosion texture + Texture2D explosion = LoadTexture("resources/explosion2.png"); + + // Init variables for animation + int frameWidth = explosion.width/NUM_FRAMES; // Sprite one frame rectangle width + int frameHeight = explosion.height/NUM_LINES; // Sprite one frame rectangle height + int currentFrame = 0; + int currentLine = 0; + + Rectangle frameRec = { 0, 0, frameWidth, frameHeight }; + Vector2 position = { 0, 0 }; + + bool active = false; + int framesCounter = 0; + + SetTargetFPS(120); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + // Check for mouse button pressed and activate explosion (if not active) + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && !active) + { + position = GetMousePosition(); + active = true; + + position.x -= frameWidth/2; + position.y -= frameHeight/2; + + PlaySound(fxBoom); + } + + // Compute explosion animation frames + if (active) + { + framesCounter++; + + if (framesCounter > 2) + { + currentFrame++; + + if (currentFrame >= NUM_FRAMES) + { + currentFrame = 0; + currentLine++; + + if (currentLine >= NUM_LINES) + { + currentLine = 0; + active = false; + } + } + + framesCounter = 0; + } + } + + frameRec.x = frameWidth*currentFrame; + frameRec.y = frameHeight*currentLine; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw explosion required frame rectangle + if (active) DrawTextureRec(explosion, frameRec, position, WHITE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(explosion); // Unload texture + UnloadSound(fxBoom); // Unload sound + + CloseAudioDevice(); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +}
\ No newline at end of file diff --git a/examples/src/textures/textures_srcrec_dstrec.c b/examples/src/textures/textures_srcrec_dstrec.c index cc08eb5..298a0c6 100644 --- a/examples/src/textures/textures_srcrec_dstrec.c +++ b/examples/src/textures/textures_srcrec_dstrec.c @@ -27,13 +27,13 @@ int main() int frameHeight = scarfy.height; // NOTE: Source rectangle (part of the texture to use for drawing) - Rectangle sourceRec = { 0.0f, 0.0f, (float)frameWidth, (float)frameHeight }; + Rectangle sourceRec = { 0.0f, 0.0f, frameWidth, frameHeight }; // NOTE: Destination rectangle (screen rectangle where drawing part of texture) - Rectangle destRec = { (float)screenWidth/2, (float)screenHeight/2, (float)frameWidth*2, (float)frameHeight*2 }; + Rectangle destRec = { screenWidth/2, screenHeight/2, frameWidth*2, frameHeight*2 }; // NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size - Vector2 origin = { (float)frameWidth, (float)frameHeight }; + Vector2 origin = { frameWidth, frameHeight }; int rotation = 0; @@ -61,7 +61,7 @@ int main() // rotation defines the texture rotation (using origin as rotation point) DrawTexturePro(scarfy, sourceRec, destRec, origin, (float)rotation, WHITE); - DrawLine((int) destRec.x, 0, (int) destRec.x, screenHeight, GRAY); + DrawLine((int)destRec.x, 0, (int)destRec.x, screenHeight, GRAY); DrawLine(0, (int)destRec.y, screenWidth, (int)destRec.y, GRAY); DrawText("(c) Scarfy sprite by Eiden Marsal", screenWidth - 200, screenHeight - 20, 10, GRAY); |
