/// <summary></summary> /// <param name="state"></param> protected sealed override void DrawElement(DrawState state) { if (state.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum) { Matrix identity = Matrix.Identity; state.PushWorldMatrix(ref identity); state.DrawBatch(vertices, indices, PrimitiveType.TriangleList, null, instances, instanceCount); state.PopWorldMatrix(); } else { Graphics2D.NonInstancingSprite shader = state.GetShader <Graphics2D.NonInstancingSprite>(); for (int i = 0; i < instanceCount; i += NonInstancingRenderCount) { int count = Math.Min(NonInstancingRenderCount, (instanceCount - i)); shader.Instances.SetArray(this.instances, i); this.verticesSI.Draw(state, this.indicesSI, PrimitiveType.TriangleList, 2 * count, 0, 0); } } }
/// <summary> /// Draw multiple instances of this cube geometry /// </summary> /// <param name="state"></param> /// <param name="CanDrawItem"></param> /// <param name="instances"></param> /// <param name="instanceCount"></param> public void DrawBatch(DrawState state, Callback <bool, int, ICuller> CanDrawItem, Matrix[] instances, int instanceCount) { state.DrawBatch(verts, inds, PrimitiveType.TriangleList, CanDrawItem, instances, instanceCount); }
/// <summary> /// Draw all the model batch instances /// </summary> /// <param name="state"></param> public void Draw(DrawState state) { if (modelData == null) { throw new InvalidOperationException("ModelData is null"); } if (geometry == null) { SetupGeometry(); } int geometryIndex = 0; BatchModelShaderProvider shaderProvider = this.shaderProvider; MaterialLightCollection lights = this.lights; ShaderProviderFlag providerFlag; MaterialLightCollection.LightCollectionFlag lightsFlag; state.GetDrawFlag(out providerFlag); if (providerFlag.OverrideShaderProvider) { shaderProvider = providerFlag.ShaderProvider; } state.GetDrawFlag(out lightsFlag); if (lightsFlag.OverrideLightCollection) { lights = lightsFlag.LightCollection; } if (shaderProvider != null) { shaderProvider.BeginDraw(state); } //loop through the model data for (int m = 0; m < modelData.meshes.Length; m++) { MeshData mesh = modelData.meshes[m]; if (shaderProvider != null) { shaderProvider.BeginMesh(state, mesh); } for (int g = 0; g < mesh.geometry.Length; g++) { GeometryData geom = mesh.geometry[g]; GeometrySet set = this.geometry[geometryIndex]; if (set.count > 0) { bool instancing = state.SupportsHardwareInstancing && set.count > 2; if (shaderProvider == null || !shaderProvider.BeginGeometryShaderOverride(state, geom, lights, instancing)) { MaterialShader shader = geom.MaterialShader; shader.AnimationTransforms = null; shader.UseHardwareInstancing = instancing; shader.Lights = lights; shader.Bind(state); } //draw the geometry if (instancing) { state.DrawBatch(geom.Vertices, geom.Indices, PrimitiveType.TriangleList, null, set.instances, set.count); } else { for (int i = 0; i < set.count; i++) { state.PushWorldMatrixMultiply(ref set.instances[i]); geom.Vertices.Draw(state, geom.Indices, PrimitiveType.TriangleList); state.PopWorldMatrix(); } } if (shaderProvider != null) { shaderProvider.EndGeometry(state, geom); } } set.count = 0; geometryIndex++; } if (shaderProvider != null) { shaderProvider.EndMesh(state, mesh); } } if (shaderProvider != null) { shaderProvider.EndDraw(state); } drawCount = 0; }