public RenderNode(RenderObject renderObject, RenderView renderView, ViewObjectNodeReference viewObjectNode, RenderStage renderStage) { RenderObject = renderObject; RenderView = renderView; ViewObjectNode = viewObjectNode; EffectObjectNode = EffectObjectNodeReference.Invalid; RenderStage = renderStage; RenderEffect = null; Resources = null; }
/// <summary> /// Called when a render object is removed. /// </summary> /// <param name="renderObject"></param> protected virtual void OnRemoveRenderObject(RenderObject renderObject) { }
internal bool RemoveRenderObject(List<RenderObject> renderObjects, RenderObject renderObject) { if (renderObject.RenderFeature == null) renderObjectsWithoutFeatures.Remove(renderObject); RenderSystem.RemoveRenderObject(renderObject); // Get and clear ordered node index var orderedRenderNodeIndex = renderObject.VisibilityObjectNode.Index; if (renderObject.VisibilityObjectNode == StaticObjectNodeReference.Invalid) return false; renderObject.VisibilityObjectNode = StaticObjectNodeReference.Invalid; // SwapRemove each items in dataArrays RenderData.SwapRemoveItem(DataType.StaticObject, orderedRenderNodeIndex, renderObjects.Count - 1); // Remove entry from ordered node index renderObjects.SwapRemoveAt(orderedRenderNodeIndex); // If last item was moved, update its index if (orderedRenderNodeIndex < renderObjects.Count) { renderObjects[orderedRenderNodeIndex].VisibilityObjectNode = new StaticObjectNodeReference(orderedRenderNodeIndex); } return true; }
protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { var renderMesh = (RenderMesh)renderObject; var drawData = renderMesh.ActiveMeshDraw; pipelineState.InputElements = drawData.VertexBuffers.CreateInputElements(); pipelineState.PrimitiveType = drawData.PrimitiveType; }
/// <summary> /// Implemented by subclasses to reset effect dependent data. /// </summary> protected virtual void InvalidateEffectPermutation(RenderObject renderObject, RenderEffect renderEffect) { }
internal void AddRenderObject(RenderObject renderObject) { renderObject.RenderFeature = this; // Generate static data ID renderObject.StaticObjectNode = new StaticObjectNodeReference(RenderObjects.Count); // Add to render object RenderObjects.Add(renderObject); OnAddRenderObject(renderObject); }
/// <summary> /// Called when a render object is added. /// </summary> /// <param name="renderObject"></param> protected virtual void OnAddRenderObject(RenderObject renderObject) { }
/// <summary> /// Creates a view object node during Extract phase. /// </summary> /// <param name="view"></param> /// <param name="renderObject"></param> /// <returns>The view object node reference.</returns> public ViewObjectNodeReference CreateViewObjectNode(RenderView view, RenderObject renderObject) { var renderViewNode = new ViewObjectNode(renderObject, view, renderObject.ObjectNode); // Create view node var index = viewObjectNodes.Add(renderViewNode); var result = new ViewObjectNodeReference(index); return result; }
public abstract void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState);
/// <summary> /// Removes a <see cref="RenderObject"/> from the rendering. /// </summary> /// <param name="renderObject"></param> public void RemoveRenderObject(RenderObject renderObject) { var renderFeature = renderObject.RenderFeature; renderFeature?.RemoveRenderObject(renderObject); }
public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject) { RootRenderFeature = rootRenderFeature; RenderNode = renderNode; RenderObject = renderObject; }
internal ObjectNodeReference GetOrCreateObjectNode(RenderObject renderObject) { if (renderObject.ObjectNode == ObjectNodeReference.Invalid) { renderObject.ObjectNode = new ObjectNodeReference(objectNodes.Count); objectNodes.Add(new ObjectNode(renderObject)); ObjectNodeReferences.Add(renderObject.ObjectNode); } return renderObject.ObjectNode; }
public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { var output = renderNode.RenderStage.Output; var isMultisample = output.MultisampleCount != MultisampleCount.None; var renderMesh = (RenderMesh)renderObject; // Make object in transparent stage use AlphaBlend and DepthRead if (renderNode.RenderStage == TransparentRenderStage) { pipelineState.BlendState = renderMesh.MaterialPass.BlendState ?? BlendStates.AlphaBlend; pipelineState.DepthStencilState = DepthStencilStates.DepthRead; if (isMultisample) { pipelineState.BlendState.AlphaToCoverageEnable = true; } } var cullMode = pipelineState.RasterizerState.CullMode; // Apply material cull mode var cullModeOverride = renderMesh.MaterialInfo.CullMode; // No override, or already two-sided? if (cullModeOverride.HasValue && cullMode != CullMode.None) { if (cullModeOverride.Value == CullMode.None) { // Override to two-sided cullMode = CullMode.None; } else if (cullModeOverride.Value == cullMode) { // No or double flipping cullMode = CullMode.Back; } else { // Single flipping cullMode = CullMode.Front; } } // Flip faces when geometry is inverted if (renderMesh.IsScalingNegative) { if (cullMode == CullMode.Front) { cullMode = CullMode.Back; } else if (cullMode == CullMode.Back) { cullMode = CullMode.Front; } } pipelineState.RasterizerState.CullMode = cullMode; if (isMultisample) { pipelineState.RasterizerState.MultisampleCount = output.MultisampleCount; pipelineState.RasterizerState.MultisampleAntiAliasLine = true; } pipelineState.RasterizerState.ScissorTestEnable = output.ScissorTestEnable; }
/// <inheritdoc/> protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { var renderParticleEmitter = (RenderParticleEmitter)renderObject; pipelineState.InputElements = renderParticleEmitter.ParticleEmitter.VertexBuilder.VertexDeclaration.CreateInputElements(); pipelineState.PrimitiveType = PrimitiveType.TriangleList; var material = renderParticleEmitter.ParticleMaterialInfo.Material; material.SetupPipeline(context, pipelineState); }
internal RenderNodeReference CreateRenderNode(RenderObject renderObject, RenderView renderView, ViewObjectNodeReference renderPerViewNode, RenderStage renderStage) { var renderNode = new RenderNode(renderObject, renderView, renderPerViewNode, renderStage); // Create view node var index = RenderNodes.Add(renderNode); var result = new RenderNodeReference(index); return result; }
protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { var renderMesh = (RenderMesh)renderObject; var drawData = renderMesh.ActiveMeshDraw; pipelineState.InputElements = PrepareInputElements(pipelineState, drawData); pipelineState.PrimitiveType = drawData.PrimitiveType; // Prepare each sub render feature foreach (var renderFeature in RenderFeatures) { renderFeature.ProcessPipelineState(context, renderNodeReference, ref renderNode, renderObject, pipelineState); } }
internal unsafe ObjectNodeReference GetOrCreateObjectNode(RenderObject renderObject) { fixed (ObjectNodeReference* objectNodeRef = &renderObject.ObjectNode) { var oldValue = Interlocked.CompareExchange(ref *(int*)objectNodeRef, -2, -1); if (oldValue == -1) { var index = objectNodes.Add(new ObjectNode(renderObject)); renderObject.ObjectNode = new ObjectNodeReference(index); ObjectNodeReferences.Add(renderObject.ObjectNode); } else { while (renderObject.ObjectNode.Index == -2) { } } } return renderObject.ObjectNode; }
public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { if (renderNode.RenderStage == RenderStage) { pipelineState.RasterizerState = RasterizerStates.Wireframe; } }
protected override void InvalidateEffectPermutation(RenderObject renderObject, RenderEffect renderEffect) { var renderParticleEmitter = (RenderParticleEmitter)renderObject; var materialInfo = renderParticleEmitter.ParticleMaterialInfo; materialInfo.PerMaterialLayout = null; }
internal void RemoveRenderObject(RenderObject renderObject) { OnRemoveRenderObject(renderObject); // Get and clear ordered node index var orderedRenderNodeIndex = renderObject.StaticObjectNode.Index; renderObject.StaticObjectNode = StaticObjectNodeReference.Invalid; // SwapRemove each items in dataArrays RenderData.SwapRemoveItem(DataType.StaticObject, orderedRenderNodeIndex, RenderObjects.Count - 1); // Remove entry from ordered node index RenderObjects.SwapRemoveAt(orderedRenderNodeIndex); // If last item was moved, update its index if (orderedRenderNodeIndex < RenderObjects.Count) { RenderObjects[orderedRenderNodeIndex].StaticObjectNode = new StaticObjectNodeReference(orderedRenderNodeIndex); } // Detach render feature renderObject.RenderFeature = null; }
public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { // Objects in the shadow map render stage disable culling and depth clip if (renderNode.RenderStage == ShadowMapRenderStage) { pipelineState.RasterizerState = new RasterizerStateDescription(CullMode.None) { DepthClipEnable = DepthClipping }; } }
protected virtual void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState) { }
internal void AddRenderObject(List<RenderObject> renderObjects, RenderObject renderObject) { if (renderObject.VisibilityObjectNode != StaticObjectNodeReference.Invalid) return; renderObject.VisibilityObjectNode = new StaticObjectNodeReference(renderObjects.Count); renderObjects.Add(renderObject); // Resize arrays to accomodate for new data RenderData.PrepareDataArrays(); RenderSystem.AddRenderObject(renderObject); if (renderObject.RenderFeature != null) ReevaluateActiveRenderStages(renderObject); else renderObjectsWithoutFeatures.Add(renderObject); }
/// <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) { }
private void ReevaluateActiveRenderStages(RenderObject renderObject) { var renderFeature = renderObject.RenderFeature; if (renderFeature == null) return; // Determine which render stages are activated for this object renderObject.ActiveRenderStages = new ActiveRenderStage[RenderSystem.RenderStages.Count]; foreach (var renderStageSelector in renderFeature.RenderStageSelectors) renderStageSelector.Process(renderObject); // Compute render stage mask var renderStageMask = RenderData.GetData(RenderStageMaskKey); var renderStageMaskNode = renderObject.VisibilityObjectNode * stageMaskMultiplier; for (int index = 0; index < renderObject.ActiveRenderStages.Length; index++) { // TODO: Could easily be optimized to read and set value only once per uint var activeRenderStage = renderObject.ActiveRenderStages[index]; if (activeRenderStage.Active) renderStageMask[renderStageMaskNode + (index / RenderStageMaskSizePerEntry)] |= 1U << (index % RenderStageMaskSizePerEntry); } }