Esempio n. 1
0
 /// <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));
 }
Esempio n. 3
0
        /// <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();
        }