/// <summary> /// [Requires <see cref="SupportsHardwareInstancing"/>] Draws multiple instances of a vertex buffer in an efficient way, using an optional callback to determine if an instance should be drawn. Using Shader Instancing is highly recommended for smaller batches of simple geometry. /// </summary> /// <param name="vertices">Vertex buffer of the instances to be drawn</param> /// <param name="indices">Index buffer of the instances to be drawn</param> /// <param name="primitiveType">Primitive type to be drawn</param> /// <param name="CanDrawItem">[optional] callback to determine if an instance index should be drawn or not (may be null)</param> /// <param name="instances">Array of instances to draw</param> /// <param name="instancesLength">Number of instances in the array to draw</param> /// <returns>number of instances drawn</returns> /// <param name="startIndex">starting index in the <paramref name="instances"/> array</param> public int DrawBatch(Xen.Graphics.IVertices vertices, Graphics.IIndices indices, PrimitiveType primitiveType, Callback <bool, int, ICuller> CanDrawItem, Vector3[] instances, int instancesLength, int startIndex) { ValidateProtected(); if (instancesLength == 0) { return(0); } StreamBuffer buffer = GetBuffer(instancesLength); int start; Graphics.StreamFrequency.InstanceMatrix[] instanceMartixData = buffer.Prepare(out start); int count = 0; if (CanDrawItem != null) { ICuller culler = this; for (int i = 0; i < instancesLength; i++) { PushWorldTranslateMultiply(ref instances[i + startIndex]); if (CanDrawItem(i + startIndex, culler)) { GetWorldMatrix(ref instanceMartixData[start++]); count++; } PopWorldMatrix(); } } else { if (ms_World.isIdentity || (instancesLength > 4 && ms_World.value == Matrix.Identity)) { for (int i = 0; i < instancesLength; i++) { instanceMartixData[start++].Set(ref instances[i + startIndex]); } count = instancesLength; } else { for (int i = 0; i < instancesLength; i++) { PushWorldTranslateMultiply(ref instances[i + startIndex]); instanceMartixData[start].Set(ref ms_World.value); start++; count++; PopWorldMatrix(); } } } return(DrawBatch(buffer.Fill(vertices, count), indices, primitiveType, count)); }
/// <summary> /// [Requires <see cref="SupportsHardwareInstancing"/>] Complete a batch draw process (being with <see cref="BeginDrawBatch"/>) /// </summary> /// <param name="vertices">Vertex buffer of the instances to be drawn</param> /// <param name="indices">Index buffer of the instances to be drawn</param> /// <param name="primitiveType">Primitive type to be drawn</param> /// <param name="instances">Instance buffer that contains the instances to be drawn</param> public void EndDrawBatch(Xen.Graphics.IVertices vertices, Graphics.IIndices indices, PrimitiveType primitiveType, Graphics.StreamFrequency.InstanceBuffer instances) { ValidateProtected(); if (instances == null) { throw new ArgumentNullException(); } if (instances.InstanceCount == 0) { return; } DrawBatch(((StreamBuffer)instances.instanceBuffer).Fill(vertices, instances.InstanceCount), indices, primitiveType, instances.InstanceCount); }
/// <summary> /// [Requires <see cref="SupportsHardwareInstancing"/>] Draws multiple instances of a vertex buffer in an efficient way, using an optional callback to determine if an instance should be drawn. Using Shader Instancing is highly recommended for smaller batches of simple geometry. /// </summary> /// <param name="vertices">Vertex buffer of the instances to be drawn</param> /// <param name="indices">Index buffer of the instances to be drawn</param> /// <param name="primitiveType">Primitive type to be drawn</param> /// <param name="CanDrawItem">[optional] callback to determine if an instance index should be drawn or not (may be null)</param> /// <param name="instances">Array of instances to draw</param> /// <param name="instancesLength">Number of instances in the array to draw</param> /// <returns>number of instances drawn</returns> public int DrawBatch(Xen.Graphics.IVertices vertices, Graphics.IIndices indices, PrimitiveType primitiveType, Callback <bool, int, ICuller> CanDrawItem, Vector3[] instances, int instancesLength) { return(DrawBatch(vertices, indices, primitiveType, CanDrawItem, instances, instancesLength, 0)); }
/// <summary> /// [Requires <see cref="SupportsHardwareInstancing"/>] Draws multiple instances of a vertex buffer in an efficient way, using an optional callback to determine if an instance should be drawn. Using Shader Instancing is highly recommended for smaller batches of simple geometry. /// </summary> /// <param name="vertices">Vertex buffer of the instances to be drawn</param> /// <param name="indices">Index buffer of the instances to be drawn</param> /// <param name="primitiveType">Primitive type to be drawn</param> /// <param name="CanDrawItem">[optional] callback to determine if an instance index should be drawn or not (may be null)</param> /// <param name="instances">Array of instances to draw</param> /// <returns>number of instances drawn</returns> public int DrawBatch(Xen.Graphics.IVertices vertices, Graphics.IIndices indices, PrimitiveType primitiveType, Callback <bool, int, ICuller> CanDrawItem, params Matrix[] instances) { return(DrawBatch(vertices, indices, primitiveType, CanDrawItem, instances, instances.Length)); }