181 lines
12 KiB
C
181 lines
12 KiB
C
// dear imgui test engine
|
|
// (screen/video capture tool)
|
|
// This is usable as a standalone applet or controlled by the test engine.
|
|
|
|
#pragma once
|
|
|
|
#include "imgui_te_utils.h" // ImFuncPtr
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Forward declarations
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Our types
|
|
struct ImGuiCaptureArgs; // Parameters for Capture
|
|
struct ImGuiCaptureContext; // State of an active capture tool
|
|
struct ImGuiCaptureImageBuf; // Simple helper to store an RGBA image in memory
|
|
struct ImGuiCaptureToolUI; // Capture tool instance + UI window
|
|
|
|
typedef unsigned int ImGuiCaptureFlags; // See enum: ImGuiCaptureFlags_
|
|
|
|
// Capture function which needs to be provided by user application
|
|
typedef bool (ImGuiScreenCaptureFunc)(ImGuiID viewport_id, int x, int y, int w, int h, unsigned int* pixels, void* user_data);
|
|
|
|
// External types
|
|
struct ImGuiWindow; // imgui.h
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// [Internal]
|
|
// Helper class for simple bitmap manipulation (not particularly efficient!)
|
|
struct IMGUI_API ImGuiCaptureImageBuf
|
|
{
|
|
int Width;
|
|
int Height;
|
|
unsigned int* Data; // RGBA8
|
|
|
|
ImGuiCaptureImageBuf() { Width = Height = 0; Data = NULL; }
|
|
~ImGuiCaptureImageBuf() { Clear(); }
|
|
|
|
void Clear(); // Free allocated memory buffer if such exists.
|
|
void CreateEmpty(int w, int h); // Reallocate buffer for pixel data and zero it.
|
|
bool SaveFile(const char* filename); // Save pixel data to specified image file.
|
|
void RemoveAlpha(); // Clear alpha channel from all pixels.
|
|
};
|
|
|
|
enum ImGuiCaptureFlags_ : unsigned int
|
|
{
|
|
ImGuiCaptureFlags_None = 0,
|
|
ImGuiCaptureFlags_StitchAll = 1 << 0, // Capture entire window scroll area (by scrolling and taking multiple screenshot). Only works for a single window.
|
|
ImGuiCaptureFlags_IncludeOtherWindows = 1 << 1, // Disable hiding other windows (when CaptureAddWindow has been called by default other windows are hidden)
|
|
ImGuiCaptureFlags_IncludeTooltipsAndPopups = 1 << 2, // Expand capture area to automatically include visible popups and tooltips (use with ImGuiCaptureflags_HideOtherWindows)
|
|
ImGuiCaptureFlags_HideMouseCursor = 1 << 3, // Hide render software mouse cursor during capture.
|
|
ImGuiCaptureFlags_Instant = 1 << 4, // Perform capture on very same frame. Only works when capturing a rectangular region. Unsupported features: content stitching, window hiding, window relocation.
|
|
ImGuiCaptureFlags_NoSave = 1 << 5 // Do not save output image.
|
|
};
|
|
|
|
// Defines input and output arguments for capture process.
|
|
// When capturing from tests you can usually use the ImGuiTestContext::CaptureXXX() helpers functions.
|
|
struct ImGuiCaptureArgs
|
|
{
|
|
// [Input]
|
|
ImGuiCaptureFlags InFlags = 0; // Flags for customizing behavior of screenshot tool.
|
|
ImVector<ImGuiWindow*> InCaptureWindows; // Windows to capture. All other windows will be hidden. May be used with InCaptureRect to capture only some windows in specified rect.
|
|
ImRect InCaptureRect; // Screen rect to capture. Does not include padding.
|
|
float InPadding = 16.0f; // Extra padding at the edges of the screenshot. Ensure that there is available space around capture rect horizontally, also vertically if ImGuiCaptureFlags_StitchFullContents is not used.
|
|
char InOutputFile[256] = ""; // Output will be saved to a file if InOutputImageBuf is NULL.
|
|
ImGuiCaptureImageBuf* InOutputImageBuf = NULL; // _OR_ Output will be saved to image buffer if specified.
|
|
int InRecordFPSTarget = 30; // FPS target for recording videos.
|
|
int InSizeAlign = 0; // Resolution alignment (0 = auto, 1 = no alignment, >= 2 = align width/height to be multiple of given value)
|
|
|
|
// [Output]
|
|
ImVec2 OutImageSize; // Produced image size.
|
|
};
|
|
|
|
enum ImGuiCaptureStatus
|
|
{
|
|
ImGuiCaptureStatus_InProgress,
|
|
ImGuiCaptureStatus_Done,
|
|
ImGuiCaptureStatus_Error
|
|
};
|
|
|
|
struct ImGuiCaptureWindowData
|
|
{
|
|
ImGuiWindow* Window;
|
|
ImRect BackupRect;
|
|
ImVec2 PosDuringCapture;
|
|
};
|
|
|
|
// Implements functionality for capturing images
|
|
struct IMGUI_API ImGuiCaptureContext
|
|
{
|
|
// IO
|
|
ImFuncPtr(ImGuiScreenCaptureFunc) ScreenCaptureFunc = NULL; // Graphics backend specific function that captures specified portion of framebuffer and writes RGBA data to `pixels` buffer.
|
|
void* ScreenCaptureUserData = NULL; // Custom user pointer which is passed to ScreenCaptureFunc. (Optional)
|
|
char* VideoCaptureEncoderPath = NULL; // Video encoder path (not owned, stored externally).
|
|
int VideoCaptureEncoderPathSize = 0; // Optional. Set in order to edit this parameter from UI.
|
|
char* VideoCaptureEncoderParams = NULL; // Video encoder params (not owned, stored externally).
|
|
int VideoCaptureEncoderParamsSize = 0; // Optional. Set in order to edit this parameter from UI.
|
|
char* GifCaptureEncoderParams = NULL; // Video encoder params for GIF output (not owned, stored externally).
|
|
int GifCaptureEncoderParamsSize = 0; // Optional. Set in order to edit this parameter from UI.
|
|
|
|
// [Internal]
|
|
ImRect _CaptureRect; // Viewport rect that is being captured.
|
|
ImRect _CapturedWindowRect; // Top-left corner of region that covers all windows included in capture. This is not same as _CaptureRect.Min when capturing explicitly specified rect.
|
|
int _ChunkNo = 0; // Number of chunk that is being captured when capture spans multiple frames.
|
|
int _FrameNo = 0; // Frame number during capture process that spans multiple frames.
|
|
ImVec2 _MouseRelativeToWindowPos; // Mouse cursor position relative to captured window (when _StitchAll is in use).
|
|
ImGuiWindow* _HoveredWindow = NULL; // Window which was hovered at capture start.
|
|
ImGuiCaptureImageBuf _CaptureBuf; // Output image buffer.
|
|
const ImGuiCaptureArgs* _CaptureArgs = NULL; // Current capture args. Set only if capture is in progress.
|
|
ImVector<ImGuiCaptureWindowData> _WindowsData; // Backup windows that will have their rect modified and restored. args->InCaptureWindows can not be used because popups may get closed during capture and no longer appear in that list.
|
|
|
|
// [Internal] Video recording
|
|
bool _VideoRecording = false; // Flag indicating that video recording is in progress.
|
|
double _VideoLastFrameTime = 0; // Time when last video frame was recorded.
|
|
FILE* _VideoEncoderPipe = NULL; // File writing to stdin of video encoder process.
|
|
|
|
// [Internal] Backups
|
|
bool _BackupMouseDrawCursor = false; // Initial value of g.IO.MouseDrawCursor
|
|
ImVec2 _BackupDisplayWindowPadding; // Backup padding. We set it to {0, 0} during capture.
|
|
ImVec2 _BackupDisplaySafeAreaPadding; // Backup padding. We set it to {0, 0} during capture.
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Functions
|
|
//-------------------------------------------------------------------------
|
|
|
|
ImGuiCaptureContext(ImGuiScreenCaptureFunc capture_func = NULL) { ScreenCaptureFunc = capture_func; _MouseRelativeToWindowPos = ImVec2(-FLT_MAX, -FLT_MAX); }
|
|
|
|
// These functions should be called from appropriate context hooks. See ImGui::AddContextHook() for more info.
|
|
// (ImGuiTestEngine automatically calls that for you, so this only apply to independently created instance)
|
|
void PreNewFrame();
|
|
void PreRender();
|
|
void PostRender();
|
|
|
|
// Update capturing. If this function returns true then it should be called again with same arguments on the next frame.
|
|
ImGuiCaptureStatus CaptureUpdate(ImGuiCaptureArgs* args);
|
|
void RestoreBackedUpData();
|
|
void ClearState();
|
|
|
|
// Begin video capture. Call CaptureUpdate() every frame afterwards until it returns false.
|
|
void BeginVideoCapture(ImGuiCaptureArgs* args);
|
|
void EndVideoCapture();
|
|
bool IsCapturingVideo();
|
|
bool IsCapturing();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// ImGuiCaptureToolUI
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Implements UI for capturing images
|
|
// (when using ImGuiTestEngine scripting API you may not need to use this at all)
|
|
struct IMGUI_API ImGuiCaptureToolUI
|
|
{
|
|
float SnapGridSize = 32.0f; // Size of the grid cell for "snap to grid" functionality.
|
|
char OutputLastFilename[256] = ""; // File name of last captured file.
|
|
char* VideoCaptureExtension = NULL; // Video file extension (e.g. ".gif" or ".mp4")
|
|
int VideoCaptureExtensionSize = 0; // Optional. Set in order to edit this parameter from UI.
|
|
|
|
ImGuiCaptureArgs _CaptureArgs; // Capture args
|
|
bool _StateIsPickingWindow = false;
|
|
bool _StateIsCapturing = false;
|
|
ImVector<ImGuiID> _SelectedWindows;
|
|
char _OutputFileTemplate[256] = ""; //
|
|
int _FileCounter = 0; // Counter which may be appended to file name when saving. By default, counting starts from 1. When done this field holds number of saved files.
|
|
|
|
// Public
|
|
ImGuiCaptureToolUI();
|
|
void ShowCaptureToolWindow(ImGuiCaptureContext* context, bool* p_open = NULL); // Render a capture tool window with various options and utilities.
|
|
|
|
// [Internal]
|
|
void _CaptureWindowPicker(ImGuiCaptureArgs* args); // Render a window picker that captures picked window to file specified in file_name.
|
|
void _CaptureWindowsSelector(ImGuiCaptureContext* context, ImGuiCaptureArgs* args); // Render a selector for selecting multiple windows for capture.
|
|
void _SnapWindowsToGrid(float cell_size); // Snap edges of all visible windows to a virtual grid.
|
|
bool _InitializeOutputFile(); // Format output file template into capture args struct and ensure target directory exists.
|
|
bool _ShowEncoderConfigFields(ImGuiCaptureContext* context);
|
|
};
|
|
|
|
#define IMGUI_CAPTURE_DEFAULT_VIDEO_PARAMS_FOR_FFMPEG "-hide_banner -loglevel error -r $FPS -f rawvideo -pix_fmt rgba -s $WIDTHx$HEIGHT -i - -threads 0 -y -preset ultrafast -pix_fmt yuv420p -crf 20 $OUTPUT"
|
|
#define IMGUI_CAPTURE_DEFAULT_GIF_PARAMS_FOR_FFMPEG "-hide_banner -loglevel error -r $FPS -f rawvideo -pix_fmt rgba -s $WIDTHx$HEIGHT -i - -threads 0 -y -filter_complex \"split=2 [a] [b]; [a] palettegen [pal]; [b] [pal] paletteuse\" $OUTPUT"
|