Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Mesh" /> class.
 /// </summary>
 /// <param name="meshDraw">The mesh draw.</param>
 /// <param name="parameters">The parameters.</param>
 /// <exception cref="System.ArgumentNullException">parameters</exception>
 public Mesh(MeshDraw meshDraw, ParameterCollection parameters)
 {
     if (meshDraw == null)
     {
         throw new ArgumentNullException("meshDraw");
     }
     if (parameters == null)
     {
         throw new ArgumentNullException("parameters");
     }
     Draw       = meshDraw;
     Parameters = parameters;
 }
        private InputElementDescription[] PrepareInputElements(PipelineStateDescription pipelineState, MeshDraw drawData)
        {
            // Get the input elements already contained in the mesh's vertex buffers
            var availableInputElements = drawData.VertexBuffers.CreateInputElements();
            var inputElements          = new List <InputElementDescription>(availableInputElements);

            // In addition, add input elements for all attributes that are not contained in a bound buffer, but required by the shader
            foreach (var inputAttribute in pipelineState.EffectBytecode.Reflection.InputAttributes)
            {
                var inputElementIndex = FindElementBySemantic(availableInputElements, inputAttribute.SemanticName, inputAttribute.SemanticIndex);

                // Provided by any vertex buffer?
                if (inputElementIndex >= 0)
                {
                    continue;
                }

                inputElements.Add(new InputElementDescription
                {
                    AlignedByteOffset    = 0,
                    Format               = PixelFormat.R32G32B32A32_Float,
                    InputSlot            = drawData.VertexBuffers.Length,
                    InputSlotClass       = InputClassification.Vertex,
                    InstanceDataStepRate = 0,
                    SemanticIndex        = inputAttribute.SemanticIndex,
                    SemanticName         = inputAttribute.SemanticName,
                });
            }

            return(inputElements.ToArray());
        }
        /// <inheritdoc/>
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            var commandList = context.CommandList;

            foreach (var renderFeature in RenderFeatures)
            {
                renderFeature.Draw(context, renderView, renderViewStage, startIndex, endIndex);
            }

            // TODO: stackalloc?
            var descriptorSetsLocal = descriptorSets.Value;

            if (descriptorSetsLocal == null || descriptorSetsLocal.Length < EffectDescriptorSetSlotCount)
            {
                descriptorSetsLocal = descriptorSets.Value = new DescriptorSet[EffectDescriptorSetSlotCount];
            }

            MeshDraw currentDrawData = null;
            int      emptyBufferSlot = -1;

            for (int index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);

                var renderMesh = (RenderMesh)renderNode.RenderObject;
                var drawData   = renderMesh.ActiveMeshDraw;

                // Get effect
                // TODO: Use real effect slot
                var renderEffect = renderNode.RenderEffect;
                if (renderEffect.Effect == null || renderEffect.Reflection == null)
                {
                    continue;
                }

                // Bind VB
                if (currentDrawData != drawData)
                {
                    for (int slot = 0; slot < drawData.VertexBuffers.Length; slot++)
                    {
                        var vertexBuffer = drawData.VertexBuffers[slot];
                        commandList.SetVertexBuffer(slot, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride);
                    }

                    // If the mesh's vertex buffers miss any input streams, an additional input binding will have been added to the pipeline state.
                    // We bind an additional empty vertex buffer to that slot handle those streams gracefully.
                    if (emptyBufferSlot != drawData.VertexBuffers.Length)
                    {
                        commandList.SetVertexBuffer(drawData.VertexBuffers.Length, emptyBuffer, 0, 0);
                        emptyBufferSlot = drawData.VertexBuffers.Length;
                    }

                    if (drawData.IndexBuffer != null)
                    {
                        commandList.SetIndexBuffer(drawData.IndexBuffer.Buffer, drawData.IndexBuffer.Offset, drawData.IndexBuffer.Is32Bit);
                    }
                    currentDrawData = drawData;
                }

                var resourceGroupOffset = ComputeResourceGroupOffset(renderNodeReference);

                // Update cbuffer
                renderEffect.Reflection.BufferUploader.Apply(context.CommandList, ResourceGroupPool, resourceGroupOffset);

                // Bind descriptor sets
                for (int i = 0; i < descriptorSetsLocal.Length; ++i)
                {
                    var resourceGroup = ResourceGroupPool[resourceGroupOffset++];
                    if (resourceGroup != null)
                    {
                        descriptorSetsLocal[i] = resourceGroup.DescriptorSet;
                    }
                }

                commandList.SetPipelineState(renderEffect.PipelineState);
                commandList.SetDescriptorSets(0, descriptorSetsLocal);

                // Draw
                if (drawData.IndexBuffer == null)
                {
                    commandList.Draw(drawData.DrawCount, drawData.StartLocation);
                }
                else
                {
                    commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation);
                }
            }
        }