/// <summary> /// Function to create a vertex buffer and its binding. /// </summary> /// <typeparam name="T">The type of data representing a vertex, must be an unmanaged value type.</typeparam> /// <param name="graphics">The graphics interface that will create the buffer.</param> /// <param name="vertexCount">The total number vertices that the buffer can hold.</param> /// <param name="usage">[Optional] The intended usage for the buffer.</param> /// <param name="binding">[Optional] The binding options for the buffer.</param> /// <param name="initialData">[Optional] An initial set of vertex data to send to the buffer.</param> /// <param name="bindingIndex">[Optional] The index, in vertices, inside the buffer where binding is to begin.</param> /// <param name="bufferName">[Optional] A name for the buffer.</param> /// <returns>A new <see cref="GorgonVertexBufferBinding"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="graphics"/> parameter is <b>null</b>.</exception> /// <remarks> /// <para> /// Use this to quickly create a vertex buffer and its binding based on a known vertex data type. /// </para> /// <para> /// Be aware that the <see cref="VertexBuffer"/> created by this method must be disposed manually after it is no longer of any use. /// </para> /// </remarks> /// <seealso cref="GorgonVertexBuffer"/> public static GorgonVertexBufferBinding CreateVertexBuffer <T>(GorgonGraphics graphics, int vertexCount, ResourceUsage usage = ResourceUsage.Default, VertexIndexBufferBinding binding = VertexIndexBufferBinding.None, GorgonNativeBuffer <T> initialData = null, int bindingIndex = 0, string bufferName = null) where T : unmanaged { if (graphics == null) { throw new ArgumentNullException(nameof(graphics)); } int vertexSize = Unsafe.SizeOf <T>(); var buffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo(bufferName) { SizeInBytes = vertexCount * vertexSize, Binding = binding, Usage = usage }, initialData?.Cast <byte>()); return(new GorgonVertexBufferBinding(buffer, vertexSize, bindingIndex * vertexSize)); }
/// <summary> /// Initializes a new instance of the <see cref="Cube" /> class. /// </summary> /// <param name="graphics">The graphics interface.</param> /// <param name="size">The width, height and depth of the cube.</param> /// <param name="textureCoordinates">The texture coordinates for the faces of the cube.</param> /// <param name="angle">The initial orientation of the cube, in degrees.</param> /// <param name="columnsPerFace">The number of columns per face.</param> /// <param name="rowsPerFace">The number of rows per face.</param> public Cube(GorgonGraphics graphics, DX.Vector3 size, RectangleF textureCoordinates, DX.Vector3 angle, int columnsPerFace = 1, int rowsPerFace = 1) : base(graphics) { PrimitiveType = PrimitiveType.TriangleList; int faceVertexCount = (columnsPerFace + 1) * (rowsPerFace + 1); int faceIndexCount = (columnsPerFace * rowsPerFace) * 6; VertexCount = faceVertexCount * 6; IndexCount = faceIndexCount * 6; TriangleCount = IndexCount / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { // Front. GetVertices(vertexData, 0, DX.Vector3.UnitY, -DX.Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace); // Bottom. GetVertices(vertexData, faceVertexCount, -DX.Vector3.UnitZ, -DX.Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace); // Back. GetVertices(vertexData, faceVertexCount * 2, DX.Vector3.UnitY, DX.Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace); // Top. GetVertices(vertexData, faceVertexCount * 3, DX.Vector3.UnitZ, DX.Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace); // Left. GetVertices(vertexData, faceVertexCount * 4, DX.Vector3.UnitY, -DX.Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace); // Right GetVertices(vertexData, faceVertexCount * 5, DX.Vector3.UnitY, DX.Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace); GetIndices(indexData, 0, 0, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount, faceVertexCount, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 2, faceVertexCount * 2, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 3, faceVertexCount * 3, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 4, faceVertexCount * 4, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 5, faceVertexCount * 5, columnsPerFace, rowsPerFace); CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("CubeVB") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("CubeIB") { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <summary> /// Function to create a vertex buffer and its binding. /// </summary> /// <typeparam name="T">The type of data representing a vertex, must be an unmanaged value type.</typeparam> /// <param name="graphics">The graphics interface that will create the buffer.</param> /// <param name="info">Information about the buffer to create.</param> /// <param name="initialData">[Optional] An initial set of vertex data to send to the buffer.</param> /// <param name="bindingIndex">[Optional] The index, in vertices, inside the buffer where binding is to begin.</param> /// <returns>A new <see cref="GorgonVertexBufferBinding"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="graphics"/>, or the <paramref name="info"/> parameter is <b>null</b>.</exception> /// <remarks> /// <para> /// Use this to quickly create a vertex buffer and its binding based on a known vertex data type. /// </para> /// <para> /// Be aware that the <see cref="VertexBuffer"/> created by this method must be disposed manually after it is no longer of any use. /// </para> /// </remarks> /// <seealso cref="GorgonVertexBuffer"/> public static GorgonVertexBufferBinding CreateVertexBuffer <T>(GorgonGraphics graphics, IGorgonVertexBufferInfo info, GorgonNativeBuffer <T> initialData = null, int bindingIndex = 0) where T : unmanaged { if (graphics == null) { throw new ArgumentNullException(nameof(graphics)); } if (info == null) { throw new ArgumentNullException(nameof(info)); } var buffer = new GorgonVertexBuffer(graphics, info, initialData?.Cast <byte>()); int vertexSize = Unsafe.SizeOf <T>(); return(new GorgonVertexBufferBinding(buffer, vertexSize, bindingIndex * vertexSize)); }
/// <summary> /// Initializes a new instance of the <see cref="Sphere" /> class. /// </summary> /// <param name="graphics">Graphics interface to use.</param> /// <param name="radius">Radius of the sphere</param> /// <param name="textureCoordinates">The texture coordinates to apply to the sphere.</param> /// <param name="angle">The angle of rotation, in degrees.</param> /// <param name="ringCount">Number of rings in the sphere.</param> /// <param name="segmentCount">Number of segments in the sphere.</param> public Sphere(GorgonGraphics graphics, float radius, RectangleF textureCoordinates, DX.Vector3 angle, int ringCount = 8, int segmentCount = 16) : base(graphics) { // Calculate number of vertices and indices required for our sphere. PrimitiveType = PrimitiveType.TriangleList; VertexCount = (ringCount + 1) * (segmentCount + 1); IndexCount = 6 * ringCount * (segmentCount + 1); TriangleCount = IndexCount / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { GetVertices(vertexData, indexData, radius, textureCoordinates, ringCount, segmentCount); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("SphereVertexBuffer") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("SphereIndexBuffer") { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <summary> /// Initializes a new instance of the <see cref="Triangle" /> class. /// </summary> /// <param name="graphics">The graphics interface.</param> /// <param name="point1">The 1st point in the triangle.</param> /// <param name="point2">The 2nd point in the triangle.</param> /// <param name="point3">The 3rd point in the triangle.</param> public Triangle(GorgonGraphics graphics, Vertex3D point1, Vertex3D point2, Vertex3D point3) : base(graphics) { PrimitiveType = PrimitiveType.TriangleList; VertexCount = 3; IndexCount = 3; TriangleCount = 1; point1.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); point2.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); point3.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); using (var points = new GorgonNativeBuffer <Vertex3D>(3)) using (var indices = new GorgonNativeBuffer <int>(3)) { points[0] = point1; points[1] = point2; points[2] = point3; indices[0] = 0; indices[1] = 1; indices[2] = 2; VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("TriVB") { Usage = ResourceUsage.Immutable, SizeInBytes = Vertex3D.Size * 3 }, points.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("TriIB") { Usage = ResourceUsage.Dynamic, Use16BitIndices = false, IndexCount = 3 }, indices); } }
/// <summary> /// Initializes a new instance of the <see cref="Plane" /> class. /// </summary> /// <param name="graphics">The graphics interface to use.</param> /// <param name="size">The width and height of the plane.</param> /// <param name="textureCoordinates">The texture coordinates to apply to the plane.</param> /// <param name="angle">The initial orientation, in degrees.</param> /// <param name="columns">The number of columns to subdivide by.</param> /// <param name="rows">The number of rows to subdivide by.</param> public Plane(GorgonGraphics graphics, DX.Vector2 size, RectangleF textureCoordinates, DX.Vector3 angle, int columns = 1, int rows = 1) : base(graphics) { PrimitiveType = PrimitiveType.TriangleStrip; VertexCount = (columns + 1) * (rows + 1); IndexCount = ((columns * rows) * 6) + (rows - 1); TriangleCount = (IndexCount - (rows - 1)) / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { GetVertices(vertexData, size, textureCoordinates, columns, rows); GetIndices(indexData, columns, rows); CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("PlaneVB") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }