/// <summary></summary> /// <param name="shaderProvider"></param> public ShaderProviderFlag(BatchModelShaderProvider shaderProvider) { this.overrideShaderProvider = true; this.shaderProvider = shaderProvider; }
/// <summary> /// Extend the <see cref="BatchModelShaderProvider"/> abstract class to override shaders used by this batch model /// </summary> /// <param name="provider"></param> public void SetShaderOverride(BatchModelShaderProvider provider) { shaderProvider = provider; }
/// <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; }