Exemple #1
0
 /// <inheritdoc/>
 public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage)
 {
     foreach (var renderFeature in RenderFeatures)
     {
         renderFeature.Draw(context, renderView, renderViewStage);
     }
 }
Exemple #2
0
        public override unsafe void GenerateSortKey(RenderView renderView, RenderViewStage renderViewStage, SortKey *sortKeys)
        {
            Matrix.Invert(ref renderView.View, out var viewInverse);
            var plane = new Plane(viewInverse.Forward, Vector3.Dot(viewInverse.TranslationVector, viewInverse.Forward)); // TODO: Point-normal-constructor seems wrong. Check.

            var renderNodes = renderViewStage.RenderNodes;

            int distanceShift = 32 - distancePrecision;
            int stateShift    = 32 - statePrecision;

            for (int i = 0; i < renderNodes.Count; ++i)
            {
                var renderNode = renderNodes[i];

                var renderObject = renderNode.RenderObject;
                var distance     = CollisionHelper.DistancePlanePoint(ref plane, ref renderObject.BoundingBox.Center);
                var distanceI    = ComputeDistance(distance);
                if (reverseDistance)
                {
                    distanceI = ~distanceI;
                }

                // Compute sort key
                sortKeys[i] = new SortKey {
                    Value = ((ulong)renderNode.RootRenderFeature.SortKey << 56) | ((ulong)(distanceI >> distanceShift) << distancePosition) | ((ulong)(renderObject.StateSortKey >> stateShift) << statePosition), Index = i, StableIndex = renderObject.Index
                };
            }
        }
Exemple #3
0
 public abstract bool IsVisible(RenderObject renderObject, RenderView renderView, RenderViewStage renderViewStage);
Exemple #4
0
 public abstract unsafe void GenerateSortKey(RenderView renderView, RenderViewStage renderViewStage, SortKey *sortKeys);
Exemple #5
0
        /// <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)
                {
                    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)
                {
                    if (renderMesh.InstanceCount > 0)
                    {
                        commandList.DrawInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation);
                    }
                    else
                    {
                        commandList.Draw(drawData.DrawCount, drawData.StartLocation);
                    }
                }
                else
                {
                    if (renderMesh.InstanceCount > 0)
                    {
                        commandList.DrawIndexedInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation);
                    }
                    else
                    {
                        commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation);
                    }
                }
            }
        }