Demo: Demonstrate out-of-order rendering using ImDrawListSplitter.

This commit is contained in:
ocornut 2023-08-06 20:13:05 +02:00
parent cf3726bcbc
commit 2b1fc6f765
3 changed files with 39 additions and 1 deletions

View File

@ -48,6 +48,7 @@ Other changes:
v_max=INT_MAX (#6675, #6679) [@jbarthelmes]
- ImDrawList: Fixed OOB access in _CalcCircleAutoSegmentCount when passing excessively
large radius to AddCircle(). (#6657, #5317) [@EggsyCRO, @jdpatdiscord]
- Demo: Demonstrate out-of-order rendering using ImDrawListSplitter.
-----------------------------------------------------------------------

View File

@ -2706,7 +2706,7 @@ struct ImDrawList
// Advanced: Channels
// - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives)
// - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end)
// - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place!
// - This API shouldn't have been in ImDrawList in the first place!
// Prefer using your own persistent instance of ImDrawListSplitter as you can stack them.
// Using the ImDrawList::ChannelsXXXX you cannot stack a split over another.
inline void ChannelsSplit(int count) { _Splitter.Split(this, count); }

View File

@ -7866,6 +7866,43 @@ static void ShowExampleAppCustomRendering(bool* p_open)
ImGui::EndTabItem();
}
// Demonstrate out-of-order rendering via channels splitting
// We use functions in ImDrawList as each draw list contains a convenience splitter,
// but you can also instantiate your own ImDrawListSplitter if you need to nest them.
if (ImGui::BeginTabItem("Draw Channels"))
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
{
ImGui::Text("Blue shape is drawn first: appears in back");
ImGui::Text("Red shape is drawn after: appears in front");
ImVec2 p0 = ImGui::GetCursorScreenPos();
draw_list->AddRectFilled(ImVec2(p0.x, p0.y), ImVec2(p0.x + 50, p0.y + 50), IM_COL32(0, 0, 255, 255)); // Blue
draw_list->AddRectFilled(ImVec2(p0.x + 25, p0.y + 25), ImVec2(p0.x + 75, p0.y + 75), IM_COL32(255, 0, 0, 255)); // Red
ImGui::Dummy(ImVec2(75, 75));
}
ImGui::Separator();
{
ImGui::Text("Blue shape is drawn first, into channel 1: appears in front");
ImGui::Text("Red shape is drawn after, into channel 0: appears in back");
ImVec2 p1 = ImGui::GetCursorScreenPos();
// Create 2 channels and draw a Blue shape THEN a Red shape.
// You can create any number of channels. Tables API use 1 channel per column in order to better batch draw calls.
draw_list->ChannelsSplit(2);
draw_list->ChannelsSetCurrent(1);
draw_list->AddRectFilled(ImVec2(p1.x, p1.y), ImVec2(p1.x + 50, p1.y + 50), IM_COL32(0, 0, 255, 255)); // Blue
draw_list->ChannelsSetCurrent(0);
draw_list->AddRectFilled(ImVec2(p1.x + 25, p1.y + 25), ImVec2(p1.x + 75, p1.y + 75), IM_COL32(255, 0, 0, 255)); // Red
// Flatten/reorder channels. Red shape is in channel 0 and it appears below the Blue shape in channel 1.
// This works by copying draw indices only (vertices are not copied).
draw_list->ChannelsMerge();
ImGui::Dummy(ImVec2(75, 75));
ImGui::Text("After reordering, contents of channel 0 appears below channel 1.");
}
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}