protected override void DrawCore(RenderContext context, RenderDrawContext drawContext) { var graphicsDevice = drawContext.GraphicsDevice; var graphicsContext = drawContext.GraphicsContext; var commandList = drawContext.GraphicsContext.CommandList; myCustomShader.UpdateEffect(graphicsDevice); var normal = new Vector3(1, 0, 0); VertexBuffer = Buffer.New(graphicsDevice, new[] { new VertexPositionNormalColor(new Vector3(-0.5f, -0.5f, 0.5f), normal, Color.Red), new VertexPositionNormalColor(new Vector3(0, 0.4f, -0.5f), normal, Color.Red), new VertexPositionNormalColor(new Vector3(10, 10f, 0f), normal, Color.Red), }, BufferFlags.VertexBuffer, GraphicsResourceUsage.Immutable); drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green); drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer); myCustomShader.Parameters.Set(TransformationKeys.WorldViewProjection, WorldMatrix); myCustomShader.Parameters.Set(test_shader1Keys.Color, Color.Red); pipelineState.State.RootSignature = myCustomShader.RootSignature; pipelineState.State.EffectBytecode = myCustomShader.Effect.Bytecode; pipelineState.State.Output.CaptureState(commandList); pipelineState.Update(); ; commandList.SetPipelineState(pipelineState.CurrentState); myCustomShader.Apply(graphicsContext); commandList.SetVertexBuffer(0, VertexBuffer, 0, VertexDeclaration.VertexStride); commandList.Draw(3); }
public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex) { // First do everything that doesn't change per individual render object var graphicsDevice = context.GraphicsDevice; var graphicsContext = context.GraphicsContext; var commandList = context.GraphicsContext.CommandList; // Refresh shader, might have changed during runtime myCustomShader.UpdateEffect(graphicsDevice); // Set common shader parameters if needed //myCustomShader.Parameters.Set(TransformationKeys.ViewProjection, renderView.ViewProjection); for (int index = startIndex; index < endIndex; index++) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); var myRenderObject = (MyRenderObject)renderNode.RenderObject; if (myRenderObject.VertexBuffer == null) { continue; //next render object } // Assign shader parameters myCustomShader.Parameters.Set(TransformationKeys.WorldViewProjection, myRenderObject.WorldMatrix * renderView.ViewProjection); myCustomShader.Parameters.Set(TexturingKeys.Texture0, myRenderObject.Texture); myCustomShader.Parameters.Set(MyCustomShaderKeys.TextureScale, myRenderObject.TextureScale); myCustomShader.Parameters.Set(MyCustomShaderKeys.Color, myRenderObject.Color); // Prepare pipeline state pipelineState.State.RootSignature = myCustomShader.RootSignature; pipelineState.State.EffectBytecode = myCustomShader.Effect.Bytecode; pipelineState.State.Output.CaptureState(commandList); pipelineState.Update(); commandList.SetPipelineState(pipelineState.CurrentState); // Apply the effect myCustomShader.Apply(graphicsContext); // Set vertex buffer and draw commandList.SetVertexBuffer(0, myRenderObject.VertexBuffer, 0, MyRenderObject.VertexDeclaration.VertexStride); commandList.Draw(MyRenderObject.VertexCount, 0); } }
void ILowLevelAPIRender.Draw(RenderContext renderContext, RenderDrawContext drawContext, RenderView renderView, RenderViewStage renderViewStage, CommandList commandList) { if (!enabledPin.Value) { return; } try { var pipelineState = this.pipelineState ?? (this.pipelineState = new MutablePipelineState(renderContext.GraphicsDevice)); // TODO1: PerFrame could be done in Update if we'd have access to frame time // TODO2: This code can be optimized by using parameter accessors and not parameter keys parameters.SetPerFrameParameters(perFrameParams, drawContext.RenderContext); parameters.SetPerViewParameters(perViewParams, renderView); if (worldPin != null) { var world = worldPin.ShaderValue; parameters.SetPerDrawParameters(perDrawParams, renderView, ref world); } // Set permutation parameters before updating the effect (needed by compiler) parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, threadNumbersPin.Value); // Give user chance to override parameterSetterPin?.Value.Invoke(parameters, renderView, drawContext); if (instance.UpdateEffect(renderContext.GraphicsDevice) || pipelineStateDirty) { threadGroupCountAccessor = parameters.GetAccessor(ComputeShaderBaseKeys.ThreadGroupCountGlobal); foreach (var p in Inputs.OfType <ParameterPin>()) { p.Update(parameters); } pipelineState.State.SetDefaults(); pipelineState.State.RootSignature = instance.RootSignature; pipelineState.State.EffectBytecode = instance.Effect.Bytecode; pipelineState.Update(); pipelineStateDirty = false; } // Apply pipeline state commandList.SetPipelineState(pipelineState.CurrentState); // Set thread group count as provided by input pin var threadGroupCount = dispatchCountPin.Value; parameters.Set(ComputeShaderBaseKeys.ThreadGroupCountGlobal, threadGroupCount); // TODO: This can be optimized by uploading only parameters from the PerDispatch groups - look in Xenkos RootEffectRenderFeature var iterationCount = Math.Max(iterationCountPin.Value, 1); for (int i = 0; i < iterationCount; i++) { // Give user chance to override iterationParameterSetterPin.Value?.Invoke(parameters, renderView, drawContext, i); // The thread group count can be set for each dispatch threadGroupCount = parameters.Get(threadGroupCountAccessor); // Upload the parameters instance.Apply(drawContext.GraphicsContext); // Draw a full screen quad commandList.Dispatch(threadGroupCount.X, threadGroupCount.Y, threadGroupCount.Z); } } catch (Exception e) { var re = new RuntimeException(e.InnermostException(), this); RuntimeGraph.ReportException(re); } }
public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage) { shader.UpdateEffect(context.GraphicsDevice); foreach (var renderNode in renderViewStage.SortedRenderNodes) { var renderMesh = renderNode.RenderObject as RenderMesh; if (renderMesh == null) { continue; } // get wireframe script WireframeScript wireframeScript = null; if (renderMesh.Source is ModelComponent) { wireframeScript = (renderMesh.Source as ModelComponent).Entity.Get <WireframeScript>(); } if (wireframeScript == null || !wireframeScript.Enabled) { continue; } MeshDraw drawData = renderMesh.ActiveMeshDraw; // bind VB for (int slot = 0; slot < drawData.VertexBuffers.Length; slot++) { var vertexBuffer = drawData.VertexBuffers[slot]; context.CommandList.SetVertexBuffer(slot, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride); } // set shader parameters shader.Parameters.Set(TransformationKeys.WorldViewProjection, renderMesh.World * renderView.ViewProjection); // matrix shader.Parameters.Set(TransformationKeys.WorldScale, new Vector3(ScaleAdjust + 1.0f)); // increase size to avoid z-fight shader.Parameters.Set(SinglePassWireframeShaderKeys.Viewport, new Vector4(context.RenderContext.RenderView.ViewSize, 0, 0)); shader.Parameters.Set(SinglePassWireframeShaderKeys.LineWidth, wireframeScript.LineWidth); shader.Parameters.Set(SinglePassWireframeShaderKeys.LineColor, (Vector3)wireframeScript.Color); // prepare pipeline state pipelineState.State.RootSignature = shader.RootSignature; pipelineState.State.EffectBytecode = shader.Effect.Bytecode; pipelineState.State.PrimitiveType = drawData.PrimitiveType; pipelineState.State.Output.CaptureState(context.CommandList); pipelineState.Update(); context.CommandList.SetIndexBuffer(drawData.IndexBuffer.Buffer, drawData.IndexBuffer.Offset, drawData.IndexBuffer.Is32Bit); context.CommandList.SetPipelineState(pipelineState.CurrentState); // apply the effect shader.Apply(context.GraphicsContext); if (drawData.IndexBuffer != null) { context.CommandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation); } else { context.CommandList.Draw(drawData.DrawCount, drawData.StartLocation); } } }