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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 literal 0 HcmV?d00001