mirror of
https://github.com/ocornut/imgui.git
synced 2026-09-28 16:13:07 +08:00
Merge branch 'master' into context
This commit is contained in:
@@ -22,6 +22,11 @@ void DebugHUD_InitDefaults( DebugHUD *hud )
|
||||
hud->cubeColor2[1] = 0.4f;
|
||||
hud->cubeColor2[2] = 0.4f;
|
||||
hud->cubeColor2[3] = 1.0f;
|
||||
|
||||
hud->clearColor[0] = 0.45f;
|
||||
hud->clearColor[1] = 0.55f;
|
||||
hud->clearColor[2] = 0.60f;
|
||||
hud->clearColor[3] = 1.00f;
|
||||
}
|
||||
|
||||
void DebugHUD_DoInterface(DebugHUD *hud)
|
||||
@@ -33,7 +38,7 @@ void DebugHUD_DoInterface(DebugHUD *hud)
|
||||
static int counter = 0;
|
||||
ImGui::Text("Hello, world!"); // Display some text (you can use a format string too)
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||
ImGui::ColorEdit3("clear color", hud->clearColor); // Edit 3 floats representing a color
|
||||
|
||||
ImGui::Checkbox("Demo Window", &hud->show_demo_window); // Edit bools storing our windows open/close state
|
||||
ImGui::Checkbox("Another Window", &hud->show_another_window);
|
||||
@@ -49,7 +54,7 @@ void DebugHUD_DoInterface(DebugHUD *hud)
|
||||
// 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows.
|
||||
if (hud->show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &hud-?show_another_window);
|
||||
ImGui::Begin("Another Window", &hud->show_another_window);
|
||||
ImGui::Text("Hello from another window!");
|
||||
ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1);
|
||||
ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2);
|
||||
|
||||
@@ -11,6 +11,7 @@ typedef struct DebugHUD
|
||||
float rotation_speed;
|
||||
float cubeColor1[4];
|
||||
float cubeColor2[4];
|
||||
float clearColor[4];
|
||||
} DebugHUD;
|
||||
|
||||
#if __cplusplus
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "imgui_impl_sdl_gl2.h"
|
||||
|
||||
// Data
|
||||
static double g_Time = 0.0f;
|
||||
static Uint64 g_Time = 0;
|
||||
static bool g_MousePressed[3] = { false, false, false };
|
||||
static GLuint g_FontTexture = 0;
|
||||
|
||||
@@ -152,7 +152,8 @@ bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event)
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK;
|
||||
int key = event->key.keysym.scancode;
|
||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
||||
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
|
||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
||||
@@ -203,8 +204,9 @@ void ImGui_ImplSdlGL2_InvalidateDeviceObjects()
|
||||
|
||||
bool ImGui_ImplSdlGL2_Init(SDL_Window* window)
|
||||
{
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
|
||||
@@ -214,16 +216,16 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window)
|
||||
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = SDLK_a;
|
||||
io.KeyMap[ImGuiKey_C] = SDLK_c;
|
||||
io.KeyMap[ImGuiKey_V] = SDLK_v;
|
||||
io.KeyMap[ImGuiKey_X] = SDLK_x;
|
||||
io.KeyMap[ImGuiKey_Y] = SDLK_y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDLK_z;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
||||
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
|
||||
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
||||
|
||||
io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
|
||||
io.SetClipboardTextFn = ImGui_ImplSdlGL2_SetClipboardText;
|
||||
@@ -262,10 +264,10 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window)
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
|
||||
|
||||
// Setup time step
|
||||
Uint32 time = SDL_GetTicks();
|
||||
double current_time = time / 1000.0;
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
|
||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||
Uint64 current_time = SDL_GetPerformanceCounter();
|
||||
io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
// Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler)
|
||||
|
||||
@@ -31,6 +31,7 @@ int main(int, char**)
|
||||
SDL_GetCurrentDisplayMode(0, ¤t);
|
||||
SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
||||
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
|
||||
// Setup ImGui binding
|
||||
ImGui::CreateContext();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <GL/gl3w.h> // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you.
|
||||
|
||||
// Data
|
||||
static double g_Time = 0.0f;
|
||||
static Uint64 g_Time = 0.0f;
|
||||
static bool g_MousePressed[3] = { false, false, false };
|
||||
static GLuint g_FontTexture = 0;
|
||||
static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
||||
@@ -174,7 +174,8 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event)
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK;
|
||||
int key = event->key.keysym.scancode;
|
||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
||||
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
|
||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
||||
@@ -314,8 +315,9 @@ void ImGui_ImplSdlGL3_InvalidateDeviceObjects()
|
||||
|
||||
bool ImGui_ImplSdlGL3_Init(SDL_Window* window)
|
||||
{
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
|
||||
@@ -325,16 +327,16 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window)
|
||||
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = SDLK_a;
|
||||
io.KeyMap[ImGuiKey_C] = SDLK_c;
|
||||
io.KeyMap[ImGuiKey_V] = SDLK_v;
|
||||
io.KeyMap[ImGuiKey_X] = SDLK_x;
|
||||
io.KeyMap[ImGuiKey_Y] = SDLK_y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDLK_z;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
||||
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
|
||||
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
||||
|
||||
io.RenderDrawListsFn = ImGui_ImplSdlGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
|
||||
io.SetClipboardTextFn = ImGui_ImplSdlGL3_SetClipboardText;
|
||||
@@ -373,10 +375,10 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window)
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
|
||||
|
||||
// Setup time step
|
||||
Uint32 time = SDL_GetTicks();
|
||||
double current_time = time / 1000.0;
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
|
||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||
Uint64 current_time = SDL_GetPerformanceCounter();
|
||||
io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
// Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler)
|
||||
|
||||
@@ -30,6 +30,7 @@ int main(int, char**)
|
||||
SDL_GetCurrentDisplayMode(0, ¤t);
|
||||
SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
||||
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
gl3wInit();
|
||||
|
||||
// Setup ImGui binding
|
||||
|
||||
@@ -113,6 +113,7 @@ struct ImVec2
|
||||
float x, y;
|
||||
ImVec2() { x = y = 0.0f; }
|
||||
ImVec2(float _x, float _y) { x = _x; y = _y; }
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return *(&x + idx); } // We very rarely use this [] operator, thus an assert is fine.
|
||||
#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2.
|
||||
IM_VEC2_CLASS_EXTRA
|
||||
#endif
|
||||
@@ -870,6 +871,7 @@ struct ImGuiStyle
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered.
|
||||
ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows.
|
||||
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU.
|
||||
bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
|
||||
+12
-3
@@ -1051,9 +1051,10 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
if (ImGui::TreeNode("Child regions"))
|
||||
{
|
||||
static bool disable_mouse_wheel = false;
|
||||
static bool disable_menu = false;
|
||||
ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel);
|
||||
ImGui::Checkbox("Disable Menu", &disable_menu);
|
||||
|
||||
ImGui::Text("Without border");
|
||||
static int line = 50;
|
||||
bool goto_line = ImGui::Button("Goto");
|
||||
ImGui::SameLine();
|
||||
@@ -1080,8 +1081,16 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
// Child 2: rounded border
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f);
|
||||
ImGui::BeginChild("Child2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0));
|
||||
ImGui::Text("With border");
|
||||
ImGui::BeginChild("Child2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0) | (disable_menu ? 0 : ImGuiWindowFlags_MenuBar));
|
||||
if (!disable_menu && ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Menu"))
|
||||
{
|
||||
ShowExampleMenuFile();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::Columns(2);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
|
||||
+22
-9
@@ -45,6 +45,7 @@ struct ImGuiWindowSettings;
|
||||
typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_
|
||||
typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_
|
||||
typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_
|
||||
typedef int ImGuiItemStatusFlags; // flags: storage for DC.LastItemXXX // enum ImGuiItemStatusFlags_
|
||||
typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_
|
||||
typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_
|
||||
|
||||
@@ -216,6 +217,13 @@ enum ImGuiSeparatorFlags_
|
||||
ImGuiSeparatorFlags_Vertical = 1 << 1
|
||||
};
|
||||
|
||||
// Storage for LastItem data
|
||||
enum ImGuiItemStatusFlags_
|
||||
{
|
||||
ImGuiItemStatusFlags_HoveredRect = 1 << 0,
|
||||
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1
|
||||
};
|
||||
|
||||
// FIXME: this is in development, not exposed/functional as a generic feature yet.
|
||||
enum ImGuiLayoutType_
|
||||
{
|
||||
@@ -285,6 +293,7 @@ struct IMGUI_API ImRect
|
||||
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
||||
void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; }
|
||||
void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); }
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
bool IsFinite() const { return Min.x != FLT_MAX; }
|
||||
};
|
||||
|
||||
@@ -675,6 +684,7 @@ struct ImGuiContext
|
||||
};
|
||||
|
||||
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
|
||||
// This is going to be exposed in imgui.h when stabilized enough.
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true
|
||||
@@ -701,8 +711,9 @@ struct IMGUI_API ImGuiDrawContext
|
||||
float LogLinePosY;
|
||||
int TreeDepth;
|
||||
ImGuiID LastItemId;
|
||||
ImRect LastItemRect;
|
||||
bool LastItemRectHoveredRect;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect; // Interaction rect
|
||||
ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect)
|
||||
bool MenuBarAppending;
|
||||
float MenuBarOffsetX;
|
||||
ImVector<ImGuiWindow*> ChildWindows;
|
||||
@@ -732,8 +743,8 @@ struct IMGUI_API ImGuiDrawContext
|
||||
LogLinePosY = -1.0f;
|
||||
TreeDepth = 0;
|
||||
LastItemId = 0;
|
||||
LastItemRect = ImRect();
|
||||
LastItemRectHoveredRect = false;
|
||||
LastItemStatusFlags = 0;
|
||||
LastItemRect = LastItemDisplayRect = ImRect();
|
||||
MenuBarAppending = false;
|
||||
MenuBarOffsetX = 0.0f;
|
||||
StateStorage = NULL;
|
||||
@@ -840,13 +851,14 @@ public:
|
||||
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
|
||||
struct ImGuiItemHoveredDataBackup
|
||||
{
|
||||
ImGuiID LastItemId;
|
||||
ImRect LastItemRect;
|
||||
bool LastItemRectHoveredRect;
|
||||
ImGuiID LastItemId;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect;
|
||||
ImRect LastItemDisplayRect;
|
||||
|
||||
ImGuiItemHoveredDataBackup() { Backup(); }
|
||||
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; }
|
||||
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; }
|
||||
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemStatusFlags = window->DC.LastItemStatusFlags; LastItemRect = window->DC.LastItemRect; LastItemDisplayRect = window->DC.LastItemDisplayRect; }
|
||||
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -898,6 +910,7 @@ namespace ImGui
|
||||
|
||||
IMGUI_API void OpenPopupEx(ImGuiID id);
|
||||
IMGUI_API void ClosePopup(ImGuiID id);
|
||||
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window);
|
||||
IMGUI_API bool IsPopupOpen(ImGuiID id);
|
||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
|
||||
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
|
||||
|
||||
@@ -120,9 +120,7 @@ In this document:
|
||||
|
||||
Dear Imgui uses stb_truetype.h to rasterize fonts (with optional oversampling).
|
||||
This technique and implementation are not ideal for fonts rendered at _small sizes_, which may appear a little blurry.
|
||||
There is an implementation of the ImFontAtlas builder using FreeType that you can use:
|
||||
|
||||
https://github.com/ocornut/imgui_club
|
||||
There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder.
|
||||
|
||||
FreeType supports auto-hinting which tends to improve the readability of small fonts.
|
||||
Note that this code currently creates textures that are unoptimally too large (could be fixed with some work)
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
# imgui_freetype
|
||||
|
||||
This is an attempt to replace stb_truetype (the default imgui's font rasterizer) with FreeType.
|
||||
Currently not optimal and probably has some limitations or bugs.
|
||||
By [Vuhdo](https://github.com/Vuhdo) (Aleksei Skriabin). Improvements by @mikesart. Maintained by @ocornut.
|
||||
|
||||
**Usage**
|
||||
1. Get latest FreeType binaries or build yourself.
|
||||
2. Add imgui_freetype.h/cpp alongside your imgui sources.
|
||||
3. Include imgui_freetype.h after imgui.h.
|
||||
4. Call ImGuiFreeType::BuildFontAtlas() *BEFORE* calling ImFontAtlas::GetTexDataAsRGBA32() or ImFontAtlas::Build() (so normal Build() won't be called):
|
||||
|
||||
```cpp
|
||||
// See ImGuiFreeType::RasterizationFlags
|
||||
unsigned int flags = ImGuiFreeType::DisableHinting;
|
||||
ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
```
|
||||
|
||||
**Gamma Correct Blending**
|
||||
FreeType assumes blending in linear space rather than gamma space.
|
||||
See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph).
|
||||
For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
The default imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
**Test code Usage**
|
||||
```cpp
|
||||
#include "misc/freetype/imgui_freetype.h"
|
||||
#include "misc/freetype/imgui_freetype.cpp"
|
||||
|
||||
// Load various small fonts
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 13.0f);
|
||||
io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 13.0f);
|
||||
io.Fonts->AddFontDefault();
|
||||
|
||||
FreeTypeTest freetype_test;
|
||||
|
||||
// Main Loop
|
||||
while (true)
|
||||
{
|
||||
if (freetype_test.UpdateRebuild())
|
||||
{
|
||||
// REUPLOAD FONT TEXTURE TO GPU
|
||||
// e.g ImGui_ImplGlfwGL3_InvalidateDeviceObjects() + ImGui_ImplGlfwGL3_CreateDeviceObjects()
|
||||
}
|
||||
ImGui::NewFrame();
|
||||
freetype_test.ShowFreetypeOptionsWindow();
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Test code**
|
||||
```cpp
|
||||
#include "misc/freetype/imgui_freetype.h"
|
||||
#include "misc/freetype/imgui_freetype.cpp"
|
||||
|
||||
struct FreeTypeTest
|
||||
{
|
||||
enum FontBuildMode
|
||||
{
|
||||
FontBuildMode_FreeType,
|
||||
FontBuildMode_Stb,
|
||||
};
|
||||
|
||||
FontBuildMode BuildMode;
|
||||
bool WantRebuild;
|
||||
float FontsMultiply;
|
||||
unsigned int FontsFlags;
|
||||
|
||||
FreeTypeTest()
|
||||
{
|
||||
BuildMode = FontBuildMode_FreeType;
|
||||
WantRebuild = true;
|
||||
FontsMultiply = 1.0f;
|
||||
FontsFlags = 0;
|
||||
}
|
||||
|
||||
// Call _BEFORE_ NewFrame()
|
||||
bool UpdateRebuild()
|
||||
{
|
||||
if (!WantRebuild)
|
||||
return false;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
for (int n = 0; n < io.Fonts->Fonts.Size; n++)
|
||||
{
|
||||
io.Fonts->Fonts[n]->ConfigData->RasterizerMultiply = FontsMultiply;
|
||||
io.Fonts->Fonts[n]->ConfigData->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
|
||||
}
|
||||
if (BuildMode == FontBuildMode_FreeType)
|
||||
ImGuiFreeType::BuildFontAtlas(io.Fonts, FontsFlags);
|
||||
else if (BuildMode == FontBuildMode_Stb)
|
||||
io.Fonts->Build();
|
||||
WantRebuild = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Call to draw interface
|
||||
void ShowFreetypeOptionsWindow()
|
||||
{
|
||||
ImGui::Begin("FreeType Options");
|
||||
ImGui::ShowFontSelector("Fonts");
|
||||
WantRebuild |= ImGui::RadioButton("FreeType", (int*)&BuildMode, FontBuildMode_FreeType);
|
||||
ImGui::SameLine();
|
||||
WantRebuild |= ImGui::RadioButton("Stb (Default)", (int*)&BuildMode, FontBuildMode_Stb);
|
||||
WantRebuild |= ImGui::DragFloat("Multiply", &FontsMultiply, 0.001f, 0.0f, 2.0f);
|
||||
if (BuildMode == FontBuildMode_FreeType)
|
||||
{
|
||||
WantRebuild |= ImGui::CheckboxFlags("NoHinting", &FontsFlags, ImGuiFreeType::NoHinting);
|
||||
WantRebuild |= ImGui::CheckboxFlags("NoAutoHint", &FontsFlags, ImGuiFreeType::NoAutoHint);
|
||||
WantRebuild |= ImGui::CheckboxFlags("ForceAutoHint", &FontsFlags, ImGuiFreeType::ForceAutoHint);
|
||||
WantRebuild |= ImGui::CheckboxFlags("LightHinting", &FontsFlags, ImGuiFreeType::LightHinting);
|
||||
WantRebuild |= ImGui::CheckboxFlags("MonoHinting", &FontsFlags, ImGuiFreeType::MonoHinting);
|
||||
WantRebuild |= ImGui::CheckboxFlags("Bold", &FontsFlags, ImGuiFreeType::Bold);
|
||||
WantRebuild |= ImGui::CheckboxFlags("Oblique", &FontsFlags, ImGuiFreeType::Oblique);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Known issues**
|
||||
- Output texture has excessive resolution (lots of vertical waste)
|
||||
- FreeType's memory allocator is not overridden.
|
||||
|
||||
**Obligatory comparison screenshots**
|
||||
|
||||
Using Windows built-in segoeui.ttf font. Open in new browser tabs, view at 1080p+.
|
||||
|
||||

|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
// Wrapper to use Freetype (instead of stb_truetype) for Dear ImGui
|
||||
// Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
|
||||
// Original code by @Vuhdo (Aleksei Skriabin), maintained by @ocornut
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h" // IMGUI_API, ImFontAtlas
|
||||
|
||||
namespace ImGuiFreeType
|
||||
{
|
||||
// Hinting greatly impacts visuals (and glyph sizes).
|
||||
// When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output.
|
||||
// The Default hinting mode usually looks good, but may distort glyphs in an unusual way.
|
||||
// The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer.
|
||||
|
||||
// You can set those flags on a per font basis in ImFontConfig::RasterizerFlags.
|
||||
// Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts.
|
||||
enum RasterizerFlags
|
||||
{
|
||||
// By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter.
|
||||
NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.
|
||||
NoAutoHint = 1 << 1, // Disable auto-hinter.
|
||||
ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter.
|
||||
LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
|
||||
MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output.
|
||||
Bold = 1 << 5, // Styling: Should we artificially embolden the font?
|
||||
Oblique = 1 << 6 // Styling: Should we slant the font, emulating italic style?
|
||||
};
|
||||
|
||||
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
|
||||
}
|
||||
@@ -33,8 +33,7 @@
|
||||
</Type>
|
||||
|
||||
<Type Name="ImGuiWindow">
|
||||
<DisplayString Condition="Active||WasActive">{{Name={Name,s}}}</DisplayString>
|
||||
<DisplayString Condition="!(Active||WasActive)">{{Name={Name,s}} Inactive}</DisplayString>
|
||||
<DisplayString>{{Name={Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags & 0x01000000)?1:0,d} Popup {(Flags & 0x04000000)?1:0,d}}</DisplayString>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
||||
Reference in New Issue
Block a user