From 6f60622619ed3b2606cc186d9d87cfe15e665e75 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 21:20:14 +0200 Subject: [PATCH] ADDED: Example: core_custom_frame_control --- examples/core/core_custom_frame_control.c | 126 ++++++++++++++++++++ examples/core/core_custom_frame_control.png | Bin 0 -> 16952 bytes 2 files changed, 126 insertions(+) create mode 100644 examples/core/core_custom_frame_control.c create mode 100644 examples/core/core_custom_frame_control.png diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c new file mode 100644 index 000000000..c1290abff --- /dev/null +++ b/examples/core/core_custom_frame_control.c @@ -0,0 +1,126 @@ +/******************************************************************************************* +* +* raylib [core] example - custom frame control +* +* WARNING: This is an example for advance users willing to have full control over +* the frame processes. By default, EndDrawing() calls the following processes: +* 1. Draw remaining batch data: rlDrawRenderBatchActive() +* 2. SwapScreenBuffer() +* 3. Frame time control: WaitTime() +* 4. PollInputEvents() +* +* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in +* config.h (it requires recompiling raylib). This way those steps are up to the user. +* +* Note that enabling this flag invalidates some functions: +* - GetFrameTime() +* - SetTargetFPS() +* - GetFPS() +* +* This example has been created using raylib 3.8 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2021 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - custom frame control"); + + // Custom timming variables + double previousTime = GetTime(); // Previous time measure + double currentTime = 0.0; // Current time measure + double updateDrawTime = 0.0; // Update + Draw time + double waitTime = 0.0; // Wait time (if target fps required) + float deltaTime = 0.0f; // Frame time (Update + Draw + Wait time) + + float timeCounter = 0.0f; // Accumulative time counter (seconds) + float position = 0.0f; // Circle position + bool pause = false; // Pause control flag + + int targetFPS = 60; // Our initial target fps + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL) + + if (IsKeyPressed(KEY_SPACE)) pause = !pause; + + if (IsKeyPressed(KEY_UP)) targetFPS += 20; + else if (IsKeyPressed(KEY_DOWN)) targetFPS -= 20; + + if (targetFPS < 0) targetFPS = 0; + + if (!pause) + { + position += 200*deltaTime; // We move at 200 pixels per second + + if (position >= GetScreenWidth()) position = 0; + + timeCounter += deltaTime; // We count time (seconds) + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + for (int i = 0; i < GetScreenWidth()/200; i++) DrawRectangle(200*i, 0, 1, GetScreenHeight(), SKYBLUE); + + DrawCircle((int)position, GetScreenHeight()/2 - 25, 50, RED); + + DrawText(FormatText("%03.0f ms", timeCounter*1000.0f), position - 40, GetScreenHeight()/2 - 100, 20, MAROON); + DrawText(FormatText("PosX: %03.0f", position), position - 50, GetScreenHeight()/2 + 40, 20, BLACK); + + DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY); + DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 30, 20, GRAY); + DrawText(FormatText("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME); + DrawText(FormatText("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); + + EndDrawing(); + + // NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL, + // Events polling, screen buffer swap and frame time control must be managed by the user + + SwapScreenBuffer(); // Flip the back buffer to screen (front buffer) + + currentTime = GetTime(); + updateDrawTime = currentTime - previousTime; + + if (targetFPS > 0) // We want a fixed frame rate + { + waitTime = (1.0f/(float)targetFPS) - updateDrawTime; + if (waitTime > 0.0) + { + WaitTime((float)waitTime*1000.0f); + currentTime = GetTime(); + deltaTime = (float)(currentTime - previousTime); + } + } + else deltaTime = updateDrawTime; // Framerate could be variable + + previousTime = currentTime; + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core/core_custom_frame_control.png b/examples/core/core_custom_frame_control.png new file mode 100644 index 0000000000000000000000000000000000000000..7d615efe29c0e9561453344a33650c269810373d GIT binary patch literal 16952 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 omdKI;Vst01YR?-T(jq literal 0 HcmV?d00001