/// <summary> /// Creates a new <see cref="IndexBufferSubset"/> with the given <see cref="BufferObject"/> /// and specified offset into the buffer, storage length and element type. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="storageOffsetBytes">The offset into the <see cref="BufferObject"/>'s storage where this subset begins.</param> /// <param name="storageLength">The length of this subset measured in elements.</param> /// <param name="elementType">The type of elements this index subset will use.</param> public IndexBufferSubset(BufferObject bufferObject, uint storageOffsetBytes, uint storageLength, DrawElementsType elementType) : base(bufferObject, BufferTargetARB.ElementArrayBuffer) { ElementType = elementType; ElementSize = GetSizeInBytesOfElementType(elementType); ResizeSubset(storageOffsetBytes, storageLength); }
/// <summary> /// Creates a <see cref="VertexBuffer{T}"/> with specified length, optional index buffer and usage hint. /// </summary> /// <param name="graphicsDevice">The <see cref="GraphicsDevice"/> this <see cref="VertexBuffer{T}"/> will use.</param> /// <param name="storageLength">The length for the <see cref="VertexBuffer{T}"/>'s element storage measured in vertices.</param> /// <param name="indexStorageLength">The length for the <see cref="VertexBuffer{T}"/>'s index storage measured in index elements, or 0 for no index storage.</param> /// <param name="indexElementType">The type of index element to use.</param> /// <param name="usageHint">Used by the graphics driver to optimize performance.</param> public VertexBuffer(GraphicsDevice graphicsDevice, uint storageLength, uint indexStorageLength, DrawElementsType indexElementType, BufferUsageARB usageHint) { ValidateStorageLength(storageLength); ElementSize = (uint)Marshal.SizeOf <T>(); uint bufferStorageLengthBytes; uint elementSubsetLengthBytes = storageLength * ElementSize; bool hasIndexBuffer = indexStorageLength > 0; uint indexSubsetStartBytes; if (hasIndexBuffer) { uint indexElementSize = IndexBufferSubset.GetSizeInBytesOfElementType(indexElementType); indexSubsetStartBytes = (elementSubsetLengthBytes + indexElementSize - 1) / indexElementSize * indexElementSize; bufferStorageLengthBytes = indexSubsetStartBytes + indexElementSize * indexStorageLength; } else { indexSubsetStartBytes = 0; bufferStorageLengthBytes = elementSubsetLengthBytes; } Buffer = new BufferObject(graphicsDevice, bufferStorageLengthBytes, usageHint); DataSubset = new VertexDataBufferSubset <T>(Buffer, 0, storageLength); IndexBufferSubset indexSubset = hasIndexBuffer ? new IndexBufferSubset(Buffer, indexSubsetStartBytes, indexStorageLength, indexElementType) : null; VertexArray = VertexArray.CreateSingleBuffer <T>(graphicsDevice, DataSubset, indexSubset); }
/// <summary> /// Creates a new <see cref="IndexBufferSubset"/> with the specified offset into the buffer, /// storage length, <see cref="DrawElementsType.UnsignedByte"/> element type and initial data. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="storageOffsetBytes">The offset into the <see cref="BufferObject"/>'s storage where this subset begins.</param> /// <param name="storageLength">The length of this subset measured in elements.</param> /// <param name="data">A <see cref="ReadOnlySpan{T}"/> containing the initial data to set to the subset.</param> /// <param name="dataWriteOffset">The offset into the subset's storage at which to start writting the initial data.</param> public IndexBufferSubset(BufferObject bufferObject, uint storageOffsetBytes, uint storageLength, ReadOnlySpan <byte> data, uint dataWriteOffset = 0) : this(bufferObject, storageOffsetBytes, storageLength, DrawElementsType.UnsignedByte) { if (!data.IsEmpty) { SetData(data, dataWriteOffset); } }
internal UniformBufferSubset(uint elementSize, BufferObject bufferObject, uint storageOffsetBytes, uint storageLength) : base(bufferObject, BufferTargetARB.UniformBuffer) { ElementSize = elementSize; uint uniformOffsetAlignment = (uint)bufferObject.GraphicsDevice.UniformBufferOffsetAlignment; ElementStride = (ElementSize + uniformOffsetAlignment - 1) / uniformOffsetAlignment * uniformOffsetAlignment; ResizeSubset(storageOffsetBytes, storageLength); }
internal DataBufferSubset(uint elementSize, BufferObject bufferObject, BufferTargetARB bufferTarget) : base(bufferObject, bufferTarget) { ElementSize = elementSize; uint storageLength = bufferObject.StorageLengthInBytes / elementSize; if (storageLength * elementSize != bufferObject.StorageLengthInBytes) { throw new ArgumentException("The provided " + nameof(BufferObject) + "'s " + nameof(BufferObject.StorageLengthInBytes) + " should be a multiple of " + nameof(ElementSize)); } ResizeSubset(0, storageLength); }
/// <summary> /// Creates a <see cref="BufferObjectSubset"/> with the given <see cref="BufferObject"/> and /// target, but storage offset and length are left uninitialized. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="bufferTarget">The <see cref="BufferTargetARB"/> this subset will always bind to.</param> internal BufferObjectSubset(BufferObject bufferObject, BufferTargetARB bufferTarget) { if (bufferObject == null) { throw new ArgumentNullException(nameof(bufferObject)); } if (!Enum.IsDefined(typeof(BufferTargetARB), bufferTarget)) { throw new ArgumentException(nameof(bufferTarget) + " must be a valid " + nameof(BufferTargetARB) + " value", nameof(bufferTarget)); } bufferTargetBindingIndex = bufferObject.GraphicsDevice.GetBindingTargetIndex(bufferTarget); Buffer = bufferObject; BufferHandle = Buffer.Handle; BufferTarget = bufferTarget; }
internal UniformBufferSubset(uint elementSize, BufferObject bufferObject) : base(bufferObject, BufferTargetARB.UniformBuffer) { ElementSize = elementSize; uint uniformOffsetAlignment = (uint)bufferObject.GraphicsDevice.UniformBufferOffsetAlignment; ElementStride = (ElementSize + uniformOffsetAlignment - 1) / uniformOffsetAlignment * uniformOffsetAlignment; uint storageLength = bufferObject.StorageLengthInBytes / ElementStride; if (storageLength == 0) { storageLength = bufferObject.StorageLengthInBytes / ElementSize; if (storageLength == 0) { throw new ArgumentException(nameof(bufferObject) + " must have enough capacity for at least one uniform", nameof(bufferObject)); } } ResizeSubset(0, storageLength); }
/// <summary> /// Creates an <see cref="IndexBufferSubset"/> with the given <see cref="BufferObject"/>, /// with the subset covering the entire <see cref="BufferObject"/>'s storage. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="elementType">The type of elements this index subset will use.</param> public IndexBufferSubset(BufferObject bufferObject, DrawElementsType elementType) : this(bufferObject, 0, bufferObject.StorageLengthInBytes, elementType) { }
internal DataBufferSubset(uint elementSize, BufferObject bufferObject, BufferTargetARB bufferTarget, uint storageOffsetBytes, uint storageLength) : base(bufferObject, bufferTarget) { ElementSize = elementSize; ResizeSubset(storageOffsetBytes, storageLength); }
/// <summary> /// Creates a <see cref="VertexDataBufferSubset{T}"/> with the given <see cref="BufferObject"/> /// and target, with the subset covering the entire buffer's storage and optional initial data. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="data">A <see cref="ReadOnlySpan{T}"/> containing the initial data to set to the subset, or empty.</param> /// <param name="dataWriteOffset">The offset into the subset's storage at which to start writting the initial data.</param> public VertexDataBufferSubset(BufferObject bufferObject, ReadOnlySpan <T> data = default, uint dataWriteOffset = 0) : base(bufferObject, BufferTargetARB.ArrayBuffer, data, dataWriteOffset) { }
/// <summary> /// Creates a <see cref="BufferObjectSubset"/> with the given <see cref="BufferObject"/> and /// target, offset into the buffer and storage length. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="bufferTarget">The <see cref="BufferTargetARB"/> this subset will always bind to.</param> /// <param name="storageOffsetBytes">The offset into the <see cref="BufferObject"/>'s storage where this subset begins.</param> /// <param name="storageLengthBytes">The length of this subset measured in bytes.</param> internal BufferObjectSubset(BufferObject bufferObject, BufferTargetARB bufferTarget, uint storageOffsetBytes, uint storageLengthBytes) : this(bufferObject, bufferTarget) { InitializeStorage(storageOffsetBytes, storageLengthBytes); }
/// <summary> /// Creates a <see cref="VertexDataBufferSubset{T}"/> with the given <see cref="BufferObject"/> /// and target, offset into the buffer in bytes, storage length in elements and optional initial data. /// </summary> /// <param name="bufferObject">The <see cref="BufferObject"/> this subset will belong to.</param> /// <param name="storageOffsetBytes">The offset into the <see cref="BufferObject"/>'s storage where this subset begins.</param> /// <param name="storageLength">The length of this subset measured in elements.</param> /// <param name="data">A <see cref="ReadOnlySpan{T}"/> containing the initial data to set to the subset, or empty.</param> /// <param name="dataWriteOffset">The offset into the subset's storage at which to start writting the initial data.</param> public VertexDataBufferSubset(BufferObject bufferObject, uint storageOffsetBytes, uint storageLength, ReadOnlySpan <T> data = default, uint dataWriteOffset = 0) : base(bufferObject, BufferTarget.ArrayBuffer, storageOffsetBytes, storageLength, data, dataWriteOffset) { }