public void CreateIndirectDrawCommands(BucketManager bucketManager, InstanceDataBuffer instanceData) { foreach (var commandBuffer in PrimitiveIndirectDrawBuffer.Values) { if (commandBuffer.Count > 0) { return; } commandBuffer.Clear( ); } foreach (var part in InstanceManager.Parts) { var bucket = bucketManager.GetBucketResource(part); var primitiveType = part.PrimitiveType; var bufferKey = new IndirectCommandBufferKey(bucket, primitiveType); if (!PrimitiveIndirectDrawBuffer.ContainsKey(bufferKey)) { PrimitiveIndirectDrawBuffer[bufferKey] = new IndirectDrawCommandBuffer(primitiveType, bucket); } PrimitiveIndirectDrawBuffer[bufferKey].AddDrawCommand(part, bucket, instanceData[part]); } foreach (var indirectDrawCommandBuffers in PrimitiveIndirectDrawBuffer.Values) { indirectDrawCommandBuffers.CreateCommandBuffer( ); } }
/// <summary> /// Buffers array data and creates draw commands as needed for a given object /// </summary> /// <param name="eye">Viewer camera used to select detail level</param> /// <param name="objectBlock">Object to draw</param> /// <param name="instance">Instance data of object to draw</param> private void Dispatch(Camera eye, ObjectBlock objectBlock, IH2ObjectInstance instance) { CacheKey cacheKey; if (!objectBlock.TryGetCacheKey(out cacheKey)) { return; } var modelBlock = objectBlock.Model.Get <ModelBlock>(cacheKey); var renderBlock = modelBlock?.RenderModel.Get <RenderModelBlock>(cacheKey); if (renderBlock == null) { return; } BucketManager.UnpackVertexData(renderBlock); // TODO use bounding offset and bounding radius here x var distance = eye.DistanceOf(instance.ObjectDatum.Position); var detailLevel = GetDetailLevel(modelBlock, distance); var variant = StringIdent.Zero; var type = instance.GetType( ); if (!SupportsPermutations.ContainsKey(type)) { SupportsPermutations[type] = type.Field("PermutationData") != null; } var supportsPermutation = SupportsPermutations[type]; if (supportsPermutation) { var instanceVariant = StringIdent.Zero; var defaultModelVariant = objectBlock.DefaultModelVariant; // Select the instance variant if it exists, else select the default variant if it exists, // else default to zero variant = instanceVariant == StringIdent.Zero ? defaultModelVariant == StringIdent.Zero ? StringIdent.Zero : defaultModelVariant : instanceVariant; } var hasVariant = variant != StringIdent.Zero; var hasRegions = modelBlock.ModelRegionBlock.Length > 0; // Here sections are collected using the detail level and chosen variant (if it exists) RenderModelSectionBlock[] sections; if (hasVariant) { var variantBlock = modelBlock.Variants.Single(e => e.Name == variant); sections = ProcessVariant(variantBlock, renderBlock, detailLevel); } else if (hasRegions) { sections = ProcessRegions(modelBlock.ModelRegionBlock, renderBlock, detailLevel); } else { sections = renderBlock.Sections; } // Loop through all the sections and load the vertex data if needed and pass the part along // to the draw manager to handle sorting and grouping foreach (var renderModelSection in sections) { if (renderModelSection.SectionData.Length <= 0) { continue; } _bucketManager.BufferPartData(renderModelSection.SectionData[0].Section); foreach (var part in renderModelSection.SectionData[0].Section.Parts) { var materialBlock = renderBlock.Materials[part.Material]; // Create an instance for this part and assign a shader for it _drawManager.CreateInstance(part, instance, supportsPermutation); _drawManager.AssignShader(part, cacheKey, materialBlock.Shader.Ident); } } }
public ScenarioManager( ) { _materialManager = new MaterialManager( ); _drawManager = new DrawManager( ); _bucketManager = new BucketManager( ); }
public Handle(BucketManager bucketManager) { _bucketManager = bucketManager; }