private unsafe void RenderImDrawData(DrawData *draw_data, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; uint indexOffsetInElements = 0; if (draw_data->CmdListsCount == 0) { return; } uint totalVBSize = (uint)(draw_data->TotalVtxCount * sizeof(DrawVert)); if (totalVBSize > _vertexBuffer.SizeInBytes) { _vertexBuffer.Dispose(); _vertexBuffer = gd.ResourceFactory.CreateVertexBuffer(new BufferDescription((ulong)(totalVBSize * 1.5f), true)); } uint totalIBSize = (uint)(draw_data->TotalIdxCount * sizeof(ushort)); if (totalIBSize > _indexBuffer.SizeInBytes) { _indexBuffer.Dispose(); _indexBuffer = gd.ResourceFactory.CreateIndexBuffer(new IndexBufferDescription((ulong)(totalIBSize * 1.5f), IndexFormat.UInt16, true)); } for (int i = 0; i < draw_data->CmdListsCount; i++) { NativeDrawList *cmd_list = draw_data->CmdLists[i]; cl.UpdateBuffer( _vertexBuffer, (uint)(vertexOffsetInVertices * sizeof(DrawVert)), new IntPtr(cmd_list->VtxBuffer.Data), (uint)(cmd_list->VtxBuffer.Size * sizeof(DrawVert))); cl.UpdateBuffer( _indexBuffer, (uint)(indexOffsetInElements * sizeof(ushort)), new IntPtr(cmd_list->IdxBuffer.Data), (uint)(cmd_list->IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmd_list->VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list->IdxBuffer.Size; } // Setup orthographic projection matrix into our constant buffer { var io = ImGui.GetIO(); Matrix4x4 mvp = Matrix4x4.CreateOrthographicOffCenter( 0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f); cl.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); } cl.SetVertexBuffer(0, _vertexBuffer); cl.SetIndexBuffer(_indexBuffer); cl.SetPipeline(_pipeline); cl.SetResourceSet(0, _resourceSet); ImGui.ScaleClipRects(draw_data, ImGui.GetIO().DisplayFramebufferScale); // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data->CmdListsCount; n++) { NativeDrawList *cmd_list = draw_data->CmdLists[n]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { DrawCmd *pcmd = &(((DrawCmd *)cmd_list->CmdBuffer.Data)[cmd_i]); if (pcmd->UserCallback != IntPtr.Zero) { throw new NotImplementedException(); } else { if (pcmd->TextureId != IntPtr.Zero) { if (pcmd->TextureId != new IntPtr(_fontAtlasID)) { throw new NotImplementedException(); } } cl.SetScissorRect( 0, (uint)pcmd->ClipRect.X, (uint)pcmd->ClipRect.Y, (uint)pcmd->ClipRect.Z, (uint)pcmd->ClipRect.W); cl.Draw(pcmd->ElemCount, 1, (uint)idx_offset, vtx_offset, 0); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } }