mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
ImDrawList: Small refactor toward removing dependency on GImGui + PushClipRectFullscreen now correctly uses data provided by imgui which can takes account of DisplaySize + Removed static variable in PathArcToFast() which caused linking issues to some.
This commit is contained in:
parent
230f826ef5
commit
531c11d5c7
25
imgui.cpp
25
imgui.cpp
@ -1818,7 +1818,7 @@ bool ImGuiListClipper::Step()
|
||||
// ImGuiWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiWindow::ImGuiWindow(const char* name)
|
||||
ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
{
|
||||
Name = ImStrdup(name);
|
||||
ID = ImHash(name, 0);
|
||||
@ -1859,7 +1859,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
||||
FontWindowScale = 1.0f;
|
||||
|
||||
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
|
||||
IM_PLACEMENT_NEW(DrawList) ImDrawList();
|
||||
IM_PLACEMENT_NEW(DrawList) ImDrawList(&context->DrawListSharedData);
|
||||
DrawList->_OwnerName = Name;
|
||||
ParentWindow = NULL;
|
||||
RootWindow = NULL;
|
||||
@ -2254,6 +2254,11 @@ ImDrawList* ImGui::GetOverlayDrawList()
|
||||
return &GImGui->OverlayDrawList;
|
||||
}
|
||||
|
||||
ImDrawListSharedData* ImGui::GetDrawListSharedData()
|
||||
{
|
||||
return &GImGui->DrawListSharedData;
|
||||
}
|
||||
|
||||
void ImGui::NewFrame()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -2274,6 +2279,8 @@ void ImGui::NewFrame()
|
||||
|
||||
SetCurrentFont(GetDefaultFont());
|
||||
IM_ASSERT(g.Font->IsLoaded());
|
||||
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
|
||||
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
|
||||
|
||||
g.Time += g.IO.DeltaTime;
|
||||
g.FrameCount += 1;
|
||||
@ -4145,7 +4152,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
|
||||
// Create window the first time
|
||||
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
|
||||
IM_PLACEMENT_NEW(window) ImGuiWindow(name);
|
||||
IM_PLACEMENT_NEW(window) ImGuiWindow(&g, name);
|
||||
window->Flags = flags;
|
||||
g.WindowsById.SetVoidPtr(window->ID, window);
|
||||
|
||||
@ -5243,7 +5250,11 @@ static void SetCurrentFont(ImFont* font)
|
||||
g.Font = font;
|
||||
g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale;
|
||||
g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
|
||||
g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel;
|
||||
|
||||
ImFontAtlas* atlas = g.Font->ContainerAtlas;
|
||||
g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
|
||||
g.DrawListSharedData.Font = g.Font;
|
||||
g.DrawListSharedData.FontSize = g.FontSize;
|
||||
}
|
||||
|
||||
void ImGui::PushFont(ImFont* font)
|
||||
@ -5820,7 +5831,7 @@ float ImGui::GetFontSize()
|
||||
|
||||
ImVec2 ImGui::GetFontTexUvWhitePixel()
|
||||
{
|
||||
return GImGui->FontTexUvWhitePixel;
|
||||
return GImGui->DrawListSharedData.TexUvWhitePixel;
|
||||
}
|
||||
|
||||
void ImGui::SetWindowFontScale(float scale)
|
||||
@ -10489,7 +10500,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 uv_white = g.FontTexUvWhitePixel;
|
||||
ImVec2 uv_white = GetFontTexUvWhitePixel();
|
||||
draw_list->PrimReserve(6, 6);
|
||||
draw_list->PrimVtx(tra, uv_white, hue_color32);
|
||||
draw_list->PrimVtx(trb, uv_white, hue_color32);
|
||||
@ -11609,7 +11620,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
return;
|
||||
|
||||
ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list
|
||||
overlay_draw_list->PushClipRectFullScreen();
|
||||
int elem_offset = 0;
|
||||
for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
|
||||
{
|
||||
@ -11652,7 +11662,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
overlay_draw_list->PopClipRect();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
|
7
imgui.h
7
imgui.h
@ -50,6 +50,7 @@ struct ImDrawChannel; // Temporary storage for outputting drawing
|
||||
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call)
|
||||
struct ImDrawData; // All draw command lists required to render the frame
|
||||
struct ImDrawList; // A single draw command list (generally one per window)
|
||||
struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself)
|
||||
struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
|
||||
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
|
||||
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
|
||||
@ -466,6 +467,7 @@ namespace ImGui
|
||||
IMGUI_API float GetTime();
|
||||
IMGUI_API int GetFrameCount();
|
||||
IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text
|
||||
IMGUI_API ImDrawListSharedData* GetDrawListSharedData();
|
||||
IMGUI_API const char* GetStyleColorName(ImGuiCol idx);
|
||||
IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items
|
||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
@ -1325,7 +1327,7 @@ struct ImDrawCmd
|
||||
ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
||||
void* UserCallbackData; // The draw callback code can access this.
|
||||
|
||||
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }
|
||||
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }
|
||||
};
|
||||
|
||||
// Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h)
|
||||
@ -1384,6 +1386,7 @@ struct ImDrawList
|
||||
ImVector<ImDrawVert> VtxBuffer; // Vertex buffer.
|
||||
|
||||
// [Internal, used while building lists]
|
||||
const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
|
||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||
unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size
|
||||
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||
@ -1395,7 +1398,7 @@ struct ImDrawList
|
||||
int _ChannelsCount; // [Internal] number of active channels (1+)
|
||||
ImVector<ImDrawChannel> _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
|
||||
|
||||
ImDrawList() { _OwnerName = NULL; Clear(); }
|
||||
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); }
|
||||
~ImDrawList() { ClearFreeMemory(); }
|
||||
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
||||
IMGUI_API void PushClipRectFullScreen();
|
||||
|
@ -277,10 +277,27 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawList
|
||||
// ImDrawListData
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
Font = NULL;
|
||||
FontSize = 0.0f;
|
||||
CurveTessellationTol = 0.0f;
|
||||
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
|
||||
|
||||
// Const data
|
||||
for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12);
|
||||
CircleVtx12[i] = ImVec2(cosf(a), sinf(a));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawList
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImDrawList::Clear()
|
||||
{
|
||||
@ -321,7 +338,7 @@ void ImDrawList::ClearFreeMemory()
|
||||
}
|
||||
|
||||
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
|
||||
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect)
|
||||
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
|
||||
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL)
|
||||
|
||||
void ImDrawList::AddDrawCmd()
|
||||
@ -412,8 +429,7 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_
|
||||
|
||||
void ImDrawList::PushClipRectFullScreen()
|
||||
{
|
||||
PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w));
|
||||
//PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here?
|
||||
PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w));
|
||||
}
|
||||
|
||||
void ImDrawList::PopClipRect()
|
||||
@ -533,7 +549,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
|
||||
// Fully unrolled with inline call to keep our debug builds decently fast.
|
||||
void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col)
|
||||
{
|
||||
ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel);
|
||||
ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel);
|
||||
ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx;
|
||||
_IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2);
|
||||
_IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3);
|
||||
@ -581,7 +597,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
if (points_count < 2)
|
||||
return;
|
||||
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
anti_aliased &= GImGui->Style.AntiAliasedLines;
|
||||
//if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug
|
||||
|
||||
@ -759,7 +775,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
|
||||
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased)
|
||||
{
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
anti_aliased &= GImGui->Style.AntiAliasedShapes;
|
||||
//if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug
|
||||
|
||||
@ -842,20 +858,6 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
||||
|
||||
void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12)
|
||||
{
|
||||
static ImVec2 circle_vtx[12];
|
||||
static bool circle_vtx_builds = false;
|
||||
const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx);
|
||||
if (!circle_vtx_builds)
|
||||
{
|
||||
for (int i = 0; i < circle_vtx_count; i++)
|
||||
{
|
||||
const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI;
|
||||
circle_vtx[i].x = cosf(a);
|
||||
circle_vtx[i].y = sinf(a);
|
||||
}
|
||||
circle_vtx_builds = true;
|
||||
}
|
||||
|
||||
if (radius == 0.0f || a_min_of_12 > a_max_of_12)
|
||||
{
|
||||
_Path.push_back(centre);
|
||||
@ -864,7 +866,7 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_
|
||||
_Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1));
|
||||
for (int a = a_min_of_12; a <= a_max_of_12; a++)
|
||||
{
|
||||
const ImVec2& c = circle_vtx[a % circle_vtx_count];
|
||||
const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)];
|
||||
_Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius));
|
||||
}
|
||||
}
|
||||
@ -916,7 +918,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV
|
||||
if (num_segments == 0)
|
||||
{
|
||||
// Auto-tessellated
|
||||
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, GImGui->Style.CurveTessellationTol, 0);
|
||||
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -998,7 +1000,7 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32
|
||||
if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
PrimReserve(6, 4);
|
||||
PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2));
|
||||
PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3));
|
||||
@ -1094,12 +1096,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
||||
if (text_begin == text_end)
|
||||
return;
|
||||
|
||||
// IMPORTANT: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful.
|
||||
// Might just move Font/FontSize to ImDrawList?
|
||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||
if (font == NULL)
|
||||
font = GImGui->Font;
|
||||
font = _Data->Font;
|
||||
if (font_size == 0.0f)
|
||||
font_size = GImGui->FontSize;
|
||||
font_size = _Data->FontSize;
|
||||
|
||||
IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
|
||||
|
||||
|
@ -453,6 +453,21 @@ struct ImGuiColumnsSet
|
||||
}
|
||||
};
|
||||
|
||||
struct ImDrawListSharedData
|
||||
{
|
||||
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
|
||||
ImFont* Font; // Current/default font (optional, for simplified AddText overload)
|
||||
float FontSize; // Current/default font size (optional, for simplified AddText overload)
|
||||
float CurveTessellationTol;
|
||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||
|
||||
// Const data
|
||||
// FIXME: Bake rounded corners fill/borders in atlas
|
||||
ImVec2 CircleVtx12[12];
|
||||
|
||||
ImDrawListSharedData();
|
||||
};
|
||||
|
||||
// Main state for ImGui
|
||||
struct ImGuiContext
|
||||
{
|
||||
@ -462,7 +477,7 @@ struct ImGuiContext
|
||||
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
||||
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
||||
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
|
||||
ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel
|
||||
ImDrawListSharedData DrawListSharedData;
|
||||
|
||||
float Time;
|
||||
int FrameCount;
|
||||
@ -574,12 +589,11 @@ struct ImGuiContext
|
||||
int WantTextInputNextFrame;
|
||||
char TempBuffer[1024*3+1]; // temporary text buffer
|
||||
|
||||
ImGuiContext()
|
||||
ImGuiContext() : OverlayDrawList(NULL)
|
||||
{
|
||||
Initialized = false;
|
||||
Font = NULL;
|
||||
FontSize = FontBaseSize = 0.0f;
|
||||
FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
|
||||
Time = 0.0f;
|
||||
FrameCount = 0;
|
||||
@ -639,6 +653,7 @@ struct ImGuiContext
|
||||
OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f);
|
||||
|
||||
ModalWindowDarkeningRatio = 0.0f;
|
||||
OverlayDrawList._Data = &DrawListSharedData;
|
||||
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
memset(MouseCursorData, 0, sizeof(MouseCursorData));
|
||||
@ -805,7 +820,7 @@ struct IMGUI_API ImGuiWindow
|
||||
int FocusIdxTabRequestNext; // "
|
||||
|
||||
public:
|
||||
ImGuiWindow(const char* name);
|
||||
ImGuiWindow(ImGuiContext* context, const char* name);
|
||||
~ImGuiWindow();
|
||||
|
||||
ImGuiID GetID(const char* str, const char* str_end = NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user