Exemplo n.º 1
0
        /// <inheritdoc/>
        public override void Prepare(RenderThreadContext context)
        {
            var renderViewObjectInfoData = RootRenderFeature.RenderData.GetData(renderViewObjectInfoKey);

            var resourceGroupPool = ((RootEffectRenderFeature)RootRenderFeature).ResourceGroupPool;

            for (int renderNodeIndex = 0; renderNodeIndex < RootRenderFeature.RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference  = new RenderNodeReference(renderNodeIndex);
                var renderNode           = RootRenderFeature.RenderNodes[renderNodeIndex];
                var renderViewObjectInfo = renderViewObjectInfoData[renderNode.ViewObjectNode];

                if (renderViewObjectInfo == null)
                {
                    continue;
                }

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                {
                    continue;
                }

                if (!PrepareLightParameterEntry(context, renderViewObjectInfo, renderNode.RenderEffect))
                {
                    continue;
                }

                var resourceGroupPoolOffset = ((RootEffectRenderFeature)RootRenderFeature).ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[resourceGroupPoolOffset + perLightingDescriptorSetSlot.Index] = renderViewObjectInfo.Resources;
            }
        }
Exemplo n.º 2
0
        /// <inheritdoc/>
        public override void Prepare(RenderDrawContext context)
        {
            // Assign descriptor sets to each render node
            var resourceGroupPool = ((RootEffectRenderFeature)RootRenderFeature).ResourceGroupPool;

            Dispatcher.For(0, RootRenderFeature.RenderNodes.Count, () => context.RenderContext.GetThreadContext(), (renderNodeIndex, threadContext) =>
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode          = RootRenderFeature.RenderNodes[renderNodeIndex];
                var renderMesh          = (RenderMesh)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                {
                    return;
                }

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material           = renderMesh.Material;
                var materialInfo       = renderMesh.MaterialInfo;
                var materialParameters = material.Parameters;

                if (!UpdateMaterial(RenderSystem, threadContext, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                {
                    return;
                }

                var descriptorSetPoolOffset = ((RootEffectRenderFeature)RootRenderFeature).ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            });
        }
Exemplo n.º 3
0
 public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
 {
     if (renderNode.RenderStage == RenderStage)
     {
         pipelineState.BlendState        = BlendStates.AlphaBlend;
         pipelineState.DepthStencilState = DepthStencilStates.DepthRead;
     }
 }
Exemplo n.º 4
0
 public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
 {
     if (renderNode.RenderStage == RenderStage)
     {
         pipelineState.BlendState        = BlendStates.NonPremultiplied;
         pipelineState.DepthStencilState = DepthStencilStates.DepthRead;
         pipelineState.RasterizerState.MultisampleAntiAliasLine = true;
     }
 }
Exemplo n.º 5
0
        protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
        {
            // Bind VAO
            pipelineState.InputElements = PrimitiveQuad.VertexDeclaration.CreateInputElements();
            pipelineState.PrimitiveType = PrimitiveQuad.PrimitiveType;

            // Don't clip nor write Z value (we are writing at 1.0f = infinity)
            pipelineState.DepthStencilState = DepthStencilStates.DepthRead;
        }
        protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
        {
            base.ProcessPipelineState(context, renderNodeReference, ref renderNode, renderObject, pipelineState);

            pipelineState.DepthStencilState = new DepthStencilStateDescription(false, false);

            pipelineState.BlendState.AlphaToCoverageEnable  = false;
            pipelineState.BlendState.IndependentBlendEnable = false;

            ref var blendState0 = ref pipelineState.BlendState.RenderTarget0;
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
 public override bool Equals(object other)
 {
     if (other is RenderNodeReference)
     {
         RenderNodeReference p = (RenderNodeReference)other;
         return(Index == p.Index);
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 9
0
 public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
 {
     // Disable culling and depth clip
     if (VoxelRenderStage.Contains(renderNode.RenderStage))
     {
         pipelineState.RasterizerState = new RasterizerStateDescription(CullMode.None)
         {
             DepthClipEnable = DepthClipping
         };
         pipelineState.DepthStencilState.DepthBufferEnable      = false;
         pipelineState.DepthStencilState.DepthBufferWriteEnable = false;
         pipelineState.DepthStencilState.StencilEnable          = false;
         pipelineState.DepthStencilState.StencilWriteMask       = 0;
         pipelineState.DepthStencilState.StencilMask            = 0;
         pipelineState.BlendState.RenderTarget0.BlendEnable     = false;
         pipelineState.BlendState.IndependentBlendEnable        = false;
     }
 }
Exemplo n.º 10
0
        /// <summary>
        /// Builds the shared vertex and index buffers used by the particle systems
        /// </summary>
        /// <param name="renderDrawContext"><see cref="RenderDrawContext"/> to access the command list and the graphics context</param>
        private void BuildParticleBuffers(RenderDrawContext renderDrawContext)
        {
            // Build particle buffers
            var commandList = renderDrawContext.CommandList;

            // Build the vertex buffer with particles data
            if (particleBufferContext.VertexBuffer == null || particleBufferContext.VertexBufferSize == 0)
            {
                return;
            }

            var renderParticleNodeData = RenderData.GetData(renderParticleNodeKey);

            var mappedVertices  = commandList.MapSubresource(particleBufferContext.VertexBuffer, 0, MapMode.WriteNoOverwrite, false, 0, particleBufferContext.VertexBufferSize);
            var sharedBufferPtr = mappedVertices.DataBox.DataPointer;

            //for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            Dispatcher.For(0, RenderNodes.Count, (renderNodeIndex) =>
            {
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var nodeData            = renderParticleNodeData[renderNodeReference];
                if (nodeData.IndexCount <= 0)
                {
                    return; // Nothing to draw, nothing to build
                }
                nodeData.VertexBuffer = particleBufferContext.VertexBuffer;
                nodeData.IndexBuffer  = particleBufferContext.IndexBuffer;

                renderParticleNodeData[renderNodeReference] = nodeData;

                Matrix viewInverse; // TODO Build this per view, not per node!!!
                Matrix.Invert(ref renderNode.RenderView.View, out viewInverse);
                renderParticleEmitter.ParticleEmitter.BuildVertexBuffer(sharedBufferPtr + nodeData.VertexBufferOffset, ref viewInverse, ref renderNode.RenderView.ViewProjection);
            });

            commandList.UnmapSubresource(mappedVertices);
        }
Exemplo n.º 11
0
        public override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
        {
            base.ProcessPipelineState(context, renderNodeReference, ref renderNode, renderObject, pipelineState);

            // Check if this is a highlight rendering
            var perDrawLayout = renderNode.RenderEffect.Reflection?.PerDrawLayout;

            if (perDrawLayout == null)
            {
                return;
            }

            var colorOffset = perDrawLayout.GetConstantBufferOffset(this.color);

            if (colorOffset == -1)
            {
                return;
            }

            // Display using alpha blending and without depth-buffer writing
            pipelineState.BlendState        = BlendStates.AlphaBlend;
            pipelineState.DepthStencilState = DepthStencilStates.DepthRead;
        }
Exemplo n.º 12
0
        public override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
        {
            base.ProcessPipelineState(context, renderNodeReference, ref renderNode, renderObject, pipelineState);

            // Check if this is a wireframe rendering
            var perDrawLayout = renderNode.RenderEffect.Reflection?.PerDrawLayout;

            if (perDrawLayout == null)
            {
                return;
            }

            var perDrawDataOffset = perDrawLayout.GetConstantBufferOffset(this.perDrawData);

            if (perDrawDataOffset == -1)
            {
                return;
            }

            // Display using wireframe and without depth-buffer
            pipelineState.BlendState      = BlendStates.AlphaBlend;
            pipelineState.RasterizerState = RasterizerStates.Wireframe;
            pipelineState.DepthStencilState.DepthBufferEnable = false;
        }
Exemplo n.º 13
0
 public T this[RenderNodeReference index]
 {
     get { return(Data[index.Index]); }
     set { Data[index.Index] = value; }
 }
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            base.Prepare(context);

            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode = RenderNodes[renderNodeIndex];

                var renderSkybox = (RenderSkybox)renderNode.RenderObject;
                var sourceParameters = renderSkybox.Background == SkyboxBackground.Irradiance ? renderSkybox.Skybox.DiffuseLightingParameters : renderSkybox.Skybox.Parameters;

                var skyboxInfo = renderSkybox.SkyboxInfo;
                if (skyboxInfo == null || skyboxInfo.Skybox != renderSkybox.Skybox)
                    skyboxInfo = renderSkybox.SkyboxInfo = new SkyboxInfo(renderSkybox.Skybox);

                var parameters = skyboxInfo.ParameterCollection;

                var renderEffect = renderNode.RenderEffect;
                if (renderEffect.State != RenderEffectState.Normal)
                    continue;

                // TODO GRAPHICS REFACTOR current system is not really safe with multiple renderers (parameters come from Skybox which is shared but ResourceGroupLayout from RenderSkybox is per RenderNode)
                if (skyboxInfo.ResourceGroupLayout == null || skyboxInfo.ResourceGroupLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index].Hash)
                {
                    var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index];

                    var parameterCollectionLayout = skyboxInfo.ParameterCollectionLayout = new ParameterCollectionLayout();
                    parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout);

                    // Find material cbuffer
                    if (resourceGroupDescription.ConstantBufferReflection != null)
                    {
                        parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection);
                    }

                    //skyboxInfo.RotationParameter = parameters.GetAccessor(SkyboxKeys.Rotation);
                    //skyboxInfo.SkyMatrixParameter = parameters.GetAccessor(SkyboxKeys.SkyMatrix);

                    // TODO: Cache that
                    skyboxInfo.ResourceGroupLayout = ResourceGroupLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription, renderEffect.Effect.Bytecode);

                    parameters.UpdateLayout(parameterCollectionLayout);

                    if (renderSkybox.Background == SkyboxBackground.Irradiance)
                    {
                        skyboxInfo.ParameterCollectionCopier = new ParameterCollection.Copier(parameters, sourceParameters, ".skyboxColor");
                    }
                    else
                    {
                        skyboxInfo.ParameterCollectionCopier = new ParameterCollection.Copier(parameters, sourceParameters);
                    }
                }

                skyboxInfo.ParameterCollectionCopier.Copy();

                // Setup the intensity
                parameters.Set(SkyboxKeys.Intensity, renderSkybox.Intensity);

                // Update SkyMatrix
                Matrix skyMatrix;
                Matrix.RotationQuaternion(ref renderSkybox.Rotation, out skyMatrix);
                parameters.Set(SkyboxKeys.SkyMatrix, ref skyMatrix);

                // Update MatrixTransform
                // TODO: Use default values?
                var matrixTransformOffset = renderNode.RenderEffect.Reflection.PerDrawLayout.GetConstantBufferOffset(this.matrixTransform);
                if (matrixTransformOffset != -1)
                {
                    var mappedCB = renderNode.Resources.ConstantBuffer.Data + matrixTransformOffset;
                    Matrix.Translation(0.0f, 0.0f, 1.0f, out *(Matrix*)(byte*)mappedCB);
                }

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                context.ResourceGroupAllocator.PrepareResourceGroup(skyboxInfo.ResourceGroupLayout, BufferPoolAllocationType.UsedMultipleTime, skyboxInfo.Resources);
                ResourceGroupPool[descriptorSetPoolOffset + perLightingDescriptorSetSlot.Index] = skyboxInfo.Resources;

                var descriptorSet = skyboxInfo.Resources.DescriptorSet;

                // Set resource bindings in PerLighting resource set
                for (int resourceSlot = 0; resourceSlot < parameters.Layout.ResourceCount; ++resourceSlot)
                {
                    descriptorSet.SetValue(resourceSlot, parameters.ObjectValues[resourceSlot]);
                }

                // Process PerLighting cbuffer
                if (skyboxInfo.Resources.ConstantBuffer.Size > 0)
                {
                    var mappedCB = skyboxInfo.Resources.ConstantBuffer.Data;
                    fixed (byte* dataValues = parameters.DataValues)
                        Utilities.CopyMemory(mappedCB, (IntPtr)dataValues, skyboxInfo.Resources.ConstantBuffer.Size);
                }
            }

            transformRenderFeature.Prepare(context);
        }
