Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Vertices/IndexBuffer.cs
332 lines | 6.6 KiB | text/x-csharp | CSharpLexer
332 lines | 6.6 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System; | ||||
using System.Runtime.InteropServices; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Graphics | ||||
{ | ||||
public class IndexBuffer : GraphicsResource | ||||
{ | ||||
#region Public Properties | ||||
public BufferUsage BufferUsage | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
public int IndexCount | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
public IndexElementSize IndexElementSize | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
#endregion | ||||
#region Internal Properties | ||||
internal IGLBuffer buffer; | ||||
#endregion | ||||
#region Public Constructors | ||||
public IndexBuffer( | ||||
GraphicsDevice graphicsDevice, | ||||
IndexElementSize indexElementSize, | ||||
int indexCount, | ||||
BufferUsage bufferUsage | ||||
) : this( | ||||
graphicsDevice, | ||||
indexElementSize, | ||||
indexCount, | ||||
bufferUsage, | ||||
false | ||||
) { | ||||
} | ||||
public IndexBuffer( | ||||
GraphicsDevice graphicsDevice, | ||||
Type indexType, | ||||
int indexCount, | ||||
BufferUsage usage | ||||
) : this( | ||||
graphicsDevice, | ||||
SizeForType(graphicsDevice, indexType), | ||||
indexCount, | ||||
usage, | ||||
false | ||||
) { | ||||
} | ||||
#endregion | ||||
#region Protected Constructors | ||||
protected IndexBuffer( | ||||
GraphicsDevice graphicsDevice, | ||||
Type indexType, | ||||
int indexCount, | ||||
BufferUsage usage, | ||||
bool dynamic | ||||
) : this( | ||||
graphicsDevice, | ||||
SizeForType(graphicsDevice, indexType), | ||||
indexCount, | ||||
usage, | ||||
dynamic | ||||
) { | ||||
} | ||||
protected IndexBuffer( | ||||
GraphicsDevice graphicsDevice, | ||||
IndexElementSize indexElementSize, | ||||
int indexCount, | ||||
BufferUsage usage, | ||||
bool dynamic | ||||
) { | ||||
if (graphicsDevice == null) | ||||
{ | ||||
throw new ArgumentNullException("graphicsDevice"); | ||||
} | ||||
GraphicsDevice = graphicsDevice; | ||||
IndexElementSize = indexElementSize; | ||||
IndexCount = indexCount; | ||||
BufferUsage = usage; | ||||
buffer = GraphicsDevice.GLDevice.GenIndexBuffer( | ||||
dynamic, | ||||
usage, | ||||
IndexCount, | ||||
IndexElementSize | ||||
); | ||||
} | ||||
#endregion | ||||
#region Protected Dispose Method | ||||
protected override void Dispose(bool disposing) | ||||
{ | ||||
if (!IsDisposed) | ||||
{ | ||||
GraphicsDevice.GLDevice.AddDisposeIndexBuffer(buffer); | ||||
} | ||||
base.Dispose(disposing); | ||||
} | ||||
#endregion | ||||
#region Public GetData Methods | ||||
public void GetData<T>(T[] data) where T : struct | ||||
{ | ||||
GetData<T>( | ||||
0, | ||||
data, | ||||
0, | ||||
data.Length | ||||
); | ||||
} | ||||
public void GetData<T>( | ||||
T[] data, | ||||
int startIndex, | ||||
int elementCount | ||||
) where T : struct { | ||||
GetData<T>( | ||||
0, | ||||
data, | ||||
startIndex, | ||||
elementCount | ||||
); | ||||
} | ||||
public void GetData<T>( | ||||
int offsetInBytes, | ||||
T[] data, | ||||
int startIndex, | ||||
int elementCount | ||||
) where T : struct { | ||||
if (data == null) | ||||
{ | ||||
throw new ArgumentNullException("data"); | ||||
} | ||||
if (data.Length < (startIndex + elementCount)) | ||||
{ | ||||
throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); | ||||
} | ||||
if (BufferUsage == BufferUsage.WriteOnly) | ||||
{ | ||||
throw new NotSupportedException( | ||||
"This IndexBuffer was created with a usage type of BufferUsage.WriteOnly. " + | ||||
"Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported." | ||||
); | ||||
} | ||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); | ||||
GraphicsDevice.GLDevice.GetIndexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
handle.AddrOfPinnedObject(), | ||||
startIndex, | ||||
elementCount, | ||||
Marshal.SizeOf(typeof(T)) | ||||
); | ||||
handle.Free(); | ||||
} | ||||
#endregion | ||||
#region Public SetData Methods | ||||
public void SetData<T>(T[] data) where T : struct | ||||
{ | ||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); | ||||
GraphicsDevice.GLDevice.SetIndexBufferData( | ||||
buffer, | ||||
0, | ||||
handle.AddrOfPinnedObject(), | ||||
data.Length * Marshal.SizeOf(typeof(T)), | ||||
SetDataOptions.None | ||||
); | ||||
handle.Free(); | ||||
} | ||||
public void SetData<T>( | ||||
T[] data, | ||||
int startIndex, | ||||
int elementCount | ||||
) where T : struct { | ||||
ErrorCheck(data, startIndex, elementCount); | ||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); | ||||
GraphicsDevice.GLDevice.SetIndexBufferData( | ||||
buffer, | ||||
0, | ||||
handle.AddrOfPinnedObject() + (startIndex * Marshal.SizeOf(typeof(T))), | ||||
elementCount * Marshal.SizeOf(typeof(T)), | ||||
SetDataOptions.None | ||||
); | ||||
handle.Free(); | ||||
} | ||||
public void SetData<T>( | ||||
int offsetInBytes, | ||||
T[] data, | ||||
int startIndex, | ||||
int elementCount | ||||
) where T : struct { | ||||
ErrorCheck(data, startIndex, elementCount); | ||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); | ||||
GraphicsDevice.GLDevice.SetIndexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
handle.AddrOfPinnedObject() + (startIndex * Marshal.SizeOf(typeof(T))), | ||||
elementCount * Marshal.SizeOf(typeof(T)), | ||||
SetDataOptions.None | ||||
); | ||||
handle.Free(); | ||||
} | ||||
#endregion | ||||
#region Public Extensions | ||||
public void SetDataPointerEXT( | ||||
int offsetInBytes, | ||||
IntPtr data, | ||||
int dataLength, | ||||
SetDataOptions options | ||||
) { | ||||
GraphicsDevice.GLDevice.SetIndexBufferData( | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
dataLength, | ||||
options | ||||
); | ||||
} | ||||
#endregion | ||||
#region Internal Methods | ||||
[System.Diagnostics.Conditional("DEBUG")] | ||||
internal void ErrorCheck<T>( | ||||
T[] data, | ||||
int startIndex, | ||||
int elementCount | ||||
) where T : struct { | ||||
if (data == null) | ||||
{ | ||||
throw new ArgumentNullException("data"); | ||||
} | ||||
if (data.Length < (startIndex + elementCount)) | ||||
{ | ||||
throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); | ||||
} | ||||
} | ||||
#endregion | ||||
#region Internal Context Reset Method | ||||
/// <summary> | ||||
/// The GraphicsDevice is resetting, so GPU resources must be recreated. | ||||
/// </summary> | ||||
internal protected override void GraphicsDeviceResetting() | ||||
{ | ||||
// FIXME: Do we even want to bother with DeviceResetting for GL? -flibit | ||||
} | ||||
#endregion | ||||
#region Private Type Size Calculator | ||||
/// <summary> | ||||
/// Gets the relevant IndexElementSize enum value for the given type. | ||||
/// </summary> | ||||
/// <param name="graphicsDevice">The graphics device.</param> | ||||
/// <param name="type">The type to use for the index buffer</param> | ||||
/// <returns>The IndexElementSize enum value that matches the type</returns> | ||||
private static IndexElementSize SizeForType(GraphicsDevice graphicsDevice, Type type) | ||||
{ | ||||
int sizeInBytes = Marshal.SizeOf(type); | ||||
if (sizeInBytes == 2) | ||||
{ | ||||
return IndexElementSize.SixteenBits; | ||||
} | ||||
if (sizeInBytes == 4) | ||||
{ | ||||
return IndexElementSize.ThirtyTwoBits; | ||||
} | ||||
throw new ArgumentOutOfRangeException( | ||||
"type", | ||||
"Index buffers can only be created for types" + | ||||
" that are sixteen or thirty two bits in length" | ||||
); | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||