/// <summary> /// Function to return the object. /// </summary> /// <returns>The object created or updated by this builder.</returns> /// <exception cref="GorgonException">Thrown if the polygonal sprite has less than 3 vertices.</exception> /// <remarks> /// <para> /// This will return a <see cref="GorgonPolySprite"/> for use with the <see cref="Gorgon2D.DrawPolygonSprite"/> method. The object returned implements <see cref="IDisposable"/>, so it is the /// responsibility of the user to dispose of the object when they are done with it. /// </para> /// <para> /// <note type="warning"> /// <para> /// A polygon sprite must have a minimum of 3 vertices. If it does not, then this method will throw an exception. /// </para> /// </note> /// </para> /// </remarks> /// <seealso cref="GorgonPolySprite"/> /// <seealso cref="Gorgon2D"/> public GorgonPolySprite Build() { if (_workingSprite.RwVertices.Count < 3) { throw new GorgonException(GorgonResult.CannotCreate, Resources.GOR2D_ERR_POLY_SPRITE_NOT_ENOUGH_VERTS); } var newSprite = new GorgonPolySprite(); CopySprite(newSprite, _workingSprite); newSprite.Renderable.ActualVertexCount = newSprite.RwVertices.Count; if ((newSprite.Renderable.Vertices == null) || (newSprite.Renderable.Vertices.Length < newSprite.RwVertices.Count)) { newSprite.Renderable.Vertices = new Gorgon2DVertex[newSprite.RwVertices.Count]; } for (int i = 0; i < newSprite.RwVertices.Count; ++i) { newSprite.Renderable.Vertices[i] = newSprite.RwVertices[i].Vertex; } // Enforce clockwise ordering. _triangulator.EnsureWindingOrder(newSprite.Renderable.Vertices, WindingOrder.CounterClockwise); // Split the polygon hull into triangles. (GorgonNativeBuffer <int> indices, DX.RectangleF bounds) = _triangulator.Triangulate(newSprite.Renderable.Vertices, WindingOrder.CounterClockwise); GorgonNativeBuffer <Gorgon2DVertex> vertexData = newSprite.Renderable.Vertices.ToNativeBuffer(); try { newSprite.Renderable.IndexBuffer = new GorgonIndexBuffer(Graphics, new GorgonIndexBufferInfo { Binding = VertexIndexBufferBinding.None, Use16BitIndices = false, IndexCount = indices.Length, Usage = ResourceUsage.Immutable }, indices); newSprite.Renderable.VertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer(Graphics, new GorgonVertexBufferInfo { Usage = ResourceUsage.Immutable, Binding = VertexIndexBufferBinding.None, SizeInBytes = Gorgon2DVertex.SizeInBytes * newSprite.RwVertices.Count }, vertexData); newSprite.Renderable.ActualVertexCount = newSprite.RwVertices.Count; newSprite.Renderable.IndexCount = indices.Length; newSprite.Bounds = new DX.RectangleF(newSprite.Position.X, newSprite.Position.Y, bounds.Width, bounds.Height); } finally { vertexData?.Dispose(); indices?.Dispose(); } return(newSprite); }