Exemplo n.º 15
0
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            // Inspect each RenderObject (= ParticleEmitter) to determine if its required vertex buffer size has changed
            foreach (var renderObject in RenderObjects)
            {
                var renderParticleEmitter = (RenderParticleEmitter)renderObject;
                renderParticleEmitter.ParticleEmitter.PrepareForDraw(out renderParticleEmitter.HasVertexBufferChanged,
                                                                     out renderParticleEmitter.VertexSize, out renderParticleEmitter.VertexCount);

                // TODO: ParticleMaterial should set this up
                var materialInfo = (ParticleMaterialInfo)renderParticleEmitter.ParticleMaterialInfo;
                var colorShade   = renderParticleEmitter.Color.ToColorSpace(context.GraphicsDevice.ColorSpace);
                materialInfo?.Material.Parameters.Set(ParticleBaseKeys.ColorScale, colorShade);
            }

            // Calculate the total vertex buffer size required
            int totalVertexBufferSize  = 0;
            int highestIndexCount      = 0;
            var renderParticleNodeData = RenderData.GetData(renderParticleNodeKey);

            // Reset pipeline states if necessary
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                if (renderParticleEmitter.HasVertexBufferChanged)
                {
                    // Reset pipeline state, so input layout is regenerated
                    if (renderNode.RenderEffect != null)
                    {
                        renderNode.RenderEffect.PipelineState = null;
                    }
                }

                // Write some attributes back which we will need for rendering later
                var vertexBuilder = renderParticleEmitter.ParticleEmitter.VertexBuilder;
                var newNodeData   = new RenderAttributesPerNode
                {
                    VertexBufferOffset = totalVertexBufferSize,
                    VertexBufferSize   = renderParticleEmitter.VertexSize * renderParticleEmitter.VertexCount,
                    VertexBufferStride = renderParticleEmitter.VertexSize,
                    IndexCount         = vertexBuilder.LivingQuads * vertexBuilder.IndicesPerQuad,
                };

                renderParticleNodeData[new RenderNodeReference(renderNodeIndex)] = newNodeData;

                totalVertexBufferSize += newNodeData.VertexBufferSize;
                if (newNodeData.IndexCount > highestIndexCount)
                {
                    highestIndexCount = newNodeData.IndexCount;
                }
            }

            base.Prepare(context);

            // Assign descriptor sets to each render node
            var resourceGroupPool = ResourceGroupPool;

            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference   = new RenderNodeReference(renderNodeIndex);
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                {
                    continue;
                }

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material           = renderParticleEmitter.ParticleEmitter.Material;
                var materialInfo       = renderParticleEmitter.ParticleMaterialInfo;
                var materialParameters = material.Parameters;

                if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                {
                    continue;
                }

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }

            particleBufferContext.AllocateBuffers(context, totalVertexBufferSize, highestIndexCount);

            BuildParticleBuffers(context);
        }
