internal void BuildRenderList(RenderList renderList, RenderInstanceData instanceData, MeshEffect effect) { var uniquePipelineStates = MaterialPasses .SelectMany(x => x.MeshParts.Select(y => y.PipelineStateHandle)) .Distinct() .ToList(); foreach (var pipelineStateHandle in uniquePipelineStates) { var filteredMaterialPasses = MaterialPasses .Where(x => x.MeshParts.Any(y => y.PipelineStateHandle == pipelineStateHandle)) .ToList(); if (filteredMaterialPasses.Count > 0) { renderList.AddRenderItem(new InstancedRenderItem( instanceData, effect, pipelineStateHandle, (commandEncoder, e, h, _) => { Draw( commandEncoder, effect, h, filteredMaterialPasses, instanceData); })); } } }
private void Draw( CommandEncoder commandEncoder, MeshEffect meshEffect, EffectPipelineStateHandle pipelineStateHandle, IEnumerable <ModelMeshMaterialPass> materialPasses, RenderInstanceData instanceData) { commandEncoder.SetVertexBuffer(2, instanceData.WorldBuffer); if (Skinned) { meshEffect.SetSkinningBuffer(instanceData.SkinningBuffer); meshEffect.SetNumBones(NumBones); } meshEffect.SetSkinningEnabled(Skinned); meshEffect.SetMaterials(_materialsBuffer); meshEffect.SetTextures(_textures); commandEncoder.SetVertexBuffer(0, _vertexBuffer); foreach (var materialPass in materialPasses) { meshEffect.SetTextureIndices(materialPass.TextureIndicesBuffer); meshEffect.SetMaterialIndices(materialPass.MaterialIndicesBuffer); meshEffect.SetNumTextureStages(materialPass.NumTextureStages); commandEncoder.SetVertexBuffer(1, materialPass.TexCoordVertexBuffer); foreach (var meshPart in materialPass.MeshParts) { if (meshPart.PipelineStateHandle != pipelineStateHandle) { continue; } meshEffect.SetPrimitiveOffset(meshPart.StartIndex / 3); meshEffect.SetAlphaTest(meshPart.AlphaTest); meshEffect.SetTexturing(meshPart.Texturing); meshEffect.Apply(commandEncoder); commandEncoder.DrawIndexedInstanced( PrimitiveType.TriangleList, meshPart.IndexCount, instanceData.NumInstances, _indexBuffer, meshPart.StartIndex); } } }