|
@@ -2,12 +2,10 @@
|
|
|
*
|
|
*
|
|
|
* raylib [core] example - screen recording
|
|
* raylib [core] example - screen recording
|
|
|
*
|
|
*
|
|
|
-* Example complexity rating: [★☆☆☆] 1/4
|
|
|
|
|
|
|
+* Example complexity rating: [★★☆☆] 2/4
|
|
|
*
|
|
*
|
|
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
|
|
*
|
|
*
|
|
|
-* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
|
|
|
|
-*
|
|
|
|
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
|
|
* BSD-like license that allows static linking with closed source software
|
|
* BSD-like license that allows static linking with closed source software
|
|
|
*
|
|
*
|
|
@@ -17,6 +15,16 @@
|
|
|
|
|
|
|
|
#include "raylib.h"
|
|
#include "raylib.h"
|
|
|
|
|
|
|
|
|
|
+// Using msf_gif library to record frames into GIF
|
|
|
|
|
+#define MSF_GIF_IMPL
|
|
|
|
|
+#include "msf_gif.h" // GIF recording functionality
|
|
|
|
|
+
|
|
|
|
|
+#include <math.h> // Required for: sinf()
|
|
|
|
|
+
|
|
|
|
|
+#define GIF_RECORD_FRAMERATE 5 // Record framerate, we get a frame every N frames
|
|
|
|
|
+
|
|
|
|
|
+#define MAX_SINEWAVE_POINTS 256
|
|
|
|
|
+
|
|
|
//------------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------------
|
|
|
// Program main entry point
|
|
// Program main entry point
|
|
|
//------------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------------
|
|
@@ -29,7 +37,20 @@ int main(void)
|
|
|
|
|
|
|
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
|
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
|
|
|
|
|
|
|
|
- // TODO: Load resources / Initialize variables at this point
|
|
|
|
|
|
|
+ bool gifRecording = false; // GIF recording state
|
|
|
|
|
+ unsigned int gifFrameCounter = 0; // GIF frames counter
|
|
|
|
|
+ MsfGifState gifState = { 0 }; // MSGIF context state
|
|
|
|
|
+
|
|
|
|
|
+ Vector2 circlePosition = { 0.0f, screenHeight/2.0f };
|
|
|
|
|
+ float timeCounter = 0.0f;
|
|
|
|
|
+
|
|
|
|
|
+ // Get sine wave points for line drawing
|
|
|
|
|
+ Vector2 sinePoints[MAX_SINEWAVE_POINTS] = { 0 };
|
|
|
|
|
+ for (int i = 0; i < MAX_SINEWAVE_POINTS; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ sinePoints[i].x = i*GetScreenWidth()/180.0f;
|
|
|
|
|
+ sinePoints[i].y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*(1.0f/60.0f)*(float)i); // Calculate for 60 fps
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
SetTargetFPS(60);
|
|
SetTargetFPS(60);
|
|
|
//--------------------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------------------
|
|
@@ -39,7 +60,59 @@ int main(void)
|
|
|
{
|
|
{
|
|
|
// Update
|
|
// Update
|
|
|
//----------------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------------
|
|
|
- // TODO: Update variables / Implement example logic at this point
|
|
|
|
|
|
|
+ // Update circle sinusoidal movement
|
|
|
|
|
+ timeCounter += GetFrameTime();
|
|
|
|
|
+ circlePosition.x += GetScreenWidth()/180.0f;
|
|
|
|
|
+ circlePosition.y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*timeCounter);
|
|
|
|
|
+ if (circlePosition.x > screenWidth)
|
|
|
|
|
+ {
|
|
|
|
|
+ circlePosition.x = 0.0f;
|
|
|
|
|
+ circlePosition.y = screenHeight/2.0f;
|
|
|
|
|
+ timeCounter = 0.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Start-Stop GIF recording on CTRL+R
|
|
|
|
|
+ if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_R))
|
|
|
|
|
+ {
|
|
|
|
|
+ if (gifRecording)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Stop current recording and save file
|
|
|
|
|
+ gifRecording = false;
|
|
|
|
|
+ MsfGifResult result = msf_gif_end(&gifState);
|
|
|
|
|
+ SaveFileData(TextFormat("%s/screenrecording.gif", GetApplicationDirectory()), result.data, (unsigned int)result.dataSize);
|
|
|
|
|
+ msf_gif_free(result);
|
|
|
|
|
+
|
|
|
|
|
+ TraceLog(LOG_INFO, "Finish animated GIF recording");
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ // Start a new recording
|
|
|
|
|
+ gifRecording = true;
|
|
|
|
|
+ gifFrameCounter = 0;
|
|
|
|
|
+ msf_gif_begin(&gifState, GetRenderWidth(), GetRenderHeight());
|
|
|
|
|
+
|
|
|
|
|
+ TraceLog(LOG_INFO, "Start animated GIF recording");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (gifRecording)
|
|
|
|
|
+ {
|
|
|
|
|
+ gifFrameCounter++;
|
|
|
|
|
+
|
|
|
|
|
+ // NOTE: We record one gif frame depending on the desired gif framerate
|
|
|
|
|
+ if (gifFrameCounter > GIF_RECORD_FRAMERATE)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Get image data for the current frame (from backbuffer)
|
|
|
|
|
+ // WARNING: This process is quite slow, it can generate stuttering
|
|
|
|
|
+ Image imScreen = LoadImageFromScreen();
|
|
|
|
|
+
|
|
|
|
|
+ // Add the frame to the gif recording, providing and "estimated" time for display in centiseconds
|
|
|
|
|
+ msf_gif_frame(&gifState, imScreen.data, (int)((1.0f/60.0f)*GIF_RECORD_FRAMERATE)/10, 16, imScreen.width*4);
|
|
|
|
|
+ gifFrameCounter = 0;
|
|
|
|
|
+
|
|
|
|
|
+ UnloadImage(imScreen); // Free image data
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
//----------------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Draw
|
|
// Draw
|
|
@@ -48,20 +121,43 @@ int main(void)
|
|
|
|
|
|
|
|
ClearBackground(RAYWHITE);
|
|
ClearBackground(RAYWHITE);
|
|
|
|
|
|
|
|
- // TODO: Draw everything that requires to be drawn at this point
|
|
|
|
|
|
|
+ for (int i = 0; i < (MAX_SINEWAVE_POINTS - 1); i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ DrawLineV(sinePoints[i], sinePoints[i + 1], MAROON);
|
|
|
|
|
+ DrawCircleV(sinePoints[i], 3, MAROON);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DrawCircleV(circlePosition, 30, RED);
|
|
|
|
|
|
|
|
- DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
|
|
|
|
|
- DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
|
|
|
|
|
- DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
|
|
|
|
|
|
|
+ DrawFPS(10, 10);
|
|
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ // Draw record indicator
|
|
|
|
|
+ // WARNING: If drawn here, it will appear in the recorded image,
|
|
|
|
|
+ // use a render texture instead for the recording and LoadImageFromTexture(rt.texture)
|
|
|
|
|
+ if (gifRecording)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Display the recording indicator every half-second
|
|
|
|
|
+ if ((int)(GetTime()/0.5)%2 == 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ DrawCircle(30, GetScreenHeight() - 20, 10, MAROON);
|
|
|
|
|
+ DrawText("GIF RECORDING", 50, GetScreenHeight() - 25, 10, RED);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ */
|
|
|
EndDrawing();
|
|
EndDrawing();
|
|
|
//----------------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------------
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// De-Initialization
|
|
// De-Initialization
|
|
|
//--------------------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------------------
|
|
|
-
|
|
|
|
|
- // TODO: Unload all loaded resources at this point
|
|
|
|
|
|
|
+ // If still recording a GIF on close window, just finish
|
|
|
|
|
+ if (gifRecording)
|
|
|
|
|
+ {
|
|
|
|
|
+ MsfGifResult result = msf_gif_end(&gifState);
|
|
|
|
|
+ msf_gif_free(result);
|
|
|
|
|
+ gifRecording = false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
CloseWindow(); // Close window and OpenGL context
|
|
CloseWindow(); // Close window and OpenGL context
|
|
|
//--------------------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------------------
|