#region Using Statements using System; using System.IO; using ANX.Framework.Graphics; using SharpDX; #endregion // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license using System.Runtime.InteropServices; #if DX10 using Dx = SharpDX.Direct3D10; using DxDevice = SharpDX.Direct3D10.Device; namespace ANX.RenderSystem.Windows.DX10 #endif #if DX11 using Dx = SharpDX.Direct3D11; using DxDevice = SharpDX.Direct3D11.Device; namespace ANX.RenderSystem.Windows.DX11 #endif { public partial class DxVertexBuffer { private int vertexStride; #region SetData public void SetData<S>(S[] data) where S : struct { if (data == null) throw new ArgumentNullException("data"); SetData(data, 0, data.Length); } public void SetData<S>(S[] data, int startIndex, int elementCount) where S : struct { SetData<S>(0, data, startIndex, elementCount, vertexStride); } public void SetData<S>(int offsetInBytes, S[] data, int startIndex, int elementCount, int vertexStride) where S : struct { if (data == null) throw new ArgumentNullException("data"); if (startIndex + elementCount > data.Length) throw new ArgumentOutOfRangeException("startIndex must be smaller than elementCount + data.Length."); if (offsetInBytes + elementCount * Marshal.SizeOf(typeof(S)) > NativeBuffer.Description.SizeInBytes) throw new ArgumentOutOfRangeException(string.Format("The offset by \"{0}\" plus the byte length described by \"{1}\" is over the bounds of the buffer.", "offsetInBytes", "elementCount")); var buffer = this.NativeBuffer; if (!this.WriteNeedsStaging) { buffer = CreateStagingBuffer(ResourceMapping.Write); } try { using (var stream = MapBuffer(buffer, ResourceMapping.Write)) { if (offsetInBytes > 0) stream.Seek(offsetInBytes, SeekOrigin.Current); if (startIndex > 0 || elementCount < data.Length) for (int i = startIndex; i < startIndex + elementCount; i++) stream.Write<S>(data[i]); else for (int i = 0; i < data.Length; i++) stream.Write<S>(data[i]); UnmapBuffer(buffer); } } finally { if (!this.WriteNeedsStaging) { CopySubresource(buffer, this.NativeBuffer); buffer.Dispose(); } } } #endregion #region GetData public void GetData<S>(S[] data) where S : struct { if (data == null) throw new ArgumentNullException("data"); GetData(data, 0, data.Length); } public void GetData<S>(S[] data, int startIndex, int elementCount) where S : struct { GetData(0, data, startIndex, elementCount, vertexStride); } public void GetData<S>(int offsetInBytes, S[] data, int startIndex, int elementCount, int vertexStride) where S : struct { if (data == null) throw new ArgumentNullException("data"); if (startIndex + elementCount > data.Length) throw new ArgumentOutOfRangeException("startIndex must be smaller than elementCount + data.Length."); //TODO: Create a staging buffer only with the needed size that correctly handles startIndex and offsetInBytes. using (var stagingBuffer = CreateStagingBuffer(ResourceMapping.Read)) { CopySubresource(NativeBuffer, stagingBuffer); using (var stream = MapBuffer(stagingBuffer, ResourceMapping.Read)) { if (offsetInBytes > 0) stream.Seek(offsetInBytes, SeekOrigin.Current); stream.ReadRange(data, startIndex, elementCount); UnmapBuffer(stagingBuffer); } } } #endregion } }