mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-26 05:27:01 +00:00
ImDrawList: Fixed issues with channels split/merge. Functional without manually adding a draw cmd. + Removed unnecessary parameter to Channe
This commit is contained in:
parent
ad00d88923
commit
77b82ecad7
@ -8566,7 +8566,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
|
|||||||
ItemSize(ImVec2(0,0)); // Advance to column 0
|
ItemSize(ImVec2(0,0)); // Advance to column 0
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
window->DrawList->ChannelsMerge(window->DC.ColumnsCount);
|
window->DrawList->ChannelsMerge();
|
||||||
|
|
||||||
window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y);
|
window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y);
|
||||||
window->DC.CursorPos.y = window->DC.ColumnsCellMaxY;
|
window->DC.CursorPos.y = window->DC.ColumnsCellMaxY;
|
||||||
|
11
imgui.h
11
imgui.h
@ -1015,6 +1015,8 @@ struct ImDrawCmd
|
|||||||
ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas.
|
ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas.
|
||||||
ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
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.
|
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vertex index (override with, e.g. '#define ImDrawIdx unsigned int' in ImConfig)
|
// Vertex index (override with, e.g. '#define ImDrawIdx unsigned int' in ImConfig)
|
||||||
@ -1066,8 +1068,9 @@ struct ImDrawList
|
|||||||
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
||||||
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
ImVector<ImTextureID> _TextureIdStack; // [Internal]
|
||||||
ImVector<ImVec2> _Path; // [Internal] current path building
|
ImVector<ImVec2> _Path; // [Internal] current path building
|
||||||
int _ChannelCurrent; // [Internal] current channel number (0)
|
int _ChannelsCurrent; // [Internal] current channel number (0)
|
||||||
ImVector<ImDrawChannel> _Channels; // [Internal] draw channels for columns API
|
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() { _OwnerName = NULL; Clear(); }
|
||||||
~ImDrawList() { ClearFreeMemory(); }
|
~ImDrawList() { ClearFreeMemory(); }
|
||||||
@ -1105,8 +1108,8 @@ struct ImDrawList
|
|||||||
// Advanced
|
// Advanced
|
||||||
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.
|
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.
|
||||||
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 void ChannelsSplit(int channel_count);
|
IMGUI_API void ChannelsSplit(int channels_count);
|
||||||
IMGUI_API void ChannelsMerge(int channel_count);
|
IMGUI_API void ChannelsMerge();
|
||||||
IMGUI_API void ChannelsSetCurrent(int idx);
|
IMGUI_API void ChannelsSetCurrent(int idx);
|
||||||
|
|
||||||
// Internal helpers
|
// Internal helpers
|
||||||
|
@ -85,7 +85,7 @@ using namespace IMGUI_STB_NAMESPACE;
|
|||||||
// ImDrawList
|
// ImDrawList
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static ImVec4 GNullClipRect(-9999.0f,-9999.0f, +9999.0f, +9999.0f);
|
static ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift
|
||||||
|
|
||||||
void ImDrawList::Clear()
|
void ImDrawList::Clear()
|
||||||
{
|
{
|
||||||
@ -98,7 +98,8 @@ void ImDrawList::Clear()
|
|||||||
_ClipRectStack.resize(0);
|
_ClipRectStack.resize(0);
|
||||||
_TextureIdStack.resize(0);
|
_TextureIdStack.resize(0);
|
||||||
_Path.resize(0);
|
_Path.resize(0);
|
||||||
_ChannelCurrent = 0;
|
_ChannelsCurrent = 0;
|
||||||
|
_ChannelsCount = 1;
|
||||||
// NB: Do not clear channels so our allocations are re-used after the first frame.
|
// NB: Do not clear channels so our allocations are re-used after the first frame.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,8 @@ void ImDrawList::ClearFreeMemory()
|
|||||||
_ClipRectStack.clear();
|
_ClipRectStack.clear();
|
||||||
_TextureIdStack.clear();
|
_TextureIdStack.clear();
|
||||||
_Path.clear();
|
_Path.clear();
|
||||||
_ChannelCurrent = 0;
|
_ChannelsCurrent = 0;
|
||||||
|
_ChannelsCount = 1;
|
||||||
for (int i = 0; i < _Channels.Size; i++)
|
for (int i = 0; i < _Channels.Size; i++)
|
||||||
{
|
{
|
||||||
if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again
|
if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again
|
||||||
@ -126,11 +128,8 @@ void ImDrawList::ClearFreeMemory()
|
|||||||
void ImDrawList::AddDrawCmd()
|
void ImDrawList::AddDrawCmd()
|
||||||
{
|
{
|
||||||
ImDrawCmd draw_cmd;
|
ImDrawCmd draw_cmd;
|
||||||
draw_cmd.ElemCount = 0;
|
|
||||||
draw_cmd.ClipRect = _ClipRectStack.Size ? _ClipRectStack.back() : GNullClipRect;
|
draw_cmd.ClipRect = _ClipRectStack.Size ? _ClipRectStack.back() : GNullClipRect;
|
||||||
draw_cmd.TextureId = _TextureIdStack.Size ? _TextureIdStack.back() : NULL;
|
draw_cmd.TextureId = _TextureIdStack.Size ? _TextureIdStack.back() : NULL;
|
||||||
draw_cmd.UserCallback = NULL;
|
|
||||||
draw_cmd.UserCallbackData = NULL;
|
|
||||||
|
|
||||||
IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w);
|
IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w);
|
||||||
CmdBuffer.push_back(draw_cmd);
|
CmdBuffer.push_back(draw_cmd);
|
||||||
@ -151,24 +150,34 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
|||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::ChannelsSplit(int channel_count)
|
void ImDrawList::ChannelsSplit(int channels_count)
|
||||||
{
|
{
|
||||||
IM_ASSERT(_ChannelCurrent == 0);
|
IM_ASSERT(_ChannelsCurrent == 0 && _ChannelsCount == 1);
|
||||||
int old_channels_count = _Channels.Size;
|
int old_channels_count = _Channels.Size;
|
||||||
if (old_channels_count < channel_count)
|
if (old_channels_count < channels_count)
|
||||||
_Channels.resize(channel_count);
|
_Channels.resize(channels_count);
|
||||||
for (int i = 0; i < channel_count; i++)
|
_ChannelsCount = channels_count;
|
||||||
|
for (int i = 0; i < channels_count; i++)
|
||||||
|
{
|
||||||
if (i >= old_channels_count)
|
if (i >= old_channels_count)
|
||||||
new(&_Channels[i]) ImDrawChannel();
|
new(&_Channels[i]) ImDrawChannel();
|
||||||
else
|
else if (i > 0)
|
||||||
_Channels[i].CmdBuffer.resize(0), _Channels[i].IdxBuffer.resize(0);
|
_Channels[i].CmdBuffer.resize(0), _Channels[i].IdxBuffer.resize(0);
|
||||||
|
if (_Channels[i].CmdBuffer.Size == 0)
|
||||||
|
{
|
||||||
|
ImDrawCmd draw_cmd;
|
||||||
|
draw_cmd.ClipRect = _ClipRectStack.back();
|
||||||
|
draw_cmd.TextureId = _TextureIdStack.back();
|
||||||
|
_Channels[i].CmdBuffer.push_back(draw_cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::ChannelsMerge(int channel_count)
|
void ImDrawList::ChannelsMerge()
|
||||||
{
|
{
|
||||||
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
// Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use.
|
||||||
// This is why this function takes 'channel_count' as a parameter of how many channels to merge (the user knows)
|
// This is why this function takes 'channel_count' as a parameter of how many channels to merge (the user knows)
|
||||||
if (channel_count < 2)
|
if (_ChannelsCount <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChannelsSetCurrent(0);
|
ChannelsSetCurrent(0);
|
||||||
@ -176,7 +185,7 @@ void ImDrawList::ChannelsMerge(int channel_count)
|
|||||||
CmdBuffer.pop_back();
|
CmdBuffer.pop_back();
|
||||||
|
|
||||||
int new_cmd_buffer_count = 0, new_idx_buffer_count = 0;
|
int new_cmd_buffer_count = 0, new_idx_buffer_count = 0;
|
||||||
for (int i = 1; i < channel_count; i++)
|
for (int i = 1; i < _ChannelsCount; i++)
|
||||||
{
|
{
|
||||||
ImDrawChannel& ch = _Channels[i];
|
ImDrawChannel& ch = _Channels[i];
|
||||||
if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0)
|
if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0)
|
||||||
@ -189,23 +198,24 @@ void ImDrawList::ChannelsMerge(int channel_count)
|
|||||||
|
|
||||||
ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count;
|
ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count;
|
||||||
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count;
|
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count;
|
||||||
for (int i = 1; i < channel_count; i++)
|
for (int i = 1; i < _ChannelsCount; i++)
|
||||||
{
|
{
|
||||||
ImDrawChannel& ch = _Channels[i];
|
ImDrawChannel& ch = _Channels[i];
|
||||||
if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; }
|
if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; }
|
||||||
if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; }
|
if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; }
|
||||||
}
|
}
|
||||||
AddDrawCmd();
|
AddDrawCmd();
|
||||||
|
_ChannelsCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::ChannelsSetCurrent(int idx)
|
void ImDrawList::ChannelsSetCurrent(int idx)
|
||||||
{
|
{
|
||||||
if (_ChannelCurrent == idx) return;
|
if (_ChannelsCurrent == idx) return;
|
||||||
memcpy(&_Channels.Data[_ChannelCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer));
|
memcpy(&_Channels.Data[_ChannelsCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer)); // copy 12 bytes, four times
|
||||||
memcpy(&_Channels.Data[_ChannelCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer));
|
memcpy(&_Channels.Data[_ChannelsCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer));
|
||||||
_ChannelCurrent = idx;
|
_ChannelsCurrent = idx;
|
||||||
memcpy(&CmdBuffer, &_Channels.Data[_ChannelCurrent].CmdBuffer, sizeof(CmdBuffer));
|
memcpy(&CmdBuffer, &_Channels.Data[_ChannelsCurrent].CmdBuffer, sizeof(CmdBuffer));
|
||||||
memcpy(&IdxBuffer, &_Channels.Data[_ChannelCurrent].IdxBuffer, sizeof(IdxBuffer));
|
memcpy(&IdxBuffer, &_Channels.Data[_ChannelsCurrent].IdxBuffer, sizeof(IdxBuffer));
|
||||||
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size;
|
_IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user