예제 #1
0
        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( );
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
0
 public ScenarioManager( )
 {
     _materialManager = new MaterialManager( );
     _drawManager     = new DrawManager( );
     _bucketManager   = new BucketManager( );
 }
예제 #4
0
 public Handle(BucketManager bucketManager)
 {
     _bucketManager = bucketManager;
 }