using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework.Graphics; namespace SharpGLTF.Runtime { /// /// Replaces . /// sealed class RuntimeModelMeshPart { #region lifecycle internal RuntimeModelMeshPart(RuntimeModelMesh parent) { _Parent = parent; } #endregion #region data private readonly RuntimeModelMesh _Parent; private Effect _Effect; private IndexBuffer _IndexBuffer; private int _IndexOffset; private int _PrimitiveCount; private VertexBuffer _VertexBuffer; private int _VertexOffset; private int _VertexCount; public object Tag { get; set; } #endregion #region properties public Effect Effect { get => _Effect; set { if (_Effect == value) return; _Effect = value; _Parent.InvalidateEffectCollection(); // if we change this property, we need to invalidate the parent's effect collection. } } public GraphicsDevice Device => _Parent._GraphicsDevice; #endregion #region API public void SetVertexBuffer(VertexBuffer vb, int offset, int count) { this._VertexBuffer = vb; this._VertexOffset = offset; this._VertexCount = count; } public void SetIndexBuffer(IndexBuffer ib, int offset, int count) { this._IndexBuffer = ib; this._IndexOffset = offset; this._PrimitiveCount = count; } public void Draw(GraphicsDevice device) { if (_PrimitiveCount > 0) { device.SetVertexBuffer(_VertexBuffer); device.Indices = _IndexBuffer; for (int j = 0; j < _Effect.CurrentTechnique.Passes.Count; j++) { _Effect.CurrentTechnique.Passes[j].Apply(); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, _VertexOffset, _IndexOffset, _PrimitiveCount); } } } #endregion } /// /// Replaces /// sealed class RuntimeModelMesh { #region lifecycle public RuntimeModelMesh(GraphicsDevice graphicsDevice) { this._GraphicsDevice = graphicsDevice; } #endregion #region data internal GraphicsDevice _GraphicsDevice; private readonly List _Primitives = new List(); private IReadOnlyList _Effects; private Microsoft.Xna.Framework.BoundingSphere? _Sphere; #endregion #region properties public IReadOnlyCollection Effects { get { if (_Effects != null) return _Effects; // Create the shared effects collection on demand. _Effects = _Primitives .Select(item => item.Effect) .Distinct() .ToArray(); return _Effects; } } public Microsoft.Xna.Framework.BoundingSphere BoundingSphere { set => _Sphere = value; get { if (_Sphere.HasValue) return _Sphere.Value; return default; } } public IReadOnlyList MeshParts => _Primitives; public string Name { get; set; } public ModelBone ParentBone { get; set; } public object Tag { get; set; } #endregion #region API internal void InvalidateEffectCollection() { _Effects = null; } public RuntimeModelMeshPart CreateMeshPart() { var primitive = new RuntimeModelMeshPart(this); _Primitives.Add(primitive); InvalidateEffectCollection(); _Sphere = null; return primitive; } public void Draw() { for (int i = 0; i < _Primitives.Count; i++) { _Primitives[i].Draw(_GraphicsDevice); } } #endregion } }