Beispiel #1
0
        /// <summary>
        /// Allocates global buffers.
        /// </summary>
        private void OnCapacityCountChange()
        {
            // Allocate global buffers
            bool allocateGlobalBuffer = false;

            if (globalBuffer == null)
            {
                allocateGlobalBuffer = true;
            }
            else if (globalBuffer.ElementCount != CapacityCount)
            {
                // Reallocate global buffer if capacity changed
                allocateGlobalBuffer = true;
                // Release previous buffer
                globalBuffer.Release();
                sortBuffer.Release();
            }

            // Allocate new buffers
            if (allocateGlobalBuffer)
            {
                if (CapacityCount > 0)
                {
                    globalBuffer      = Buffer.Structured.New(graphicsDeviceService.GraphicsDevice, CapacityCount, StructureSize, true);
                    globalBuffer.Name = "ParticleGlobalBuffer";
                    sortBuffer        = Buffer.Structured.New(graphicsDeviceService.GraphicsDevice, CapacityCount, sizeof(int) * 2, true);
                    sortBuffer.Name   = "ParticleSortBuffer";
                }
            }
        }
Beispiel #2
0
            public void DisposeBuffers()
            {
                if (AppendBuffer != null)
                {
                    AppendBuffer.Release();
                    AppendBuffer = null;
                }

                if (ConsumeBuffer != null)
                {
                    ConsumeBuffer.Release();
                    ConsumeBuffer = null;
                }
            }
Beispiel #3
0
        /// <summary>
        /// Creates an Entity that contains our dynamic Vertex and Index buffers.
        /// This Entity will be rendered by the model renderer.
        /// </summary>
        /// <param name="verticesCount"></param>
        /// <param name="indicesCount"></param>
        private void CreateTerrainModelEntity(int verticesCount, int indicesCount)
        {
            // Compute sizes
            var vertexDeclaration = VertexNormalTexture.VertexDeclaration;
            var vertexBufferSize  = verticesCount * vertexDeclaration.CalculateSize();
            var indexBufferSize   = indicesCount * sizeof(int);

            // Create Vertex and Index buffers
            terrainVertexBuffer = Buffer.Vertex.New(GraphicsDevice, vertexBufferSize, GraphicsResourceUsage.Dynamic);
            terrainIndexBuffer  = Buffer.New(GraphicsDevice, indexBufferSize, BufferFlags.IndexBuffer, GraphicsResourceUsage.Dynamic);

            // Prepare mesh and entity
            var meshDraw = new MeshDraw
            {
                PrimitiveType = PrimitiveType.TriangleStrip,
                VertexBuffers = new[] { new VertexBufferBinding(terrainVertexBuffer, vertexDeclaration, verticesCount) },
                IndexBuffer   = new IndexBufferBinding(terrainIndexBuffer, true, indicesCount),
            };

//            var effect1 = EffectSystem.LoadEffect("SimpleTerrainEffectMain").WaitForResult();
//            var effect2 = EffectSystem.LoadEffect("VertexTextureTerrain");
            var effectMaterial = LoadAsset <Material>("mt_rock");

            Texture tex0 = (Texture)effectMaterial.Parameters[MaterialKeys.DiffuseMap]; // rock
            Texture tex1 = (Texture)effectMaterial.Parameters[DiffuseMap1];             // grass
            Texture tex2 = (Texture)effectMaterial.Parameters[DiffuseMap2];             // water

            effectMaterial.Parameters.Add(VertexTextureTerrainKeys.MeshTexture0, tex1);
            effectMaterial.Parameters.Add(VertexTextureTerrainKeys.MeshTexture1, tex0);
            effectMaterial.Parameters.Add(VertexTextureTerrainKeys.MeshTexture2, tex2);

            effectMaterial.Parameters.Add(MaterialKeys.DiffuseMap, tex1);

            //terrainMesh = new Mesh { Draw = meshDraw /*, Material = LoadAsset<Material>("TerrainMaterial")*/ };
            terrainMesh = new Mesh {
                Draw = meshDraw, MaterialIndex = 0
            };

            //terrainEntity = new Entity { { ModelComponent.Key, new ModelComponent { Model = new Model { terrainMesh } } } };
            //TerrainEntity.Add<ModelComponent>( ModelComponent.Key, new ModelComponent { Model = new Model { terrainMesh } } );
            TerrainEntity.Add <ModelComponent>(ModelComponent.Key, new ModelComponent {
                Model = new Model {
                    terrainMesh, effectMaterial
                }
            });
        }
        public ParameterConstantBuffer(GraphicsDevice device, string constantBufferName, ShaderConstantBufferDescription constantBufferDesc)
        {
            ConstantBufferDesc = constantBufferDesc;
            constantBufferDatas = new ConstantBufferData[GraphicsDevice.ThreadCount];
            dataStreams = new DataPointer[GraphicsDevice.ThreadCount];

            for (uint i = 0; i < GraphicsDevice.ThreadCount; ++i)
            {
                constantBufferDatas[i] = new ConstantBufferData(constantBufferDesc);
                dataStreams[i] = new DataPointer(constantBufferDatas[i].Data, constantBufferDesc.Size);
            }

            Buffer = SiliconStudio.Paradox.Graphics.Buffer.New(device, constantBufferDatas[0].Desc.Size, BufferFlags.ConstantBuffer, UsingMap ? GraphicsResourceUsage.Dynamic : GraphicsResourceUsage.Default);
            
            // We want to clear flags
            // TODO: Should be later replaced with either an internal field on GraphicsResourceBase, or a reset counter somewhere?
            Buffer.Reload = Reload;
        }
