public virtual void Render(ID3D11DeviceContext context, PrimitiveTopology type, int size, uint offset) { context.IASetInputLayout(Layout); // set shaders only if available if (OurVertexShader != null) { context.VSSetShader(OurVertexShader); } if (OurVertexShader != null) { context.PSSetShader(OurPixelShader); context.PSSetSampler(0, SamplerState); } if (OurVertexShader != null) { context.GSSetShader(OurGeometryShader); } context.DrawIndexed(size, (int)offset, 0); Profiler.NumDrawCallsThisFrame++; }
public static void DrawIndexed(this ID3D11DeviceContext context, int indexCount, int startIndexLocation, int baseVertexLocation) { if (context == null) { throw new ArgumentNullException(nameof(context)); } context.DrawIndexed((uint)indexCount, (uint)startIndexLocation, baseVertexLocation); }
public void Draw(ID3D11Device device, ID3D11DeviceContext context, Span <D3D11_INPUT_ELEMENT_DESC> _layout) { if (!m_vertexBuffer) { using (var pin = PinPtr.Create(m_vertices)) { var desc = new D3D11_BUFFER_DESC { ByteWidth = (uint)m_vertices.Length, Usage = D3D11_USAGE._DEFAULT, BindFlags = (uint)D3D11_BIND_FLAG._VERTEX_BUFFER, }; var data = new D3D11_SUBRESOURCE_DATA { pSysMem = pin.Ptr }; device.CreateBuffer(ref desc, ref data, out m_vertexBuffer).ThrowIfFailed(); } } Span <IntPtr> pBufferTbl = stackalloc IntPtr[] { m_vertexBuffer.Ptr }; Span <uint> SizeTbl = stackalloc uint[] { (uint)m_vertexSize }; Span <uint> OffsetTbl = stackalloc uint[] { 0 }; context.IASetVertexBuffers(0, 1, ref MemoryMarshal.GetReference(pBufferTbl), ref MemoryMarshal.GetReference(SizeTbl), ref MemoryMarshal.GetReference(OffsetTbl)); if (!m_indexBuffer) { using (var pin = PinPtr.Create(m_indices)) { var desc = new D3D11_BUFFER_DESC { ByteWidth = (uint)m_indices.Length, Usage = D3D11_USAGE._DEFAULT, BindFlags = (uint)D3D11_BIND_FLAG._INDEX_BUFFER, }; var data = new D3D11_SUBRESOURCE_DATA { pSysMem = pin.Ptr }; device.CreateBuffer(ref desc, ref data, out m_indexBuffer).ThrowIfFailed(); } } context.IASetIndexBuffer(m_indexBuffer, m_indexFormat, 0); context.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY._TRIANGLELIST); context.DrawIndexed((uint)m_indexCount, 0, 0); } } }
public override void Render(ID3D11DeviceContext deviceContext, PrimitiveTopology type, int size, uint offset) { deviceContext.IASetInputLayout(Layout); deviceContext.VSSetShader(OurVertexShader); deviceContext.PSSetShader(OurPixelShader); switch (type) { case PrimitiveTopology.LineList: case PrimitiveTopology.TriangleList: deviceContext.DrawIndexed(size, (int)offset, 0); break; case PrimitiveTopology.LineStrip: deviceContext.Draw(size, 0); break; default: break; } Profiler.NumDrawCallsThisFrame++; }
public void Draw(ID3D11Device device, ID3D11DeviceContext context, Span <VertexAttribute> layout) { Span <IntPtr> buffers = stackalloc IntPtr[layout.Length]; Span <uint> strides = stackalloc uint[layout.Length]; Span <uint> offsets = stackalloc uint[layout.Length]; for (int i = 0; i < layout.Length; ++i) { var va = layout[i]; if (m_vertexBufferMap.TryGetValue(va.Semantic, out VertexBuffer vb)) { buffers[i] = vb.GetPtr(device); strides[i] = (uint)vb.Stride; } } context.IASetVertexBuffers(0, (uint)layout.Length, ref MemoryMarshal.GetReference(buffers), ref MemoryMarshal.GetReference(strides), ref MemoryMarshal.GetReference(offsets)); context.IASetIndexBuffer(m_indexBuffer.Buffer, m_indexFormat, 0); context.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY._TRIANGLELIST); context.DrawIndexed((uint)m_indexCount, 0, 0); }
public void Render(ImDrawDataPtr data) { // Avoid rendering when minimized if (data.DisplaySize.X <= 0.0f || data.DisplaySize.Y <= 0.0f) { return; } ID3D11DeviceContext ctx = deviceContext; if (vertexBuffer == null || vertexBufferSize < data.TotalVtxCount) { vertexBuffer?.Release(); vertexBufferSize = data.TotalVtxCount + 5000; BufferDescription desc = new BufferDescription(); desc.Usage = Vortice.Direct3D11.Usage.Dynamic; desc.SizeInBytes = vertexBufferSize * sizeof(ImDrawVert); desc.BindFlags = BindFlags.VertexBuffer; desc.CpuAccessFlags = CpuAccessFlags.Write; vertexBuffer = device.CreateBuffer(desc); } if (indexBuffer == null || indexBufferSize < data.TotalIdxCount) { indexBuffer?.Release(); indexBufferSize = data.TotalIdxCount + 10000; BufferDescription desc = new BufferDescription(); desc.Usage = Vortice.Direct3D11.Usage.Dynamic; desc.SizeInBytes = indexBufferSize * sizeof(ImDrawIdx); desc.BindFlags = BindFlags.IndexBuffer; desc.CpuAccessFlags = CpuAccessFlags.Write; indexBuffer = device.CreateBuffer(desc); } // Upload vertex/index data into a single contiguous GPU buffer var vertexResource = ctx.Map(vertexBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var indexResource = ctx.Map(indexBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var vertexResourcePointer = (ImDrawVert *)vertexResource.DataPointer; var indexResourcePointer = (ImDrawIdx *)indexResource.DataPointer; for (int n = 0; n < data.CmdListsCount; n++) { var cmdlList = data.CmdListsRange[n]; var vertBytes = cmdlList.VtxBuffer.Size * sizeof(ImDrawVert); Buffer.MemoryCopy((void *)cmdlList.VtxBuffer.Data, vertexResourcePointer, vertBytes, vertBytes); var idxBytes = cmdlList.IdxBuffer.Size * sizeof(ImDrawIdx); Buffer.MemoryCopy((void *)cmdlList.IdxBuffer.Data, indexResourcePointer, idxBytes, idxBytes); vertexResourcePointer += cmdlList.VtxBuffer.Size; indexResourcePointer += cmdlList.IdxBuffer.Size; } ctx.Unmap(vertexBuffer, 0); ctx.Unmap(indexBuffer, 0); // Setup orthographic projection matrix into our constant buffer // Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. var constResource = ctx.Map(constantBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var span = constResource.AsSpan <float>(VertexConstantBufferSize); float L = data.DisplayPos.X; float R = data.DisplayPos.X + data.DisplaySize.X; float T = data.DisplayPos.Y; float B = data.DisplayPos.Y + data.DisplaySize.Y; float[] mvp = { 2.0f / (R - L), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (T - B), 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f, }; mvp.CopyTo(span); ctx.Unmap(constantBuffer, 0); SetupRenderState(data, ctx); // Render command lists // (Because we merged all buffers into a single one, we maintain our own offset into them) int global_idx_offset = 0; int global_vtx_offset = 0; Vector2 clip_off = data.DisplayPos; for (int n = 0; n < data.CmdListsCount; n++) { var cmdList = data.CmdListsRange[n]; for (int i = 0; i < cmdList.CmdBuffer.Size; i++) { var cmd = cmdList.CmdBuffer[i]; if (cmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException("user callbacks not implemented"); } else { var rect = new Rect((int)(cmd.ClipRect.X - clip_off.X), (int)(cmd.ClipRect.Y - clip_off.Y), (int)(cmd.ClipRect.Z - clip_off.X), (int)(cmd.ClipRect.W - clip_off.Y)); ctx.RSSetScissorRects(rect); textureResources.TryGetValue(cmd.TextureId, out var texture); if (texture != null) { ctx.PSSetShaderResources(0, texture); } ctx.DrawIndexed((int)cmd.ElemCount, (int)(cmd.IdxOffset + global_idx_offset), (int)(cmd.VtxOffset + global_vtx_offset)); } } global_idx_offset += cmdList.IdxBuffer.Size; global_vtx_offset += cmdList.VtxBuffer.Size; } }