/// <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); } } }