ImDrawList: Added ImDrawCmd::VtxOffset value to support large meshes (64k+ vertices) using 16-bits indices. To enable the feature, the renderer back-end needs to set 'io.BackendFlags |= ImGuiBackendFlags_HasVtxOffset' and honor the ImDrawCmd::VtxOffset field. Otherwise the value will always be zero. This has the advantage of preserving smaller index buffers and allowing to execute on hardware that do not support 32-bits indices.
ImDrawList: Added ImDrawCmd::IdxOffset value, equivalent to summing element count for each draw command. This is provided for convenience and consistency with VtxOffset. (#2591)
@ -3774,19 +3780,28 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
return;
}
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. May trigger for you if you are using PrimXXX functions incorrectly.
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
// May trigger for you if you are using PrimXXX functions incorrectly.
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
// If this assert triggers because you are drawing lots of stuff manually:
// A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use the Metrics window to inspect draw list contents.
// B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes.
// You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing:
// Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API.
// C) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists.
// - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
// Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics window to inspect draw list contents.
// - If you want large meshes with more than 64K vertices, you can either:
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer back-end, and set 'io.BackendFlags |= ImGuiBackendFlags_HasVtxOffset'.
// Most example back-ends already support this from 1.71. Pre-1.71 back-ends won't.
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
// (B) Or handle 32-bits indices in your renderer back-end, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
// Most example back-ends already support this. For example, the OpenGL example code detect index size at compile-time:
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
@ -1003,9 +1003,10 @@ enum ImGuiConfigFlags_
enumImGuiBackendFlags_
{
ImGuiBackendFlags_None=0,
ImGuiBackendFlags_HasGamepad=1<<0,// Back-end supports gamepad and currently has one connected.
ImGuiBackendFlags_HasMouseCursors=1<<1,// Back-end supports honoring GetMouseCursor() value to change the OS cursor shape.
ImGuiBackendFlags_HasSetMousePos=1<<2// Back-end supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set).
ImGuiBackendFlags_HasGamepad=1<<0,// Platform Back-end supports gamepad and currently has one connected.
ImGuiBackendFlags_HasMouseCursors=1<<1,// Platform Back-end supports honoring GetMouseCursor() value to change the OS cursor shape.
ImGuiBackendFlags_HasSetMousePos=1<<2,// Platform Back-end supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set).
ImGuiBackendFlags_HasVtxOffset=1<<3// Renderer Back-end supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bits indices.
};
// Enumeration for PushStyleColor() / PopStyleColor()
@ -1771,25 +1772,31 @@ struct ImColor
// The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) { cmd.UserCallback(parent_list, cmd); } else { RenderTriangles() }'
// Special Draw Callback value to request renderer back-end to reset the graphics/render state.
// Special Draw callback value to request renderer back-end to reset the graphics/render state.
// The renderer back-end needs to handle this special value, otherwise it will crash trying to call a function at this address.
// This is useful for example if you submitted callbacks which you know have altered the render state and you want it to be restored.
// It is not done by default because they are many perfectly useful way of altering render state for imgui contents (e.g. changing shader/blending settings before an Image call).
// Typically, 1 command = 1 GPU draw call (unless command is a callback)
// Pre 1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields. When (io.BackendFlags & ImGuiBackendFlags_HasVtxOffset)
// is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bits indices.
structImDrawCmd
{
unsignedintElemCount;// 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[].
ImVec4ClipRect;// Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates
ImTextureIDTextureId;// 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.
unsignedintVtxOffset;// Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_HasVtxOffset: always 0. With ImGuiBackendFlags_HasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bits indices.
unsignedintIdxOffset;// Start offset in index buffer. Always equal to sum of ElemCount drawn so far.
ImDrawCallbackUserCallback;// 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.
// Vertex index (override with '#define ImDrawIdx unsigned int' in imconfig.h)
// Vertex index
// (to allow large meshes with 16-bits indices: set 'io.BackendFlags |= ImGuiBackendFlags_HasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end)
// (to use 32-bits indices: override with '#define ImDrawIdx unsigned int' in imconfig.h)
#ifndef ImDrawIdx
typedefunsignedshortImDrawIdx;
#endif
@ -1835,7 +1842,8 @@ enum ImDrawListFlags_
{
ImDrawListFlags_None=0,
ImDrawListFlags_AntiAliasedLines=1<<0,// Lines are anti-aliased (*2 the number of triangles for 1.0f wide line, otherwise *3 the number of triangles)
ImDrawListFlags_AntiAliasedFill=1<<1// Filled shapes have anti-aliased edges (*2 the number of vertices)
ImDrawListFlags_AntiAliasedFill=1<<1,// Filled shapes have anti-aliased edges (*2 the number of vertices)
ImDrawListFlags_AllowVtxOffset=1<<2// Can emit 'VtxOffset > 0' to allow large meshes. Set when 'io.BackendFlags & ImGuiBackendFlags_HasVtxOffset' is enabled.
};
// Draw command list
@ -1855,7 +1863,8 @@ struct ImDrawList
// [Internal, used while building lists]
constImDrawListSharedData*_Data;// Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
constchar*_OwnerName;// Pointer to owner window's name for debugging