Exemplo n.º 16
0
        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;
        }
        /// <summary>
        /// Builds the shared vertex and index buffers used by the particle systems
        /// </summary>
        /// <param name="renderDrawContext"><see cref="RenderDrawContext"/> to access the command list and the graphics context</param>
        private void BuildParticleBuffers(RenderDrawContext renderDrawContext)
        {
            // Build particle buffers
            var commandList = renderDrawContext.CommandList;

            // Build the vertex buffer with particles data
            if (particleBufferContext.VertexBuffer == null || particleBufferContext.VertexBufferSize == 0)
                return;

            var renderParticleNodeData = RenderData.GetData(renderParticleNodeKey);

            var mappedVertices = commandList.MapSubresource(particleBufferContext.VertexBuffer, 0, MapMode.WriteNoOverwrite, false, 0, particleBufferContext.VertexBufferSize);
            var sharedBufferPtr = mappedVertices.DataBox.DataPointer;

            //for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            Dispatcher.For(0, RenderNodes.Count, (renderNodeIndex) =>
            {
                var renderNode = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var nodeData = renderParticleNodeData[renderNodeReference];
                if (nodeData.IndexCount <= 0)
                    return; // Nothing to draw, nothing to build

                nodeData.VertexBuffer = particleBufferContext.VertexBuffer;
                nodeData.IndexBuffer = particleBufferContext.IndexBuffer;

                renderParticleNodeData[renderNodeReference] = nodeData;

                Matrix viewInverse; // TODO Build this per view, not per node!!!
                Matrix.Invert(ref renderNode.RenderView.View, out viewInverse);
                renderParticleEmitter.ParticleEmitter.BuildVertexBuffer(sharedBufferPtr + nodeData.VertexBufferOffset, ref viewInverse);
            });

            commandList.UnmapSubresource(mappedVertices);
        }