Beispiel #5
0
        public ParameterConstantBuffer(GraphicsDevice device, string constantBufferName, ShaderConstantBufferDescription constantBufferDesc)
        {
            ConstantBufferDesc  = constantBufferDesc;
            constantBufferDatas = new ConstantBufferData[GraphicsDevice.ThreadCount];
            dataStreams         = new DataPointer[GraphicsDevice.ThreadCount];

            for (uint i = 0; i < GraphicsDevice.ThreadCount; ++i)
            {
                constantBufferDatas[i] = new ConstantBufferData(constantBufferDesc);
                dataStreams[i]         = new DataPointer(constantBufferDatas[i].Data, constantBufferDesc.Size);
            }

            Buffer = SiliconStudio.Paradox.Graphics.Buffer.New(device, constantBufferDatas[0].Desc.Size, BufferFlags.ConstantBuffer, UsingMap ? GraphicsResourceUsage.Dynamic : GraphicsResourceUsage.Default);

            // We want to clear flags
            // TODO: Should be later replaced with either an internal field on GraphicsResourceBase, or a reset counter somewhere?
            Buffer.Reload = Reload;
        }
Beispiel #6
0
 /// <summary>
 /// Allocates the buffers.
 /// </summary>
 public void AllocateBuffers(GraphicsDevice graphicsDevice)
 {
     DisposeBuffers();
     AppendBuffer  = Buffer.StructuredAppend.New(graphicsDevice, UserState.Count, StructureSize);
     ConsumeBuffer = Buffer.StructuredAppend.New(graphicsDevice, UserState.Count, StructureSize);
 }
        protected override void DrawCore(RenderContext context)
        {
            var inputTexture = RadianceMap;

            if (inputTexture == null)
            {
                return;
            }

            // Gets and checks the input texture
            if (inputTexture.Dimension != TextureDimension.TextureCube)
            {
                throw new NotSupportedException("Only texture cube are currently supported as input of 'LambertianPrefilteringSH' effect.");
            }

            const int FirstPassBlockSize = 4;
            const int FirstPassSumsCount = FirstPassBlockSize * FirstPassBlockSize;

            var faceCount         = inputTexture.Dimension == TextureDimension.TextureCube ? 6 : 1;
            var inputSize         = new Int2(inputTexture.Width, inputTexture.Height); // (Note: for cube maps width = height)
            var coefficientsCount = harmonicalOrder * harmonicalOrder;

            var sumsToPerfomRemaining = inputSize.X * inputSize.Y * faceCount / FirstPassSumsCount;
            var partialSumBuffer      = NewScopedTypedBuffer(coefficientsCount * sumsToPerfomRemaining, PixelFormat.R32G32B32A32_Float, true);


            // Project the radiance on the SH basis and sum up the results along the 4x4 blocks
            firstPassEffect.ThreadNumbers     = new Int3(FirstPassBlockSize, FirstPassBlockSize, 1);
            firstPassEffect.ThreadGroupCounts = new Int3(inputSize.X / FirstPassBlockSize, inputSize.Y / FirstPassBlockSize, faceCount);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHParameters.BlockSize, FirstPassBlockSize);
            firstPassEffect.Parameters.Set(SphericalHarmonicsParameters.HarmonicsOrder, harmonicalOrder);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.RadianceMap, inputTexture);
            firstPassEffect.Parameters.Set(LambertianPrefilteringSHPass1Keys.OutputBuffer, partialSumBuffer);
            firstPassEffect.Draw(context);

            // Recursively applies the pass2 (sums the coefficients together) as long as needed. Swap input/output buffer at each iteration.
            var    secondPassInputBuffer  = partialSumBuffer;
            Buffer secondPassOutputBuffer = null;

            while (sumsToPerfomRemaining % 2 == 0)
            {
                // we are limited in the number of summing threads by the group-shared memory size.
                // determine the number of threads to use and update the number of sums remaining afterward.
                var sumsCount = 1;
                while (sumsCount < (1 << 10) && sumsToPerfomRemaining % 2 == 0) // shader can perform only an 2^x number of sums.
                {
                    sumsCount             <<= 1;
                    sumsToPerfomRemaining >>= 1;
                }

                // determine the numbers of groups (limited to 65535 groups by dimensions)
                var groupCountX = 1;
                var groupCountY = sumsToPerfomRemaining;
                while (groupCountX >= short.MaxValue)
                {
                    groupCountX <<= 1;
                    groupCountY >>= 1;
                }

                // create the output buffer if not existing yet
                if (secondPassOutputBuffer == null)
                {
                    secondPassOutputBuffer = NewScopedTypedBuffer(coefficientsCount * sumsToPerfomRemaining, PixelFormat.R32G32B32A32_Float, true);
                }

                // draw pass 2
                secondPassEffect.ThreadNumbers     = new Int3(sumsCount, 1, 1);
                secondPassEffect.ThreadGroupCounts = new Int3(groupCountX, groupCountY, coefficientsCount);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHParameters.BlockSize, sumsCount);
                secondPassEffect.Parameters.Set(SphericalHarmonicsParameters.HarmonicsOrder, harmonicalOrder);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHPass2Keys.InputBuffer, secondPassInputBuffer);
                secondPassEffect.Parameters.Set(LambertianPrefilteringSHPass2Keys.OutputBuffer, secondPassOutputBuffer);
                secondPassEffect.Draw(context);

                // swap second pass input/output buffers.
                var swapTemp = secondPassOutputBuffer;
                secondPassOutputBuffer = secondPassInputBuffer;
                secondPassInputBuffer  = swapTemp;
            }

            // create and initialize result SH
            prefilteredLambertianSH = new SphericalHarmonics(HarmonicOrder);

            // Get the data out of the final buffer
            var sizeResult   = coefficientsCount * sumsToPerfomRemaining * PixelFormat.R32G32B32A32_Float.SizeInBytes();
            var stagedBuffer = NewScopedBuffer(new BufferDescription(sizeResult, BufferFlags.None, GraphicsResourceUsage.Staging));

            GraphicsDevice.CopyRegion(secondPassInputBuffer, 0, new ResourceRegion(0, 0, 0, sizeResult, 1, 1), stagedBuffer, 0);
            var finalsValues = stagedBuffer.GetData <Vector4>();

            // performs last possible additions, normalize the result and store it in the SH
            for (var c = 0; c < coefficientsCount; c++)
            {
                var coeff = Vector4.Zero;
                for (var f = 0; f < sumsToPerfomRemaining; ++f)
                {
                    coeff += finalsValues[coefficientsCount * f + c];
                }
                prefilteredLambertianSH.Coefficients[c] = 4 * MathUtil.Pi / coeff.W * new Color3(coeff.X, coeff.Y, coeff.Z);
            }
        }
