/// <summary> /// Get the size of a vertex array buffer item. /// </summary> /// <param name="vertexBaseType"> /// A <see cref="VertexBaseType"/> that describe the vertex array buffer item. /// </param> /// <returns> /// It returns the size of the vertex array buffer type having the type <paramref name="vertexBaseType"/>, in bytes. /// </returns> public static uint GetSize(this VertexBaseType vertexBaseType) { switch (vertexBaseType) { case VertexBaseType.Byte: case VertexBaseType.UByte: return(1); case VertexBaseType.Short: case VertexBaseType.UShort: case VertexBaseType.Half: return(2); case VertexBaseType.Float: case VertexBaseType.Int: case VertexBaseType.UInt: return(4); case VertexBaseType.Double: return(8); default: throw new NotSupportedException("base type not supported"); } }
/// <summary> /// Test <see cref="ArrayBufferObject.ToArray()"/>. /// </summary> /// <param name="vertexBaseType"></param> /// <param name="vertexLength"></param> /// <param name="array"></param> public void TestToArray_Core(VertexBaseType vertexBaseType, uint vertexLength, Array array) { using (ArrayBufferObject arrayBuffer = new ArrayBufferObject(vertexBaseType, vertexLength, BufferObjectHint.StaticCpuDraw)) { // Create client buffer arrayBuffer.Create(array); // ToArray() must be equal to array CollectionAssert.AreEqual(array, arrayBuffer.ToArray()); // Create GPU buffer arrayBuffer.Create(_Context); // ToArray() must be equal to array CollectionAssert.AreEqual(array, arrayBuffer.ToArray(_Context)); // Create a reversed array from test array Array arrayReverse = Array.CreateInstance(array.GetType().GetElementType(), array.Length); Array.Copy(array, arrayReverse, array.Length); Array.Reverse(arrayReverse); CollectionAssert.AreEquivalent(array, arrayReverse); // Update client buffer arrayBuffer.Create(arrayReverse); // Client buffer is updated, but not the GPU buffer CollectionAssert.AreEqual(arrayReverse, arrayBuffer.ToArray()); } }
/// <summary> /// Construct an ArrayBufferItemAttribute for matrix items. /// </summary> /// <param name="arrayType"> /// A <see cref="VertexBaseType"/> describing the matrix components type. /// </param> /// <param name="matrixColumns"> /// A <see cref="UInt32"/> that specify the matrix columns count. /// </param> /// <param name="matrixRows"> /// A <see cref="UInt32"/> that specify the matrix rows count. /// </param> public ArrayBufferItemAttribute(VertexBaseType arrayType, uint matrixColumns, uint matrixRows) { ArrayType = arrayType.GetArrayBufferType(matrixRows, matrixColumns); ArrayBaseType = arrayType; ArrayLength = matrixRows; ArrayRank = matrixColumns; }
public void TestToArray_NoExtension(VertexBaseType vertexBaseType, uint vertexLength, Array array) { _Context.PushCaps(); try { // Disable GL_ARB_vertex_array_object _Context.Caps.GlExtensions.VertexBufferObject_ARB = false; TestToArray_Core(vertexBaseType, vertexLength, array); } finally { _Context.PopCaps(); } }
/// <summary> /// Determine whether a base type is a floating-point value. /// </summary> public static bool IsFloatBaseType(this VertexBaseType vertexBaseType) { switch (vertexBaseType) { case VertexBaseType.Float: case VertexBaseType.Half: case VertexBaseType.Double: return(true); default: return(false); } }
/// <summary> /// Construct an ArrayBufferItem specifying the vertex base type and the array item length and rank. /// </summary> /// <param name="vertexBaseType"> /// A <see cref="VertexBaseType"/> that specify the basic type of the array item. /// </param> /// <param name="vertexLength"> /// A <see cref="UInt32"/> that specify the number of components of the array item. /// </param> /// <param name="vertexRank"> /// A <see cref="UInt32"/> that specify the rank of the array item (matrix columns count). /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// Exception thrown if <paramref name="vertexLength"/> or <paramref name="vertexRank"/> are outside /// the valid range (greater than 0, less than or equal to 4). /// </exception> public ArrayBufferItem(VertexBaseType vertexBaseType, uint vertexLength, uint vertexRank) { if (vertexLength < 1 || vertexLength > 4) { throw new ArgumentOutOfRangeException("vertexLength", vertexLength, "must be in [1,4] range"); } if (vertexRank < 1 || vertexRank > 4) { throw new ArgumentOutOfRangeException("vertexRank", vertexRank, "must be in [1,4] range"); } ArrayType = vertexBaseType.GetArrayBufferType(vertexLength, vertexRank); }
/// <summary> /// Check whether a <see cref="VertexBaseType"/> is supported by current OpenGL implementation. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> that specify the OpenGL implementation. /// </param> /// <param name="baseType"> /// A <see cref="VertexBaseType"/> to test for support. /// </param> /// <returns> /// It returns a boolean value indicating whether vertex attributes data can be specified with vertices having /// the base type <paramref name="baseType"/>. /// </returns> public static bool IsDataSupported(GraphicsContext ctx, VertexBaseType baseType) { if (ctx == null) { throw new ArgumentNullException("ctx"); } switch (baseType) { case VertexBaseType.Half: return(ctx.Extensions.HalfFloatVertex_ARB); default: return(true); } }
/// <summary> /// Test <see cref="ArrayBufferObject.ToArray()"/>. /// </summary> /// <param name="vertexBaseType"></param> /// <param name="vertexLength"></param> /// <param name="array"></param> public void TestToArrayCtx_Core(VertexBaseType vertexBaseType, uint vertexLength, Array array) { using (ArrayBufferObject arrayBuffer = new ArrayBufferObject(vertexBaseType, vertexLength, BufferObjectHint.StaticCpuDraw)) { // Without creation, ToArray(GraphicsContext) will throw an exception Assert.Throws <InvalidOperationException>(delegate() { arrayBuffer.ToArray(_Context); }); // Create client buffer arrayBuffer.Create(array); // ToArray() must be equal to array CollectionAssert.AreEqual(array, arrayBuffer.ToArray()); // Without creation, ToArray(GraphicsContext) will throw an exception Assert.Throws <InvalidOperationException>(delegate() { arrayBuffer.ToArray(_Context); }); // Create GPU buffer arrayBuffer.Create(_Context); // ToArray() must be equal to array CollectionAssert.AreEqual(array, arrayBuffer.ToArray(_Context)); // Create a reversed array from test array Array arrayReverse = Array.CreateInstance(array.GetType().GetElementType(), array.Length); Array.Copy(array, arrayReverse, array.Length); Array.Reverse(arrayReverse); CollectionAssert.AreEquivalent(array, arrayReverse); // Update client buffer arrayBuffer.Create(arrayReverse); // Client buffer is updated, but not the GPU buffer CollectionAssert.AreEqual(arrayReverse, arrayBuffer.ToArray()); CollectionAssert.AreNotEqual(arrayReverse, arrayBuffer.ToArray(_Context)); // Update GPU buffer arrayBuffer.Create(_Context); CollectionAssert.AreEqual(arrayReverse, arrayBuffer.ToArray(_Context)); } }
public void TestToArray(VertexBaseType vertexBaseType, uint vertexLength, Array array) { TestToArray_Core(vertexBaseType, vertexLength, array); }
/// <summary> /// Construct an ArrayBufferObject specifying its item layout on CPU side. /// </summary> /// <param name="vertexBaseType"> /// A <see cref="VertexBaseType"/> describing the item components base type on CPU side. /// </param> /// <param name="vertexLength"> /// A <see cref="UInt32"/> that specify how many components have the array item. /// </param> /// <param name="vertexRank"> /// A <see cref="UInt32"/> that specify how many columns have the array item of matrix type. /// </param> /// <param name="hint"> /// An <see cref="BufferObjectHint"/> that specify the data buffer usage hints. /// </param> public ArrayBufferObject(VertexBaseType vertexBaseType, uint vertexLength, uint vertexRank, BufferObjectHint hint) : this(ArrayBufferItem.GetArrayType(vertexBaseType, vertexLength, vertexRank), hint) { }
/// <summary> /// Get the corresponding <see cref="ArrayBufferItemType"/> from a set of parameters. /// </summary> /// <param name="baseType"> /// A <see cref="VertexBaseType"/> indicating the type of the components of the vertex array buffer item. /// </param> /// <param name="length"> /// A <see cref="UInt32"/> indicating the length of the vertex array buffer item. /// </param> /// <returns> /// It returns a <see cref="ArrayBufferItemType"/> having a base type equals to <paramref name="baseType"/>, a /// length equals to <paramref name="length"/> and a rank equals to 1 (implicit). /// </returns> public static ArrayBufferItemType GetArrayBufferType(VertexBaseType baseType, uint length) { return(baseType.GetArrayBufferType(length, 1)); }
/// <summary> /// Construct an ArrayBufferItem specifying the vertex base type and the array item length. /// </summary> /// <param name="vertexBaseType"> /// A <see cref="VertexBaseType"/> that specify the basic type of the array item. /// </param> /// <param name="vertexLength"> /// A <see cref="UInt32"/> that specify the number of components of the array item. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// Exception thrown if <paramref name="vertexLength"/> is outside the valid range (greater than 0, /// less than or equal to 4). /// </exception> public ArrayBufferItem(VertexBaseType vertexBaseType, uint vertexLength) : this(vertexBaseType, vertexLength, 1) { }
/// <summary> /// Construct an ArrayBufferItemAttribute for matrix items. /// </summary> /// <param name="arrayType"> /// A <see cref="VertexBaseType"/> describing the matrix components type. /// </param> /// <param name="matrixColumns"> /// A <see cref="System.UInt32"/> that specify the matrix columns count. /// </param> /// <param name="matrixRows"> /// A <see cref="System.UInt32"/> that specify the matrix rows count. /// </param> public ArrayBufferItemAttribute(VertexBaseType arrayType, uint matrixColumns, uint matrixRows) { mArrayType = arrayType; mArrayLength = matrixRows; mArrayRank = matrixColumns; }
/// <summary> /// Construct an ArrayBufferItemAttribute for vector items. /// </summary> /// <param name="arrayType"> /// A <see cref="VertexBaseType"/> describing the vector components type. /// </param> /// <param name="arrayLength"> /// A <see cref="System.UInt32"/> that specify the vector length. /// </param> public ArrayBufferItemAttribute(VertexBaseType arrayType, uint arrayLength) : this(arrayType, 1, arrayLength) { }
/// <summary> /// Construct an ArrayBufferItemAttribute for vector items. /// </summary> /// <param name="arrayType"> /// A <see cref="VertexBaseType"/> describing the vector components type. /// </param> /// <param name="arrayLength"> /// A <see cref="UInt32"/> that specify the vector length. /// </param> public ArrayBufferItemAttribute(VertexBaseType arrayType, uint arrayLength) : this(arrayType, 1, arrayLength) { }
/// <summary> /// Get the corresponding <see cref="ArrayBufferItemType"/> from a set of parameters. /// </summary> /// <param name="baseType"> /// A <see cref="VertexBaseType"/> indicating the type of the components of the vertex array buffer item. /// </param> /// <param name="length"> /// A <see cref="UInt32"/> indicating the length of the vertex array buffer item. /// </param> /// <param name="rank"> /// A <see cref="UInt32"/> indicating the rank of the vertex array buffer item. /// </param> /// <returns> /// It returns a <see cref="ArrayBufferItemType"/> having a base type equals to <paramref name="baseType"/>, a /// length equals to <paramref name="length"/> and a rank equals to <paramref name="rank"/>. /// </returns> public static ArrayBufferItemType GetArrayBufferType(this VertexBaseType baseType, uint length, uint rank) { if ((length < 1) || (length > 4)) { throw new ArgumentOutOfRangeException("length", length, "it must be in the range [1..4]"); } if ((rank < 1) || (rank > 4)) { throw new ArgumentOutOfRangeException("rank", rank, "it must be in the range [1..4]"); } if ((rank > 1) && (length == 1)) { throw new InvalidOperationException("bad combination of rank and length"); } switch (baseType) { #region VertexBaseType.Byte case VertexBaseType.Byte: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Byte); case 2: return(ArrayBufferItemType.Byte2); case 3: return(ArrayBufferItemType.Byte3); case 4: return(ArrayBufferItemType.Byte4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Byte with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Byte with rank {0}", rank)); } #endregion #region VertexBaseType.UByte case VertexBaseType.UByte: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.UByte); case 2: return(ArrayBufferItemType.UByte2); case 3: return(ArrayBufferItemType.UByte3); case 4: return(ArrayBufferItemType.UByte4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UByte with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UByte with rank {0}", rank)); } #endregion #region VertexBaseType.Short case VertexBaseType.Short: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Short); case 2: return(ArrayBufferItemType.Short2); case 3: return(ArrayBufferItemType.Short3); case 4: return(ArrayBufferItemType.Short4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Short with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Short with rank {0}", rank)); } #endregion #region VertexBaseType.UShort case VertexBaseType.UShort: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.UShort); case 2: return(ArrayBufferItemType.UShort2); case 3: return(ArrayBufferItemType.UShort3); case 4: return(ArrayBufferItemType.UShort4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UShort with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UShort with rank {0}", rank)); } #endregion #region VertexBaseType.Int case VertexBaseType.Int: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Int); case 2: return(ArrayBufferItemType.Int2); case 3: return(ArrayBufferItemType.Int3); case 4: return(ArrayBufferItemType.Int4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Int with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Int with rank {0}", rank)); } #endregion #region VertexBaseType.UInt case VertexBaseType.UInt: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.UInt); case 2: return(ArrayBufferItemType.UInt2); case 3: return(ArrayBufferItemType.UInt3); case 4: return(ArrayBufferItemType.UInt4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UInt with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of UInt with rank {0}", rank)); } #endregion #region VertexBaseType.Float case VertexBaseType.Float: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Float); case 2: return(ArrayBufferItemType.Float2); case 3: return(ArrayBufferItemType.Float3); case 4: return(ArrayBufferItemType.Float4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Float with rank {0} and length {1}", rank, length)); } case 2: switch (length) { case 2: return(ArrayBufferItemType.Float2x2); case 3: return(ArrayBufferItemType.Float2x3); case 4: return(ArrayBufferItemType.Float2x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Float with rank {0} and length {1}", rank, length)); } case 3: switch (length) { case 2: return(ArrayBufferItemType.Float3x2); case 3: return(ArrayBufferItemType.Float3x3); case 4: return(ArrayBufferItemType.Float3x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Float with rank {0} and length {1}", rank, length)); } case 4: switch (length) { case 2: return(ArrayBufferItemType.Float4x2); case 3: return(ArrayBufferItemType.Float4x3); case 4: return(ArrayBufferItemType.Float4x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Float with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Float with rank {0}", rank)); } #endregion #region VertexBaseType.Double case VertexBaseType.Double: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Double); case 2: return(ArrayBufferItemType.Double2); case 3: return(ArrayBufferItemType.Double3); case 4: return(ArrayBufferItemType.Double4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Double with rank {0} and length {1}", rank, length)); } case 2: switch (length) { case 2: return(ArrayBufferItemType.Double2x2); case 3: return(ArrayBufferItemType.Double2x3); case 4: return(ArrayBufferItemType.Double2x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Double with rank {0} and length {1}", rank, length)); } case 3: switch (length) { case 2: return(ArrayBufferItemType.Double3x2); case 3: return(ArrayBufferItemType.Double3x3); case 4: return(ArrayBufferItemType.Double3x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Double with rank {0} and length {1}", rank, length)); } case 4: switch (length) { case 2: return(ArrayBufferItemType.Double4x2); case 3: return(ArrayBufferItemType.Double4x3); case 4: return(ArrayBufferItemType.Double4x4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Double with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Double with rank {0}", rank)); } #endregion #region VertexBaseType.Half case VertexBaseType.Half: switch (rank) { case 1: switch (length) { case 1: return(ArrayBufferItemType.Half); case 2: return(ArrayBufferItemType.Half2); case 3: return(ArrayBufferItemType.Half3); case 4: return(ArrayBufferItemType.Half4); default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Half with rank {0} and length {1}", rank, length)); } default: throw new NotSupportedException(String.Format("unsupported vertex array base type of Half with rank {0}", rank)); } #endregion default: throw new NotSupportedException(String.Format("unsupported vertex array base type of {0}", baseType)); } }
/// <summary> /// Construct an ArrayBufferObject specifying its item layout on CPU side. /// </summary> /// <param name="vertexBaseType"> /// A <see cref="VertexBaseType"/> describing the item components base type on CPU side. /// </param> /// <param name="vertexLength"> /// A <see cref="UInt32"/> that specify how many components have the array item. /// </param> /// <param name="hint"> /// An <see cref="BufferObjectHint"/> that specify the data buffer usage hints. /// </param> public ArrayBufferObject(VertexBaseType vertexBaseType, uint vertexLength, BufferObjectHint hint) : this(vertexBaseType, vertexLength, 1, hint) { }