Exemplo n.º 18
0
 public override void Process(RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
 {
     pipelineState.RasterizerState = RasterizerStates.WireframeCullBack;
 }
        /// <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);
        }
 public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject)
 {
     RootRenderFeature = rootRenderFeature;
     RenderNode = renderNode;
     RenderObject = renderObject;
 }
Exemplo n.º 21
0
        /// <inheritdoc/>
        public override void Prepare(RenderDrawContext context)
        {
            // Assign descriptor sets to each render node
            var resourceGroupPool = ((RootEffectRenderFeature)RootRenderFeature).ResourceGroupPool;
            for (int renderNodeIndex = 0; renderNodeIndex < RootRenderFeature.RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode = RootRenderFeature.RenderNodes[renderNodeIndex];
                var renderMesh = (RenderMesh)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                    continue;

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material = renderMesh.Material;
                var materialInfo = renderMesh.MaterialInfo;
                var materialParameters = material.Parameters;

                if (!UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                    continue;

                var descriptorSetPoolOffset = ((RootEffectRenderFeature)RootRenderFeature).ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }
        }
Exemplo n.º 22
0
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderThreadContext context)
        {
            base.Prepare(context);

            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode          = RenderNodes[renderNodeIndex];

                var renderSkybox     = (RenderSkybox)renderNode.RenderObject;
                var sourceParameters = renderSkybox.Background == SkyboxBackground.Irradiance ? renderSkybox.Skybox.DiffuseLightingParameters : renderSkybox.Skybox.Parameters;

                var skyboxInfo = renderSkybox.SkyboxInfo;
                if (skyboxInfo == null || skyboxInfo.Skybox != renderSkybox.Skybox)
                {
                    skyboxInfo = renderSkybox.SkyboxInfo = new SkyboxInfo(renderSkybox.Skybox);
                }

                var parameters = skyboxInfo.ParameterCollection;

                var renderEffect = renderNode.RenderEffect;
                if (renderEffect.State != RenderEffectState.Normal)
                {
                    continue;
                }

                // TODO GRAPHICS REFACTOR current system is not really safe with multiple renderers (parameters come from Skybox which is shared but ResourceGroupLayout from RenderSkybox is per RenderNode)
                if (skyboxInfo.ResourceGroupLayout == null || skyboxInfo.ResourceGroupLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index].Hash)
                {
                    var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[perLightingDescriptorSetSlot.Index];

                    var parameterCollectionLayout = skyboxInfo.ParameterCollectionLayout = new ParameterCollectionLayout();
                    parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout);

                    // Find material cbuffer
                    if (resourceGroupDescription.ConstantBufferReflection != null)
                    {
                        parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection);
                    }

                    //skyboxInfo.RotationParameter = parameters.GetAccessor(SkyboxKeys.Rotation);
                    //skyboxInfo.SkyMatrixParameter = parameters.GetAccessor(SkyboxKeys.SkyMatrix);

                    // TODO: Cache that
                    skyboxInfo.ResourceGroupLayout = ResourceGroupLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription, renderEffect.Effect.Bytecode);

                    parameters.UpdateLayout(parameterCollectionLayout);

                    if (renderSkybox.Background == SkyboxBackground.Irradiance)
                    {
                        skyboxInfo.ParameterCollectionCopier = new ParameterCollection.Copier(parameters, sourceParameters, ".skyboxColor");
                    }
                    else
                    {
                        skyboxInfo.ParameterCollectionCopier = new ParameterCollection.Copier(parameters, sourceParameters);
                    }
                }

                skyboxInfo.ParameterCollectionCopier.Copy();

                // Setup the intensity
                parameters.Set(SkyboxKeys.Intensity, renderSkybox.Intensity);

                // Update SkyMatrix
                Matrix skyMatrix;
                Matrix.RotationQuaternion(ref renderSkybox.Rotation, out skyMatrix);
                parameters.Set(SkyboxKeys.SkyMatrix, ref skyMatrix);

                // Update MatrixTransform
                // TODO: Use default values?
                var matrixTransformOffset = renderNode.RenderEffect.Reflection.PerDrawLayout.GetConstantBufferOffset(this.matrixTransform);
                if (matrixTransformOffset != -1)
                {
                    var mappedCB = renderNode.Resources.ConstantBuffer.Data + matrixTransformOffset;
                    Matrix.Translation(0.0f, 0.0f, 1.0f, out *(Matrix *)(byte *)mappedCB);
                }

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                context.ResourceGroupAllocator.PrepareResourceGroup(skyboxInfo.ResourceGroupLayout, BufferPoolAllocationType.UsedMultipleTime, skyboxInfo.Resources);
                ResourceGroupPool[descriptorSetPoolOffset + perLightingDescriptorSetSlot.Index] = skyboxInfo.Resources;

                var descriptorSet = skyboxInfo.Resources.DescriptorSet;

                // Set resource bindings in PerLighting resource set
                for (int resourceSlot = 0; resourceSlot < parameters.Layout.ResourceCount; ++resourceSlot)
                {
                    descriptorSet.SetValue(resourceSlot, parameters.ObjectValues[resourceSlot]);
                }

                // Process PerLighting cbuffer
                if (skyboxInfo.Resources.ConstantBuffer.Size > 0)
                {
                    var mappedCB = skyboxInfo.Resources.ConstantBuffer.Data;

                    fixed(byte *dataValues = parameters.DataValues)
                    Utilities.CopyMemory(mappedCB, (IntPtr)dataValues, skyboxInfo.Resources.ConstantBuffer.Size);
                }
            }

            transformRenderFeature.Prepare(context);
        }