Beispiel #8
0
        private static byte[] GetDataSafe(this Buffer buffer)
        {
            var data = buffer.GetSerializationData();

            return(data != null ? data.Content : buffer.GetData <byte>());
        }
Beispiel #9
0
        public void Generate(IServiceRegistry services, Model model)
        {
            if (services == null)
            {
                throw new ArgumentNullException("services");
            }
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }

            var graphicsDevice = services.GetSafeServiceAs <IGraphicsDeviceService>().GraphicsDevice;

            var data = this.CreatePrimitiveMeshData();

            if (data.Vertices.Length == 0)
            {
                throw new InvalidOperationException("Invalid GeometricPrimitive [{0}]. Expecting non-zero Vertices array");
            }

            var boundingBox = BoundingBox.Empty;

            for (int i = 0; i < data.Vertices.Length; i++)
            {
                BoundingBox.Merge(ref boundingBox, ref data.Vertices[i].Position, out boundingBox);
            }

            BoundingSphere boundingSphere;

            unsafe
            {
                fixed(void *verticesPtr = data.Vertices)
                BoundingSphere.FromPoints((IntPtr)verticesPtr, 0, data.Vertices.Length, VertexPositionNormalTexture.Size, out boundingSphere);
            }

            var originalLayout = data.Vertices[0].GetLayout();

            // Generate Tangent/BiNormal vectors
            var resultWithTangentBiNormal = VertexHelper.GenerateTangentBinormal(originalLayout, data.Vertices, data.Indices);

            // Generate Multitexcoords
            var result = VertexHelper.GenerateMultiTextureCoordinates(resultWithTangentBiNormal);

            var meshDraw = new MeshDraw();

            var layout       = result.Layout;
            var vertexBuffer = result.VertexBuffer;
            var indices      = data.Indices;

            if (indices.Length < 0xFFFF)
            {
                var indicesShort = new ushort[indices.Length];
                for (int i = 0; i < indicesShort.Length; i++)
                {
                    indicesShort[i] = (ushort)indices[i];
                }
                meshDraw.IndexBuffer = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indicesShort).RecreateWith(indicesShort), false, indices.Length);
            }
            else
            {
                if (graphicsDevice.Features.Profile <= GraphicsProfile.Level_9_3)
                {
                    throw new InvalidOperationException("Cannot generate more than 65535 indices on feature level HW <= 9.3");
                }

                meshDraw.IndexBuffer = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices).RecreateWith(indices), true, indices.Length);
            }

            meshDraw.VertexBuffers = new[] { new VertexBufferBinding(Buffer.New(graphicsDevice, vertexBuffer, BufferFlags.VertexBuffer).RecreateWith(vertexBuffer), layout, data.Vertices.Length) };

            meshDraw.DrawCount     = indices.Length;
            meshDraw.PrimitiveType = PrimitiveType.TriangleList;

            var mesh = new Mesh {
                Draw = meshDraw, BoundingBox = boundingBox, BoundingSphere = boundingSphere
            };

            model.BoundingBox    = boundingBox;
            model.BoundingSphere = boundingSphere;
            model.Add(mesh);

            if (MaterialInstance != null && MaterialInstance.Material != null)
            {
                model.Materials.Add(MaterialInstance);
            }
        }
