[wpigui] Add wpigui wrappers for GLFW+imgui

These hide the platform specifics behind a common C++ API.  Platforms:
 - Windows: DirectX 11 (with 10 backwards compatibility)
 - Linux: OpenGL 3
 - Mac: Metal
This commit is contained in:
Peter Johnson
2020-08-25 23:52:09 -07:00
parent 148f43b4a5
commit b80fde4388
17 changed files with 1349 additions and 2 deletions

View File

@@ -0,0 +1,151 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <functional>
#include <imgui.h>
extern "C" struct GLFWwindow;
namespace wpi::gui {
/**
* Creates GUI context. Must be called prior to calling any other functions.
*/
void CreateContext();
/**
* Destroys GUI context.
*/
void DestroyContext();
/**
* Initializes the GUI.
*
* @param title main application window title
* @param width main application window width
* @param height main application window height
*/
bool Initialize(const char* title, int width, int height);
/**
* Runs main GUI loop. On some OS'es this must be called from the main thread.
* Does not return until Exit() is called.
*/
void Main();
/**
* Exits main GUI loop when current loop iteration finishes.
* Safe to call from any thread, including from within main GUI loop.
*/
void Exit();
/**
* Adds initializer to GUI. The passed function is called once, immediately
* after the GUI (both GLFW and Dear ImGui) are initialized in Initialize().
* To have any effect, must be called prior to Initialize().
*
* @param initialize initialization function
*/
void AddInit(std::function<void()> initialize);
/**
* Adds window scaler function. The passed function is called once during
* Initialize() if the window scale is not 1.0. To have any effect, must
* be called prior to Initialize().
*
* @param windowScaler window scaler function
*/
void AddWindowScaler(std::function<void(float scale)> windowScaler);
/**
* Adds per-frame executor to GUI. The passed function is called on each
* Dear ImGui frame prior to any of the late execute functions.
*
* @param execute frame execution function
*/
void AddEarlyExecute(std::function<void()> execute);
/**
* Adds per-frame executor to GUI. The passed function is called on each
* Dear ImGui frame after all of the early execute functions.
*
* @param execute frame execution function
*/
void AddLateExecute(std::function<void()> execute);
/**
* Gets GLFW window handle.
*/
GLFWwindow* GetSystemWindow();
/**
* Adds a font to the GUI. The passed function is called during
* initialization as many times as necessary to create a range of sizes.
*
* @param name font name
* @param makeFont font creation / loader function
* @return Font index for later use with GetFont()
*/
int AddFont(
const char* name,
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
makeFont);
/**
* Gets a font added with AddFont() with the appropriate font size for
* the current scaling of the GUI.
*
* @param font font index returned by AddFont()
* @return Font pointer
*/
ImFont* GetFont(int font);
enum Style { kStyleClassic = 0, kStyleDark, kStyleLight };
/**
* Sets the ImGui style. Using this function makes this setting persistent.
*
* @param style Style
*/
void SetStyle(Style style);
/**
* Sets the clear (background) color.
*
* @param color Color
*/
void SetClearColor(ImVec4 color);
/**
* Emits a View menu (e.g. for a main menu bar) that allows setting of
* style and zoom. Internally starts with ImGui::BeginMenu("View").
*/
void EmitViewMenu();
/**
* Loads a texture from a file.
*
* @param filename filename
* @param out_texture texture (output)
* @param out_width image width (output)
* @param out_height image height (output)
* @return True on success, false on failure.
*/
bool LoadTextureFromFile(const char* filename, ImTextureID* out_texture,
int* out_width, int* out_height);
/**
* Deletes a texture.
*
* @param texture texture
*/
void DeleteTexture(ImTextureID texture);
} // namespace wpi::gui

View File

@@ -0,0 +1,73 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <atomic>
#include <functional>
#include <string>
#include <utility>
#include <vector>
#include <GLFW/glfw3.h>
#include <imgui.h>
namespace wpi::gui {
struct SavedSettings {
bool loadedWidthHeight = false;
int width;
int height;
int maximized = 0;
int xPos = -1;
int yPos = -1;
int userScale = 2;
int style = 0;
};
struct Font {
static constexpr int kScaledLevels = 9;
ImFont* scaled[kScaledLevels];
};
struct Context : public SavedSettings {
std::atomic_bool exit{false};
std::string title;
int defaultWidth;
int defaultHeight;
GLFWwindow* window = nullptr;
std::vector<std::function<void()>> initializers;
std::vector<std::function<void(float scale)>> windowScalers;
std::vector<std::pair<
const char*,
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>>>
makeFonts;
ImVec4 clearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
std::vector<std::function<void()>> earlyExecutors;
std::vector<std::function<void()>> lateExecutors;
int fontScale = 2; // updated by main loop
std::vector<Font> fonts;
};
extern Context* gContext;
void PlatformCreateContext();
void PlatformDestroyContext();
void PlatformGlfwInitHints();
void PlatformGlfwWindowHints();
bool PlatformInitRenderer();
void PlatformRenderFrame();
void PlatformShutdown();
void CommonRenderFrame();
} // namespace wpi::gui