Exemplo n.º 23
0
 public RenderNode GetRenderNode(RenderNodeReference reference)
 {
     return RenderNodes[reference.Index];
 }
        protected override void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
        {
            // Bind VAO
            pipelineState.InputElements = PrimitiveQuad.VertexDeclaration.CreateInputElements();
            pipelineState.PrimitiveType = PrimitiveQuad.PrimitiveType;

            // Don't clip nor write Z value (we are writing at 1.0f = infinity)
            pipelineState.DepthStencilState = DepthStencilStates.DepthRead;
        }
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            // Inspect each RenderObject (= ParticleEmitter) to determine if its required vertex buffer size has changed
            foreach (var renderObject in RenderObjects)
            {
                var renderParticleEmitter = (RenderParticleEmitter)renderObject;
                renderParticleEmitter.ParticleEmitter.PrepareForDraw(out renderParticleEmitter.HasVertexBufferChanged,
                    out renderParticleEmitter.VertexSize, out renderParticleEmitter.VertexCount);

                // TODO: ParticleMaterial should set this up
                var materialInfo = (ParticleMaterialInfo)renderParticleEmitter.ParticleMaterialInfo;
                materialInfo?.Material.Parameters.Set(ParticleBaseKeys.ColorScale, renderParticleEmitter.RenderParticleSystem.ParticleSystemComponent.Color);
            }

            // Calculate the total vertex buffer size required
            int totalVertexBufferSize = 0;
            int highestIndexCount = 0;
            var renderParticleNodeData = RenderData.GetData(renderParticleNodeKey);

            // Reset pipeline states if necessary
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNode = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                if (renderParticleEmitter.HasVertexBufferChanged)
                {
                    // Reset pipeline state, so input layout is regenerated
                    if (renderNode.RenderEffect != null)
                        renderNode.RenderEffect.PipelineState = null;
                }

                // Write some attributes back which we will need for rendering later
                var vertexBuilder = renderParticleEmitter.ParticleEmitter.VertexBuilder; 
                var newNodeData = new RenderAttributesPerNode
                {
                    VertexBufferOffset = totalVertexBufferSize,
                    VertexBufferSize = renderParticleEmitter.VertexSize * renderParticleEmitter.VertexCount,
                    VertexBufferStride = renderParticleEmitter.VertexSize,
                    IndexCount = vertexBuilder.LivingQuads * vertexBuilder.IndicesPerQuad,
                };

                renderParticleNodeData[new RenderNodeReference(renderNodeIndex)] = newNodeData;

                totalVertexBufferSize += newNodeData.VertexBufferSize;
                if (newNodeData.IndexCount > highestIndexCount)
                    highestIndexCount = newNodeData.IndexCount;
            }

            base.Prepare(context);

            // Assign descriptor sets to each render node
            var resourceGroupPool = ResourceGroupPool;
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                    continue;

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material = renderParticleEmitter.ParticleEmitter.Material;
                var materialInfo = renderParticleEmitter.ParticleMaterialInfo;
                var materialParameters = material.Parameters;

                if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                    continue;

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }

            particleBufferContext.AllocateBuffers(context, totalVertexBufferSize, highestIndexCount);

            BuildParticleBuffers(context);
        }