Beispiel #10
0
 /// <summary>
 /// Copies the current count of structured elements from a structured buffer to an <see cref="IIndirectBuffer"/>.
 /// </summary>
 /// <param name="sourceBuffer">The structured buffer</param>
 /// <param name="destBuffer">The indirect buffer</param>
 /// <param name="offsetToDest">Offset into the indirect buffer to write arguments to</param>
 public void CopyCount(Buffer sourceBuffer, Buffer destBuffer, int offsetToDest)
 {
     throw new NotImplementedException();
 }
Beispiel #11
0
 /// <summary>
 /// Sets a constant buffer to the shader pipeline.
 /// </summary>
 /// <param name="stage">The shader stage.</param>
 /// <param name="slot">The binding slot.</param>
 /// <param name="buffer">The constant buffer to set.</param>
 public void SetConstantBuffer(ShaderStage stage, int slot, Buffer buffer)
 {
     throw new NotImplementedException();
 }
Beispiel #12
0
 /// <summary>
 /// Execute a compute shader from a thread group using arguments stored in the <see cref="IIndirectBuffer"/>.
 /// </summary>
 /// <param name="indirectBuffer">Buffer storing arguments of the standard dispatch method (threadCountX/Y/Z).</param>
 /// <param name="offsetInBytes">Offset to start to read the arguments from the indirect buffer.</param>
 public void Dispatch(Buffer indirectBuffer, int offsetInBytes)
 {
     throw new NotImplementedException();
 }
