diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 02fd7b8f..1e05b3b0 100644 --- a/docs/CHANGELOG.txt +++ b/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 dealing with Win32, and to facilitate integration in custom engines. (#2546) [@andrewwillmott] - 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. - 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 diff --git a/examples/imgui_impl_metal.h b/examples/imgui_impl_metal.h index 731ec20b..6c6e4ca9 100644 --- a/examples/imgui_impl_metal.h +++ b/examples/imgui_impl_metal.h @@ -3,6 +3,7 @@ // Implemented features: // [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. // Missing features: // [ ] Renderer: Multi-viewport / platform windows. diff --git a/examples/imgui_impl_metal.mm b/examples/imgui_impl_metal.mm index 49a7baf0..abfeb169 100644 --- a/examples/imgui_impl_metal.mm +++ b/examples/imgui_impl_metal.mm @@ -3,6 +3,7 @@ // Implemented features: // [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. // Missing features: // [ ] Renderer: Multi-viewport / platform windows. @@ -12,6 +13,7 @@ // CHANGELOG // (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-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. @@ -78,6 +80,7 @@ bool ImGui_ImplMetal_Init(id device) { ImGuiIO& io = ImGui::GetIO(); 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; dispatch_once(&onceToken, ^{ @@ -480,13 +483,10 @@ void ImGui_ImplMetal_DestroyDeviceObjects() for (int n = 0; n < drawData->CmdListsCount; 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 *)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++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; @@ -524,14 +524,15 @@ void ImGui_ImplMetal_DestroyDeviceObjects() // Bind texture, Draw if (pcmd->TextureId != NULL) [commandEncoder setFragmentTexture:(__bridge id)(pcmd->TextureId) atIndex:0]; + + [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:pcmd->ElemCount indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 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); diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index b133f9d4..ee3974e5 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -108,9 +108,9 @@ // Desktop GL has glDrawElementsBaseVertex() which GL ES and WebGL don't have. #if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) -#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 1 -#else #define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 0 +#else +#define IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX 1 #endif // OpenGL Data @@ -324,9 +324,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); #if IMGUI_IMPL_OPENGL_HAS_DRAW_WITH_BASE_VERTEX - glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)pcmd->IdxOffset, (GLint)pcmd->VtxOffset); + glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); #else - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)pcmd->IdxOffset); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); #endif } }