Exemplo n.º 26
0
        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>
 /// Compute the index of first descriptor set stored in <see cref="ResourceGroupPool"/>.
 /// </summary>
 protected internal int ComputeResourceGroupOffset(RenderNodeReference renderNode)
 {
     return renderNode.Index * effectDescriptorSetSlots.Count;
 }
Exemplo n.º 28
0
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            // Reset pipeline states if necessary
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNode = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                if (renderParticleEmitter.ParticleEmitter.VertexBuilder.IsBufferDirty)
                {
                    // Reset pipeline state, so input layout is regenerated
                    if (renderNode.RenderEffect != null)
                        renderNode.RenderEffect.PipelineState = null;
                }
            }

            foreach (var renderObject in RenderObjects)
            {
                var renderParticleEmitter = (RenderParticleEmitter)renderObject;
                renderParticleEmitter.ParticleEmitter.PrepareForDraw();

                var materialInfo = (ParticleMaterialInfo)renderParticleEmitter.ParticleMaterialInfo;

                // Handle vertex element changes
                if (renderParticleEmitter.ParticleEmitter.VertexBuilder.IsBufferDirty)
                {
                    // Create new buffers
                    renderParticleEmitter.ParticleEmitter.VertexBuilder.RecreateBuffers(RenderSystem.GraphicsDevice);
                }

                // TODO: ParticleMaterial should set this up
                materialInfo?.Material.Parameters.Set(ParticleBaseKeys.ColorScale, renderParticleEmitter.RenderParticleSystem.ParticleSystemComponent.Color);
            }

            base.Prepare(context);

            // Assign descriptor sets to each render node
            var resourceGroupPool = ResourceGroupPool;
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference = new RenderNodeReference(renderNodeIndex);
                var renderNode = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                    continue;

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material = renderParticleEmitter.ParticleEmitter.Material;
                var materialInfo = renderParticleEmitter.ParticleMaterialInfo;
                var materialParameters = material.Parameters;

                if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                    continue;

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }

            // Per view
            // TODO: Transform sub render feature?
            for (int index = 0; index < RenderSystem.Views.Count; index++)
            {
                var view = RenderSystem.Views[index];
                var viewFeature = view.Features[Index];

                // TODO GRAPHICS REFACTOR: Happens in several places
                Matrix.Multiply(ref view.View, ref view.Projection, out view.ViewProjection);

                // Copy ViewProjection to PerFrame cbuffer
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    var resourceGroup = viewLayout.Entries[view.Index].Resources;
                    var mappedCB = resourceGroup.ConstantBuffer.Data;

                    // PerView constant buffer
                    var perViewOffset = viewLayout.GetConstantBufferOffset(this.perViewCBufferOffset);
                    if (perViewOffset != -1)
                    {
                        var perView = (ParticleUtilitiesPerView*)((byte*)mappedCB + perViewOffset);
                        perView->ViewMatrix     = view.View;
                        perView->ProjectionMatrix = view.Projection;
                        perView->ViewProjectionMatrix = view.ViewProjection;
                        perView->ViewFrustum = new Vector4(view.ViewSize.X, view.ViewSize.Y, view.NearClipPlane, view.FarClipPlane);
                    }
                }
            }
        }
 protected virtual void ProcessPipelineState(RenderContext context, RenderNodeReference renderNodeReference, ref RenderNode renderNode, RenderObject renderObject, PipelineStateDescription pipelineState)
 {
 }
