Browse Source

Examples/Backends: Metal: Added support for large meshes (64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_HasVtxOffset' config flag in back-end. (#2591, #2592)

Max Thrun 6 years ago
parent
commit
ed79b4d22e
3 changed files with 8 additions and 6 deletions
  1. 1 1
      docs/CHANGELOG.txt
  2. 1 0
      examples/imgui_impl_metal.h
  3. 6 5
      examples/imgui_impl_metal.mm

+ 1 - 1
docs/CHANGELOG.txt

@@ -71,7 +71,7 @@ Other Changes:
 - Backends: Add native Mac clipboard copy/paste default implementation in core library to match what we are
 - Backends: Add native Mac clipboard copy/paste default implementation in core library to match what we are
   dealing with Win32, and to facilitate integration in custom engines. (#2546) [@andrewwillmott]
   dealing with Win32, and to facilitate integration in custom engines. (#2546) [@andrewwillmott]
 - Backends: OSX: imgui_impl_osx: Added mouse cursor support. (#2585, #1873) [@actboy168]
 - Backends: OSX: imgui_impl_osx: Added mouse cursor support. (#2585, #1873) [@actboy168]
-- Examples/Backends: DirectX9/10/11/12, Vulkan, OpenGL3 (Desktop GL only): Added support for large meshes
+- Examples/Backends: DirectX9/10/11/12, Metal, Vulkan, OpenGL3 (Desktop GL only): Added support for large meshes
   (64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_RendererHasVtxOffset' in those back-ends.
   (64k+ vertices) with 16-bits indices, enable 'ImGuiBackendFlags_RendererHasVtxOffset' in those back-ends.
 - Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(),
 - Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(),
   the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode
   the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode

+ 1 - 0
examples/imgui_impl_metal.h

@@ -3,6 +3,7 @@
 
 
 // Implemented features:
 // Implemented features:
 //  [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
 //  [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
+//  [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
 
 
 // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
 // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
 // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
 // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.

+ 6 - 5
examples/imgui_impl_metal.mm

@@ -3,6 +3,7 @@
 
 
 // Implemented features:
 // Implemented features:
 //  [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
 //  [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
+//  [X] Renderer: Support for large meshes (64k+ vertices) with 16-bits indices.
 
 
 // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
 // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
 // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
 // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
@@ -10,6 +11,7 @@
 
 
 // CHANGELOG
 // CHANGELOG
 // (minor and older changes stripped away, please see git history for details)
 // (minor and older changes stripped away, please see git history for details)
+//  2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
 //  2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
 //  2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
 //  2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
 //  2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
 //  2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
 //  2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
@@ -76,6 +78,7 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
 {
 {
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
     io.BackendRendererName = "imgui_impl_metal";
     io.BackendRendererName = "imgui_impl_metal";
+    io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
 
 
     static dispatch_once_t onceToken;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
     dispatch_once(&onceToken, ^{
@@ -478,13 +481,10 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
     for (int n = 0; n < drawData->CmdListsCount; n++)
     for (int n = 0; n < drawData->CmdListsCount; n++)
     {
     {
         const ImDrawList* cmd_list = drawData->CmdLists[n];
         const ImDrawList* cmd_list = drawData->CmdLists[n];
-        ImDrawIdx idx_buffer_offset = 0;
 
 
         memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
         memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
         memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
         memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
 
 
-        [commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0];
-
         for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
         for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
         {
         {
             const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
             const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
@@ -522,14 +522,15 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
                     // Bind texture, Draw
                     // Bind texture, Draw
                     if (pcmd->TextureId != NULL)
                     if (pcmd->TextureId != NULL)
                         [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0];
                         [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0];
+
+                    [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
                     [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
                     [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
                                                indexCount:pcmd->ElemCount
                                                indexCount:pcmd->ElemCount
                                                 indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
                                                 indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
                                               indexBuffer:indexBuffer.buffer
                                               indexBuffer:indexBuffer.buffer
-                                        indexBufferOffset:indexBufferOffset + idx_buffer_offset];
+                                        indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
                 }
                 }
             }
             }
-            idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
         }
         }
 
 
         vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
         vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);