Beispiel #13
0
 /// <summary>
 /// Clears a structured buffer
 /// </summary>
 /// <param name="buffer">The structured buffer.</param>
 /// <param name="value">Set this value for the whole buffer.</param>
 public void Clear(Buffer buffer, int value)
 {
     throw new NotImplementedException();
 }
Beispiel #14
0
            public void DisposeBuffers()
            {
                if (AppendBuffer != null)
                {
                    AppendBuffer.Release();
                    AppendBuffer = null;
                }

                if (ConsumeBuffer != null)
                {
                    ConsumeBuffer.Release();
                    ConsumeBuffer = null;
                }
            }
Beispiel #15
0
 /// <summary>
 /// Allocates the buffers.
 /// </summary>
 public void AllocateBuffers(GraphicsDevice graphicsDevice)
 {
     DisposeBuffers();
     AppendBuffer = Buffer.StructuredAppend.New(graphicsDevice, UserState.Count, StructureSize);
     ConsumeBuffer = Buffer.StructuredAppend.New(graphicsDevice, UserState.Count, StructureSize);
 }
Beispiel #16
0
 /// <summary>
 /// Allocates global buffers.
 /// </summary>
 private void OnCapacityCountChange()
 {
     // Allocate global buffers
     bool allocateGlobalBuffer = false;
     if (globalBuffer == null)
     {
         allocateGlobalBuffer = true;
     }
     else if (globalBuffer.ElementCount != CapacityCount)
     {
         // Reallocate global buffer if capacity changed
         allocateGlobalBuffer = true;
         // Release previous buffer
         globalBuffer.Release();
         sortBuffer.Release();
     }
     
     // Allocate new buffers
     if (allocateGlobalBuffer)
     {
         if (CapacityCount > 0)
         {
             globalBuffer = Buffer.Structured.New(graphicsDeviceService.GraphicsDevice, CapacityCount, StructureSize, true);
             globalBuffer.Name = "ParticleGlobalBuffer";
             sortBuffer = Buffer.Structured.New(graphicsDeviceService.GraphicsDevice, CapacityCount, sizeof(int) * 2, true);
             sortBuffer.Name = "ParticleSortBuffer";
         }
     }
 }