Exemplo n.º 30
0
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            // Reset pipeline states if necessary
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                if (renderParticleEmitter.ParticleEmitter.VertexBuilder.IsBufferDirty)
                {
                    // Reset pipeline state, so input layout is regenerated
                    if (renderNode.RenderEffect != null)
                    {
                        renderNode.RenderEffect.PipelineState = null;
                    }
                }
            }

            foreach (var renderObject in RenderObjects)
            {
                var renderParticleEmitter = (RenderParticleEmitter)renderObject;
                renderParticleEmitter.ParticleEmitter.PrepareForDraw();

                var materialInfo = (ParticleMaterialInfo)renderParticleEmitter.ParticleMaterialInfo;

                // Handle vertex element changes
                if (renderParticleEmitter.ParticleEmitter.VertexBuilder.IsBufferDirty)
                {
                    // Create new buffers
                    renderParticleEmitter.ParticleEmitter.VertexBuilder.RecreateBuffers(RenderSystem.GraphicsDevice);
                }

                // TODO: ParticleMaterial should set this up
                materialInfo?.Material.Parameters.Set(ParticleBaseKeys.ColorScale, renderParticleEmitter.RenderParticleSystem.ParticleSystemComponent.Color);
            }

            base.Prepare(context);

            // Assign descriptor sets to each render node
            var resourceGroupPool = ResourceGroupPool;

            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference   = new RenderNodeReference(renderNodeIndex);
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                {
                    continue;
                }

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material           = renderParticleEmitter.ParticleEmitter.Material;
                var materialInfo       = renderParticleEmitter.ParticleMaterialInfo;
                var materialParameters = material.Parameters;

                if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                {
                    continue;
                }

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }

            // Per view
            // TODO: Transform sub render feature?
            for (int index = 0; index < RenderSystem.Views.Count; index++)
            {
                var view        = RenderSystem.Views[index];
                var viewFeature = view.Features[Index];

                // TODO GRAPHICS REFACTOR: Happens in several places
                Matrix.Multiply(ref view.View, ref view.Projection, out view.ViewProjection);

                // Copy ViewProjection to PerFrame cbuffer
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    var viewProjectionOffset = viewLayout.GetConstantBufferOffset(this.view);
                    if (viewProjectionOffset == -1)
                    {
                        continue;
                    }

                    var resourceGroup = viewLayout.Entries[view.Index].Resources;
                    var mappedCB      = resourceGroup.ConstantBuffer.Data;

                    var perView = (Matrix *)((byte *)mappedCB + viewProjectionOffset);
                    *   perView = view.ViewProjection;
                }
            }
        }
Exemplo n.º 31
0
 public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject)
 {
     RootRenderFeature = rootRenderFeature;
     RenderNode        = renderNode;
     RenderObject      = renderObject;
 }
Exemplo n.º 32
0
 public ref   T this[RenderNodeReference index] => ref Data[index.Index];
