/// <summary> /// Retrieves or creates the primitive batch for the specified vertex type /// </summary> /// <typeparam name="VertexType"> /// Vertex type a primitive batch will be returned for /// </typeparam> /// <returns>A primitive batch that renders the specified vertex type</returns> private PrimitiveBatchHolder <VertexType> getOrCreatePrimitiveBatch <VertexType>() where VertexType : struct, IVertexType { PrimitiveBatchHolder holder; // Find out if we a primitive batch and vertex declaration already exist if (this.primitiveBatches.TryGetValue(typeof(VertexType), out holder)) { // Yes, add another reference to this primitive batch and vertex declaration ++holder.ReferenceCount; return(holder as PrimitiveBatchHolder <VertexType>); } else // No, let's create one // Create the primitive batch for rendering this vertex structure { PrimitiveBatchHolder <VertexType> newHolder; #if UNITTEST if (this.InducePrimitiveBatchErrorDelegate != null) { this.InducePrimitiveBatchErrorDelegate(); } #endif newHolder = new PrimitiveBatchHolder <VertexType>( this, new PrimitiveBatch <VertexType>(GraphicsDevice) ); this.primitiveBatches.Add(typeof(VertexType), newHolder); this.holderArraysDirty = true; return(newHolder); } }
/// <summary>Initializes a new particle system holder</summary> /// <param name="particleSystem">Particle system the holder will manage</param> /// <param name="renderer"> /// Renderer through which the particles are sent to the primitive batch /// </param> /// <param name="pruneDelegate"> /// Method which will be used to detect dead particles /// </param> /// <param name="primitiveBatchHolder"> /// Primitive batch holder that manages the primitive batch used to /// render the vertices generated by this particle system /// </param> public ParticleSystemHolder( ParticleSystem <ParticleType> particleSystem, ParticleSystem <ParticleType> .PrunePredicate pruneDelegate, IParticleRenderer <ParticleType, VertexType> renderer, PrimitiveBatchHolder <VertexType> primitiveBatchHolder ) { if (renderer == null) { throw new ArgumentException("You must specify a renderer", "renderer"); } this.particleSystem = particleSystem; this.pruneDelegate = pruneDelegate; this.renderer = renderer; this.primitiveBatchHolder = primitiveBatchHolder; }
/// <summary>Registers the specified vertex type for particle systems</summary> /// <typeparam name="VertexType">Type of vertex that will be registered</typeparam> /// <param name="vertexDeclaration"> /// Vertex declaration describing the vertex structure to the graphics device /// </param> /// <param name="stride">Offset, in bytes, from one vertex to the next</param> /// <param name="takeOwnership"> /// Whether the particle system manager takes ownership of the vertex declaration /// and will destroy it upon shutdown /// </param> /// <remarks> /// <para> /// Registering a vertex type is only required when the vertex declaration can not /// be automatically extracted from the vertex structure (eg. you didn't use /// VertexElementAttribute to describe your fields). /// </para> /// <para> /// If the vertex type is used by the particle system manager throughout its /// lifespan, it's okay to not call unregister and rely on Dispose() doing /// the clean-up work. /// </para> /// </remarks> public void RegisterVertex <VertexType>( VertexDeclaration vertexDeclaration, int stride, bool takeOwnership ) where VertexType : struct { // Check whether a vertex declaration and primitive batch already exist for // this vertex type. If so, turn it into an explicitly registered one. PrimitiveBatchHolder holder; if (this.primitiveBatches.TryGetValue(typeof(VertexType), out holder)) { // If this was set by explicit registration, complain if (holder.ExplicitlyRegistered) { throw new ArgumentException("Vertex type is already registered", "VertexType"); } holder.ExplicitlyRegistered = true; // If this point is reached, it's clear that we have ownership of // the old vertex declaration and need to destroy it. holder.OwnedVertexDeclaration.Dispose(); holder.OwnedVertexDeclaration = takeOwnership ? vertexDeclaration : null; // Make sure this primitive batch will be kept alive even if no particle systems // use it any longer. Registration counts as one reference to prevent us from // falling back to an autogenerated vertex declaration when the particle system // using it is removed from the manager and then re-added. ++holder.ReferenceCount; } else // No vertex declaration and primitive batch for this vertex type yet { holder = new PrimitiveBatchHolder <VertexType>( this, new PrimitiveBatch <VertexType>(GraphicsDevice, vertexDeclaration, stride), takeOwnership ? vertexDeclaration : null ); holder.ExplicitlyRegistered = true; // Create a new primitive batch and take over the vertex declaration this.primitiveBatches.Add(typeof(VertexType), holder); this.holderArraysDirty = true; } }