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) { gd.DisposeWhenIdle(_vertexBuffer); _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIBSize = (uint)(draw_data->TotalIdxCount * sizeof(ushort)); if (totalIBSize > _indexBuffer.SizeInBytes) { gd.DisposeWhenIdle(_indexBuffer); _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } MappedResource vbMap = _gd.Map(_vertexBuffer, MapMode.Write); MappedResource ibMap = _gd.Map(_indexBuffer, MapMode.Write); for (int i = 0; i < draw_data->CmdListsCount; i++) { NativeDrawList *cmd_list = draw_data->CmdLists[i]; Unsafe.CopyBlock( (byte *)vbMap.Data.ToPointer() + vertexOffsetInVertices * sizeof(DrawVert), cmd_list->VtxBuffer.Data, (uint)(cmd_list->VtxBuffer.Size * sizeof(DrawVert))); Unsafe.CopyBlock( (byte *)ibMap.Data.ToPointer() + indexOffsetInElements * sizeof(ushort), cmd_list->IdxBuffer.Data, (uint)(cmd_list->IdxBuffer.Size * sizeof(ushort))); vertexOffsetInVertices += (uint)cmd_list->VtxBuffer.Size; indexOffsetInElements += (uint)cmd_list->IdxBuffer.Size; } _gd.Unmap(_vertexBuffer); _gd.Unmap(_indexBuffer); // 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); _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); } cl.SetVertexBuffer(0, _vertexBuffer); cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16); cl.SetPipeline(_pipeline); cl.SetGraphicsResourceSet(0, _mainResourceSet); 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 == _fontAtlasID) { cl.SetGraphicsResourceSet(1, _fontTextureResourceSet); } else { cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd->TextureId)); } } cl.SetScissorRect( 0, (uint)pcmd->ClipRect.X, (uint)pcmd->ClipRect.Y, (uint)(pcmd->ClipRect.Z - pcmd->ClipRect.X), (uint)(pcmd->ClipRect.W - pcmd->ClipRect.Y)); cl.DrawIndexed(pcmd->ElemCount, 1, (uint)idx_offset, vtx_offset, 0); } idx_offset += (int)pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } }
/// <summary> /// Maps a <see cref="DeviceBuffer"/> or <see cref="Texture"/> into a CPU-accessible data region, and returns a structured /// view over that region. /// </summary> /// <param name="resource">The <see cref="DeviceBuffer"/> or <see cref="Texture"/> resource to map.</param> /// <param name="mode">The <see cref="MapMode"/> to use.</param> /// <param name="subresource">The subresource to map. Subresources are indexed first by mip slice, then by array layer.</param> /// <typeparam name="T">The blittable value type which mapped data is viewed as.</typeparam> /// <returns>A <see cref="MappedResource"/> structure describing the mapped data region.</returns> public MappedResourceView <T> Map <T>(MappableResource resource, MapMode mode, uint subresource) where T : struct { MappedResource mappedResource = Map(resource, mode, subresource); return(new MappedResourceView <T>(mappedResource)); }
/// <summary> /// Constructs a new MappedResourceView which wraps the given <see cref="MappedResource"/>. /// </summary> /// <param name="rawResource">The raw resource which has been mapped.</param> public MappedResourceView(MappedResource rawResource) { MappedResource = rawResource; SizeInBytes = rawResource.SizeInBytes; Count = (int)(SizeInBytes / s_sizeofT); }