Exemplo n.º 33
0
        /// <inheritdoc/>
        public override unsafe void Prepare(RenderDrawContext context)
        {
            // Inspect each RenderObject (= ParticleEmitter) to determine if its required vertex buffer size has changed
            foreach (var renderObject in RenderObjects)
            {
                var renderParticleEmitter = (RenderParticleEmitter)renderObject;
                renderParticleEmitter.ParticleEmitter.PrepareForDraw(out renderParticleEmitter.HasVertexBufferChanged,
                                                                     out renderParticleEmitter.VertexSize, out renderParticleEmitter.VertexCount);

                // TODO: ParticleMaterial should set this up
                var materialInfo = (ParticleMaterialInfo)renderParticleEmitter.ParticleMaterialInfo;
                materialInfo?.Material.Parameters.Set(ParticleBaseKeys.ColorScale, renderParticleEmitter.RenderParticleSystem.ParticleSystemComponent.Color);
            }

            // Calculate the total vertex buffer size required
            int totalVertexBufferSize  = 0;
            int highestIndexCount      = 0;
            var renderParticleNodeData = RenderData.GetData(renderParticleNodeKey);

            // Reset pipeline states if necessary
            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                if (renderParticleEmitter.HasVertexBufferChanged)
                {
                    // Reset pipeline state, so input layout is regenerated
                    if (renderNode.RenderEffect != null)
                    {
                        renderNode.RenderEffect.PipelineState = null;
                    }
                }

                // Write some attributes back which we will need for rendering later
                var vertexBuilder = renderParticleEmitter.ParticleEmitter.VertexBuilder;
                var newNodeData   = new RenderAttributesPerNode
                {
                    VertexBufferOffset = totalVertexBufferSize,
                    VertexBufferSize   = renderParticleEmitter.VertexSize * renderParticleEmitter.VertexCount,
                    VertexBufferStride = renderParticleEmitter.VertexSize,
                    IndexCount         = vertexBuilder.LivingQuads * vertexBuilder.IndicesPerQuad,
                };

                renderParticleNodeData[new RenderNodeReference(renderNodeIndex)] = newNodeData;

                totalVertexBufferSize += newNodeData.VertexBufferSize;
                if (newNodeData.IndexCount > highestIndexCount)
                {
                    highestIndexCount = newNodeData.IndexCount;
                }
            }

            base.Prepare(context);

            // Assign descriptor sets to each render node
            var resourceGroupPool = ResourceGroupPool;

            for (int renderNodeIndex = 0; renderNodeIndex < RenderNodes.Count; renderNodeIndex++)
            {
                var renderNodeReference   = new RenderNodeReference(renderNodeIndex);
                var renderNode            = RenderNodes[renderNodeIndex];
                var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject;

                // Ignore fallback effects
                if (renderNode.RenderEffect.State != RenderEffectState.Normal)
                {
                    continue;
                }

                // Collect materials and create associated MaterialInfo (includes reflection) first time
                // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order)
                // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario)
                var material           = renderParticleEmitter.ParticleEmitter.Material;
                var materialInfo       = renderParticleEmitter.ParticleMaterialInfo;
                var materialParameters = material.Parameters;

                if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters))
                {
                    continue;
                }

                var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference);
                resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources;
            }

            // Per view
            // TODO: Transform sub render feature?
            for (int index = 0; index < RenderSystem.Views.Count; index++)
            {
                var view        = RenderSystem.Views[index];
                var viewFeature = view.Features[Index];

                // TODO GRAPHICS REFACTOR: Happens in several places
                Matrix.Multiply(ref view.View, ref view.Projection, out view.ViewProjection);

                // Copy ViewProjection to PerFrame cbuffer
                foreach (var viewLayout in viewFeature.Layouts)
                {
                    var resourceGroup = viewLayout.Entries[view.Index].Resources;
                    var mappedCB      = resourceGroup.ConstantBuffer.Data;

                    // PerView constant buffer
                    var perViewOffset = viewLayout.GetConstantBufferOffset(this.perViewCBufferOffset);
                    if (perViewOffset != -1)
                    {
                        var perView = (ParticleUtilitiesPerView *)((byte *)mappedCB + perViewOffset);
                        perView->ViewMatrix           = view.View;
                        perView->ProjectionMatrix     = view.Projection;
                        perView->ViewProjectionMatrix = view.ViewProjection;
                        perView->ViewFrustum          = new Vector4(view.ViewSize.X, view.ViewSize.Y, view.NearClipPlane, view.FarClipPlane);
                    }
                }
            }

            particleBufferContext.AllocateBuffers(context, totalVertexBufferSize, highestIndexCount);

            BuildParticleBuffers(context);
        }