DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665)
This commit is contained in:
parent
f29e505d94
commit
98d52b7b26
@ -60,6 +60,14 @@ Other changes:
|
|||||||
- IO: added 'void* platform_io.Renderer_RenderState' which is set during the
|
- IO: added 'void* platform_io.Renderer_RenderState' which is set during the
|
||||||
ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render
|
ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render
|
||||||
state to draw callbacks. (#6969, #5834, #7468, #3590)
|
state to draw callbacks. (#6969, #5834, #7468, #3590)
|
||||||
|
- DrawList: AddCallback() added an optional size parameter allowing to copy and
|
||||||
|
store any amount of user data for usage by callbacks: (#6969, #4770, #7665)
|
||||||
|
- If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior).
|
||||||
|
It will be available unmodified in ImDrawCmd::UserCallbackData during render.
|
||||||
|
- If userdata_size > 0, we copy/store 'userdata_size' bytes pointed to by 'userdata' (new behavior).
|
||||||
|
We store them in a buffer stored inside the drawlist. ImDrawCmd::UserCallbackData
|
||||||
|
will point inside that buffer so you have to retrieve data from there. Your callback
|
||||||
|
may need to use ImDrawCmd::UserCallbackDataSize if you expect dynamically-sized data.
|
||||||
- Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218)
|
- Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218)
|
||||||
- InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys,
|
- InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys,
|
||||||
preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen]
|
preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen]
|
||||||
|
@ -9,7 +9,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- doc: add a proper documentation system (maybe relying on automation? #435)
|
- doc: add a proper documentation system (maybe relying on automation? #435)
|
||||||
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
|
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
|
||||||
- doc/tips: tips of the day: website? applet in imgui_club?
|
- doc/tips: tips of the day: website? applet in imgui_club?
|
||||||
- doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki
|
|
||||||
|
|
||||||
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
|
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
|
||||||
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
|
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
|
||||||
@ -44,7 +43,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
|
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
|
||||||
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
||||||
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
|
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
|
||||||
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API).
|
- drawlist: callback: add an extra void* in ImDrawCallback to expose render state instead of pulling from Renderer_RenderState (would break API).
|
||||||
- drawlist: AddRect vs AddLine position confusing (#2441)
|
- drawlist: AddRect vs AddLine position confusing (#2441)
|
||||||
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
|
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
|
||||||
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
|
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
|
||||||
|
21
imgui.h
21
imgui.h
@ -29,7 +29,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.91.4 WIP"
|
#define IMGUI_VERSION "1.91.4 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19132
|
#define IMGUI_VERSION_NUM 19133
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2953,7 +2953,9 @@ struct ImDrawCmd
|
|||||||
unsigned int IdxOffset; // 4 // Start offset in index buffer.
|
unsigned int IdxOffset; // 4 // Start offset in index buffer.
|
||||||
unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].
|
unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].
|
||||||
ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
||||||
void* UserCallbackData; // 4-8 // The draw callback code can access this.
|
void* UserCallbackData; // 4-8 // Callback user data (when UserCallback != NULL). If called AddCallback() with size == 0, this is a copy of the AddCallback() argument. If called AddCallback() with size > 0, this is pointing to a buffer where data is stored.
|
||||||
|
int UserCallbackDataSize; // 4 // Size of callback user data when using storage, otherwise 0.
|
||||||
|
int UserCallbackDataOffset;// 4 // [Internal] Offset of callback user data when using storage, otherwise -1.
|
||||||
|
|
||||||
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
|
||||||
|
|
||||||
@ -3068,6 +3070,7 @@ struct ImDrawList
|
|||||||
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
|
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
|
||||||
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
||||||
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
||||||
|
ImVector<ImU8> _CallbacksDataBuf; // [Internal]
|
||||||
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
|
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
|
||||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||||
|
|
||||||
@ -3140,8 +3143,18 @@ struct ImDrawList
|
|||||||
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
|
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||||
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);
|
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||||
|
|
||||||
// Advanced
|
// Advanced: Draw Callbacks
|
||||||
IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles.
|
// - May be used to alter render state (change sampler, blending, current shader). May be used to emit custom rendering commands (difficult to do correctly, but possible).
|
||||||
|
// - Use special ImDrawCallback_ResetRenderState callback to instruct backend to reset its render state to the default.
|
||||||
|
// - Your rendering loop must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. All standard backends are honoring this.
|
||||||
|
// - For some backends, the callback may access selected render-states exposed by the backend in a ImGui_ImplXXXX_RenderState structure pointed to by platform_io.Renderer_RenderState.
|
||||||
|
// - IMPORTANT: please be mindful of the different level of indirection between using size==0 (copying argument) and using size>0 (copying pointed data into a buffer).
|
||||||
|
// - If userdata_size == 0: we copy/store the 'userdata' argument as-is. It will be available unmodified in ImDrawCmd::UserCallbackData during render.
|
||||||
|
// - If userdata_size > 0, we copy/store 'userdata_size' bytes pointed to by 'userdata'. We store them in a buffer stored inside the drawlist. ImDrawCmd::UserCallbackData will point inside that buffer so you have to retrieve data from there. Your callback may need to use ImDrawCmd::UserCallbackDataSize if you expect dynamically-sized data.
|
||||||
|
// - Support for userdata_size > 0 was added in v1.91.4, October 2024. So earlier code always only allowed to copy/store a simple void*.
|
||||||
|
IMGUI_API void AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size = 0);
|
||||||
|
|
||||||
|
// Advanced: Miscellaneous
|
||||||
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
|
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
|
||||||
IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
|
IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
|
||||||
|
|
||||||
|
@ -414,6 +414,7 @@ void ImDrawList::_ResetForNewFrame()
|
|||||||
_IdxWritePtr = NULL;
|
_IdxWritePtr = NULL;
|
||||||
_ClipRectStack.resize(0);
|
_ClipRectStack.resize(0);
|
||||||
_TextureIdStack.resize(0);
|
_TextureIdStack.resize(0);
|
||||||
|
_CallbacksDataBuf.resize(0);
|
||||||
_Path.resize(0);
|
_Path.resize(0);
|
||||||
_Splitter.Clear();
|
_Splitter.Clear();
|
||||||
CmdBuffer.push_back(ImDrawCmd());
|
CmdBuffer.push_back(ImDrawCmd());
|
||||||
@ -431,6 +432,7 @@ void ImDrawList::_ClearFreeMemory()
|
|||||||
_IdxWritePtr = NULL;
|
_IdxWritePtr = NULL;
|
||||||
_ClipRectStack.clear();
|
_ClipRectStack.clear();
|
||||||
_TextureIdStack.clear();
|
_TextureIdStack.clear();
|
||||||
|
_CallbacksDataBuf.clear();
|
||||||
_Path.clear();
|
_Path.clear();
|
||||||
_Splitter.ClearFreeMemory();
|
_Splitter.ClearFreeMemory();
|
||||||
}
|
}
|
||||||
@ -470,7 +472,7 @@ void ImDrawList::_PopUnusedDrawCmd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
void ImDrawList::AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size)
|
||||||
{
|
{
|
||||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
@ -480,8 +482,26 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
|||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_cmd->UserCallback = callback;
|
curr_cmd->UserCallback = callback;
|
||||||
curr_cmd->UserCallbackData = callback_data;
|
if (userdata_size == 0)
|
||||||
|
{
|
||||||
|
// Store user data directly in command (no indirection)
|
||||||
|
curr_cmd->UserCallbackData = userdata;
|
||||||
|
curr_cmd->UserCallbackDataSize = 0;
|
||||||
|
curr_cmd->UserCallbackDataOffset = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy and store user data in a buffer
|
||||||
|
IM_ASSERT(userdata != NULL);
|
||||||
|
IM_ASSERT(userdata_size < (1u << 31));
|
||||||
|
curr_cmd->UserCallbackData = NULL; // Will be resolved during Render()
|
||||||
|
curr_cmd->UserCallbackDataSize = (int)userdata_size;
|
||||||
|
curr_cmd->UserCallbackDataOffset = _CallbacksDataBuf.Size;
|
||||||
|
_CallbacksDataBuf.resize(_CallbacksDataBuf.Size + (int)userdata_size);
|
||||||
|
memcpy(_CallbacksDataBuf.Data + (size_t)curr_cmd->UserCallbackDataOffset, userdata, userdata_size);
|
||||||
|
}
|
||||||
|
|
||||||
AddDrawCmd(); // Force a new command after us (see comment below)
|
AddDrawCmd(); // Force a new command after us (see comment below)
|
||||||
}
|
}
|
||||||
@ -2222,6 +2242,12 @@ void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>
|
|||||||
if (sizeof(ImDrawIdx) == 2)
|
if (sizeof(ImDrawIdx) == 2)
|
||||||
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
|
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
|
||||||
|
|
||||||
|
// Resolve callback data pointers
|
||||||
|
if (draw_list->_CallbacksDataBuf.Size > 0)
|
||||||
|
for (ImDrawCmd& cmd : draw_list->CmdBuffer)
|
||||||
|
if (cmd.UserCallback != NULL && cmd.UserCallbackDataOffset != -1 && cmd.UserCallbackDataSize > 0)
|
||||||
|
cmd.UserCallbackData = draw_list->_CallbacksDataBuf.Data + cmd.UserCallbackDataOffset;
|
||||||
|
|
||||||
// Add to output list + records state in ImDrawData
|
// Add to output list + records state in ImDrawData
|
||||||
out_list->push_back(draw_list);
|
out_list->push_back(draw_list);
|
||||||
draw_data->CmdListsCount++;
|
draw_data->CmdListsCount++;
|
||||||
|
Loading…
Reference in New Issue
Block a user