/// <summary> /// Do any changes required to the pipeline state. /// </summary> /// <param name="context"></param> /// <param name="renderNodeReference"></param> /// <param name="renderNode"></param> /// <param name="renderObject"></param> /// <param name="pipelineState"></param> public virtual void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { }
public static CameraComponent GetCurrentCamera(this RenderContext context) { return(context.Tags.Get(Current)); }
/// <summary> /// Extract data from entities, should be as fast as possible to not block simulation loop. It should be mostly copies, and the actual processing should be part of Prepare(). /// </summary> public void Extract(RenderContext context) { // Prepare views for (int index = 0; index < Views.Count; index++) { // Update indices var view = Views[index]; view.Index = index; // Create missing RenderViewFeature while (view.Features.Count < RenderFeatures.Count) { view.Features.Add(new RenderViewFeature()); } for (int i = 0; i < RenderFeatures.Count; i++) { var renderViewFeature = view.Features[i]; renderViewFeature.RootFeature = RenderFeatures[i]; } } foreach (var view in Views) { for (int index = 0; index < view.RenderStages.Count; index++) { var renderViewStage = view.RenderStages[index]; renderViewStage.RenderNodes = renderNodePool.Acquire(); renderViewStage.SortedRenderNodes = sortedRenderNodePool.Acquire(); view.RenderStages[index] = renderViewStage; } } // Create nodes for objects to render Dispatcher.ForEach(Views, view => { // Sort per render feature (used for later sorting) // We'll be able to process data more efficiently for the next steps Dispatcher.Sort(view.RenderObjects, RenderObjectFeatureComparer.Default); Dispatcher.ForEach(view.RenderObjects, () => extractThreadLocals.Value, (renderObject, batch) => { var renderFeature = renderObject.RenderFeature; var viewFeature = view.Features[renderFeature.Index]; // Create object node renderFeature.GetOrCreateObjectNode(renderObject); // Let's create the view object node var renderViewNode = renderFeature.CreateViewObjectNode(view, renderObject); viewFeature.ViewObjectNodes.Add(renderViewNode, batch.ViewFeatureObjectNodeCache); // Collect object // TODO: Check which stage it belongs to (and skip everything if it doesn't belong to any stage) // TODO: For now, we build list and then copy. Another way would be to count and then fill (might be worse, need to check) var activeRenderStages = renderObject.ActiveRenderStages; foreach (var renderViewStage in view.RenderStages) { // Check if this RenderObject wants to be rendered for this render stage var renderStageIndex = renderViewStage.Index; if (!activeRenderStages[renderStageIndex].Active) { continue; } var renderStage = RenderStages[renderStageIndex]; if (renderStage.Filter != null && !renderStage.Filter.IsVisible(renderObject, view, renderViewStage)) { continue; } var renderNode = renderFeature.CreateRenderNode(renderObject, view, renderViewNode, renderStage); // Note: Used mostly during updating viewFeature.RenderNodes.Add(renderNode, batch.ViewFeatureRenderNodeCache); // Note: Used mostly during rendering renderViewStage.RenderNodes.Add(new RenderNodeFeatureReference(renderFeature, renderNode, renderObject), batch.ViewStageRenderNodeCache); } }, batch => batch.Flush()); // Finish collectin of view feature nodes foreach (var viewFeature in view.Features) { viewFeature.ViewObjectNodes.Close(); viewFeature.RenderNodes.Close(); } // Also sort view|stage per render feature foreach (var renderViewStage in view.RenderStages) { renderViewStage.RenderNodes.Close(); Dispatcher.Sort(renderViewStage.RenderNodes, RenderNodeFeatureReferenceComparer.Default); } }); // Finish collection of render feature nodes foreach (var renderFeature in RenderFeatures) { renderFeature.CloseNodeCollectors(); } // Ensure size of data arrays per objects PrepareDataArrays(); // Generate and execute extract jobs foreach (var renderFeature in RenderFeatures) // We might be able to parallelize too as long as we resepect render feature dependency graph (probably very few dependencies in practice) { // Divide into task chunks for parallelism renderFeature.Extract(); } // Ensure size of all other data arrays PrepareDataArrays(); }