public void AddObject( int renderOrder, IRenderObject renderObject, ShaderProgram vertProg, ShaderProgram fragProg, ShaderProgram shadowFragProg, string debugName = null) { IInternalRenderObject internalRenderObj = renderObject as IInternalRenderObject; if (internalRenderObj == null) { throw new Exception( $"[{nameof(RenderScene)}] Render objects have to be implemented at engine level"); } //Keep track of all objects objects.Add(internalRenderObj); //Add them to techniques for rendering gbufferTechnique.AddObject(internalRenderObj, vertProg, fragProg, renderOrder, debugName); if (shadowFragProg != null) { shadowTechnique.AddObject( internalRenderObj, vertProg, shadowFragProg, renderOrder, debugName); } dirty = true; }
public void AddObject( IInternalRenderObject renderObject, ShaderProgram vertProg, ShaderProgram fragProg, int order = 0, bool depthClamp = false, bool depthBias = false, string debugName = null) { ThrowIfDisposed(); items.Add(new Item( order, depthClamp, depthBias, renderObject, specializationContainer, pushDataContainer, vertProg, fragProg, scene.LogicalDevice, debugName)); //Sort the objects based on order items.Sort(CompareOrder); }
internal void AddObject( IInternalRenderObject renderObject, ShaderProgram vertProg, ShaderProgram fragProg, int renderOrder = 0, string debugName = null) { renderer.AddObject(renderObject, vertProg, fragProg, renderOrder, debugName: debugName); }
public void RemoveObject(IInternalRenderObject renderObject) { ThrowIfDisposed(); for (int i = items.Count - 1; i >= 0; i--) { if (items[i].RenderObject == renderObject) { items.RemoveAt(i); } } }
public Item( int order, bool depthClamp, bool depthBias, IInternalRenderObject renderObject, SpecializationContainer specializationContainer, PushDataContainer pushDataContainer, ShaderProgram vertProg, ShaderProgram fragProg, Device logicalDevice, string debugName = null) { this.order = order; this.renderObject = renderObject; this.specializationContainer = specializationContainer; this.pushDataContainer = pushDataContainer; this.depthClamp = depthClamp; this.depthBias = depthBias; this.debugName = debugName; vertModule = vertProg.CreateModule(logicalDevice); fragModule = fragProg.CreateModule(logicalDevice); }
internal static Pipeline CreatePipeline( Device logicalDevice, RenderPass renderpass, PipelineLayout layout, ShaderModule vertModule, ShaderModule fragModule, SpecializationContainer specializationContainer, bool depthClamp, bool depthBias, ReadOnlySpan <DeviceTexture> targets, IInternalRenderObject renderObject) { if (logicalDevice == null) { throw new ArgumentNullException(nameof(logicalDevice)); } if (renderpass == null) { throw new ArgumentNullException(nameof(renderpass)); } var shaderStages = new [] { new PipelineShaderStageCreateInfo( stage: ShaderStages.Vertex, module: vertModule, name: "main", specializationInfo: specializationContainer?.GetInfo()), new PipelineShaderStageCreateInfo( stage: ShaderStages.Fragment, module: fragModule, name: "main", specializationInfo: specializationContainer?.GetInfo()) }; var depthTest = new PipelineDepthStencilStateCreateInfo { DepthTestEnable = true, DepthWriteEnable = true, DepthCompareOp = CompareOp.LessOrEqual, DepthBoundsTestEnable = false, StencilTestEnable = false }; var rasterizer = new PipelineRasterizationStateCreateInfo( depthClampEnable: depthClamp, rasterizerDiscardEnable: false, polygonMode: PolygonMode.Fill, cullMode: CullModes.Back, frontFace: renderObject.GetFrontFace(), depthBiasEnable: depthBias, depthBiasConstantFactor: .1f, depthBiasSlopeFactor: 1.75f, lineWidth: 1f ); //Gather all the color targets and setup a blend-state for them ResizeArray <PipelineColorBlendAttachmentState> blendAttachments = new ResizeArray <PipelineColorBlendAttachmentState>(); for (int i = 0; i < targets.Length; i++) { if (!targets[i].DepthTexture) { blendAttachments.Add(new PipelineColorBlendAttachmentState( colorWriteMask: ColorComponents.All, blendEnable: false)); } } var blending = new PipelineColorBlendStateCreateInfo( attachments: blendAttachments.ToArray(), logicOpEnable: false ); var multisampleState = new PipelineMultisampleStateCreateInfo( rasterizationSamples: SampleCounts.Count1, sampleShadingEnable: false ); //Pass the viewport and scissor-rect as dynamic so we are not tied to swapchain size //the advantage is this is that we don't need to recreate the pipeline on swapchain //resize var dynamicState = new PipelineDynamicStateCreateInfo( DynamicState.Viewport, DynamicState.Scissor ); return(logicalDevice.CreateGraphicsPipeline(new GraphicsPipelineCreateInfo( layout: layout, renderPass: renderpass, subpass: 0, stages: shaderStages, inputAssemblyState: renderObject.GetInputAssemblyStateInfo(), vertexInputState: renderObject.GetVertexInputState(), rasterizationState: rasterizer, tessellationState: null, //Pass empty viewport and scissor-rect as we set them dynamically viewportState: new PipelineViewportStateCreateInfo(new Viewport(), new Rect2D()), multisampleState: multisampleState, depthStencilState: depthTest, colorBlendState: blending, dynamicState: dynamicState, flags: PipelineCreateFlags.None ))); }