Exemple #1
0
            public void Build(CommandList commandList, LightSpot lightSpot)
            {
                int[] indices;

                if (lightSpot.ProjectiveTexture != null)    // If no projection texture has been supplied, we render the regular cone:
                {
                    indices      = BuildRectangleIndexBuffer();
                    vertexBuffer = Buffer.Vertex.New(graphicsDevice, new VertexPositionNormalTexture[9], GraphicsResourceUsage.Dynamic);
                    RebuildRectangleVertexBuffer(commandList, lightSpot);
                }
                else    // If a projection texture has been supplied, we render a rectangular frustum instead:
                {
                    indices      = BuildConeIndexBuffer();
                    vertexBuffer = Buffer.Vertex.New(graphicsDevice, new VertexPositionNormalTexture[4 * Tesselation + 1], GraphicsResourceUsage.Dynamic);
                    RebuildConeVertexBuffer(commandList, lightSpot);
                }

                MeshDraw = new MeshDraw
                {
                    PrimitiveType = PrimitiveType.LineList,
                    DrawCount     = indices.Length,
                    IndexBuffer   = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices), true, indices.Length),
                    VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount) },
                };
            }
Exemple #2
0
            public void Build(CommandList commandList, CameraParameters parameters)
            {
                var indices = new []
                {
                    0, 1,
                    1, 2,
                    2, 3,
                    3, 0,

                    4, 5,
                    5, 6,
                    6, 7,
                    7, 4,

                    0, 4,
                    1, 5,
                    2, 6,
                    3, 7
                };

                vertexBuffer = Buffer.Vertex.New(graphicsDevice, new VertexPositionNormalTexture[8], GraphicsResourceUsage.Dynamic);
                RebuildVertexBuffer(commandList, parameters);

                MeshDraw = new MeshDraw
                {
                    PrimitiveType = PrimitiveType.LineList,
                    DrawCount     = indices.Length,
                    IndexBuffer   = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices), true, indices.Length),
                    VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount) },
                };
            }
Exemple #3
0
        public static unsafe Buffer SetDataFromStream(this Buffer buffer, CommandList commandList, Stream stream)
        {
            var pool  = ArrayPool <byte> .Shared;
            var chunk = pool.Rent(Math.Min(buffer.SizeInBytes, 0x10000));

            try
            {
                fixed(byte *chunkPtr = chunk)
                {
                    var offset = 0;

                    while (stream.CanRead)
                    {
                        var bytesRead = stream.Read(chunk, 0, chunk.Length);
                        if (bytesRead > 0)
                        {
                            var dp = new DataPointer(chunkPtr, bytesRead);
                            buffer.SetData(commandList, dp, offset);
                            offset += bytesRead;
                        }
                    }
                }
            }
            finally
            {
                pool.Return(chunk);
            }
            return(buffer);
        }
Exemple #4
0
        public static unsafe Buffer New <TData>(GraphicsDevice device, Spread <TData> fromData, BufferFlags bufferFlags, GraphicsResourceUsage usage) where TData : struct
        {
            var immutableArray = fromData._array;
            var array          = Unsafe.As <ImmutableArray <TData>, TData[]>(ref immutableArray);

            return(Buffer.New(device, array, bufferFlags, usage));
        }
Exemple #5
0
        private static unsafe bool getMeshOutputs(Xenko.Rendering.Mesh modelMesh, out List <Vector3> positions, out List <int> indicies)
        {
            if (modelMesh.Draw is StagedMeshDraw)
            {
                StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                object verts = smd.Verticies;

                if (verts is VertexPositionNormalColor[])
                {
                    VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else if (verts is VertexPositionNormalTexture[])
                {
                    VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else if (verts is VertexPositionNormalTextureTangent[])
                {
                    VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else
                {
                    positions = null;
                    indicies  = null;
                    return(false);
                }

                // take care of indicies
                indicies = new List <int>((int[])(object)smd.Indicies);
            }
            else
            {
                Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                if (buf == null || buf.VertIndexData == null ||
                    ibuf == null || ibuf.VertIndexData == null)
                {
                    positions = null;
                    indicies  = null;
                    return(false);
                }

                if (ModelBatcher.UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                   out Vector3[] arraypositions, out Core.Mathematics.Vector3[] normals, out Core.Mathematics.Vector2[] uvs,
Exemple #6
0
        private static unsafe bool getMeshOutputs(Xenko.Rendering.Mesh modelMesh, out List <Vector3> positions, out List <int> indicies)
        {
            if (modelMesh.Draw is StagedMeshDraw)
            {
                StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                object verts = smd.Verticies;

                if (verts is VertexPositionNormalColor[])
                {
                    VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else if (verts is VertexPositionNormalTexture[])
                {
                    VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else if (verts is VertexPositionNormalTextureTangent[])
                {
                    VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else
                {
                    throw new ArgumentException("Couldn't get StageMeshDraw mesh, unknown vert type for " + modelMesh.Name);
                }

                // take care of indicies
                indicies = new List <int>(smd.Indicies.Length);
                for (int i = 0; i < smd.Indicies.Length; i++)
                {
                    indicies.Add((int)smd.Indicies[i]);
                }
            }
            else
            {
                Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                if (buf == null || buf.VertIndexData == null ||
                    ibuf == null || ibuf.VertIndexData == null)
                {
                    throw new ArgumentException("Couldn't get mesh for " + modelMesh.Name + ", buffer wasn't stored probably. Try Xenko.Graphics.Buffer.CaptureAllModelBuffers to true.");
                }

                if (ModelBatcher.UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                   out Vector3[] arraypositions, out Core.Mathematics.Vector3[] normals, out Core.Mathematics.Vector2[] uvs,
Exemple #7
0
        //    public static unsafe void WriteToDisk(this Buffer buffer, string filepath)
        //    {

        //    }

        //    public static unsafe void WriteToDisk(this Buffer buffer, Stream stream)
        //    {
        //        buffer.GetData()

        //        var pool = ArrayPool<byte>.Shared;
        //        var chunk = pool.Rent(Math.Min(buffer.SizeInBytes, 0x10000));
        //        try
        //        {
        //            fixed (byte* chunkPtr = chunk)
        //            {
        //                var offset = 0;
        //                while (stream.CanRead)
        //                {
        //                    var bytesRead = stream.Read(chunk, 0, chunk.Length);
        //                    if (bytesRead > 0)
        //                    {
        //                        var dp = new DataPointer(chunkPtr, bytesRead);
        //                        buffer.SetData(commandList, dp, offset);
        //                        offset += bytesRead;
        //                    }
        //                }
        //            }
        //        }
        //        finally
        //        {
        //            pool.Return(chunk);
        //        }
        //    }
        //}

        public static unsafe Buffer SetDataFromFile(this Buffer buffer, CommandList commandList, string filepath)
        {
            using (var stream = File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                buffer.SetDataFromStream(commandList, stream);
            }
            return(buffer);
        }
Exemple #8
0
        /// <summary>
        /// Copies the <paramref name="fromData"/> to the given <paramref name="buffer"/> on GPU memory.
        /// </summary>
        /// <typeparam name="TData">The type of the T data.</typeparam>
        /// <param name="buffer">The <see cref="Buffer"/>.</param>
        /// <param name="commandList">The <see cref="CommandList"/>.</param>
        /// <param name="fromData">The data to copy from.</param>
        /// <param name="offsetInBytes">The offset in bytes to write to.</param>
        /// <exception cref="ArgumentException"></exception>
        /// <remarks>
        /// See the unmanaged documentation about Map/UnMap for usage and restrictions.
        /// </remarks>
        /// <returns>The GPU buffer.</returns>
        public static unsafe Buffer SetData <TData>(this Buffer buffer, CommandList commandList, Spread <TData> fromData, int offsetInBytes = 0) where TData : struct
        {
            var immutableArray = fromData._array;
            var array          = Unsafe.As <ImmutableArray <TData>, TData[]>(ref immutableArray);

            buffer.SetData(commandList, array, offsetInBytes);
            return(buffer);
        }
Exemple #9
0
 public static unsafe Buffer SetDataFromXenkoAssetURL(this Buffer buffer, CommandList commandList, Game game, string url)
 {
     using (var stream = game.Content.OpenAsStream(url, StreamFlags.None))
     {
         buffer.SetDataFromStream(commandList, stream);
     }
     return(buffer);
 }
Exemple #10
0
        public static CommandList CopyResource(this CommandList commandList, Buffer sourceBuffer, Buffer targetBuffer)
        {
            var bufferS = (SharpDX.Direct3D11.Buffer)nativeDeviceChildFi.GetValue(sourceBuffer);
            var bufferT = (SharpDX.Direct3D11.Buffer)nativeDeviceChildFi.GetValue(targetBuffer);

            commandList.GetNativeDeviceContext().CopyResource(bufferS, bufferT);
            return(commandList);
        }
Exemple #11
0
        public static CommandList CopyStructureCount(this CommandList commandList, Buffer sourceBuffer, Buffer targetBuffer, int destinationAlignedByteOffset)
        {
            var buffer = (SharpDX.Direct3D11.Buffer)nativeDeviceChildFi.GetValue(targetBuffer);
            var uav    = (SharpDX.Direct3D11.UnorderedAccessView)unorderedAccessViewFi.GetValue(sourceBuffer);

            commandList.GetNativeDeviceContext().CopyStructureCount(buffer, destinationAlignedByteOffset, uav);
            return(commandList);
        }
 public void ReleaseBuffers(RenderDrawContext renderDrawContext)
 {
     // Release the temporary vertex buffer
     if (VertexBuffer != null)
     {
         renderDrawContext.GraphicsContext.Allocator.ReleaseReference(VertexBuffer);
         VertexBuffer = null;
     }
 }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public override void Dispose()
        {
            if (VertexBuffer != null && !VertexBuffer.IsDisposed)
            {
                VertexBuffer.Dispose();
            }

            if (effect != null && !effect.IsDisposed)
            {
                effect.Dispose();
            }
        }
Exemple #14
0
        public static bool DisposeBufferBySpecs(Xenko.Graphics.Buffer buf, int count)
        {
            if (buf == null || buf.ElementCount != count)
            {
                if (buf != null)
                {
                    buf.Dispose();
                }

                return(true);
            }
            return(false);
        }
        private bool NeedToRecreateBuffer(Xenko.Graphics.Buffer buf, int count)
        {
            if (buf == null || buf.ElementCount != count)
            {
                if (buf != null)
                {
                    buf.Dispose();
                }

                return(true);
            }
            return(false);
        }
        public void UpdateTempStorage(VoxelStorageContext context)
        {
            storageUints       = (tempStorageCounter + 31) / 32;
            tempStorageCounter = 0;

            var resolution = ClipMapResolution;
            int fragments  = (int)(resolution.X * resolution.Y * resolution.Z) * ClipMapCount;

            if (VoxelUtils.DisposeBufferBySpecs(FragmentsBuffer, storageUints * fragments) && storageUints * fragments > 0)
            {
                FragmentsBuffer = Xenko.Graphics.Buffer.Typed.New(context.device, storageUints * fragments, PixelFormat.R32_UInt, true);
            }
        }
Exemple #17
0
            public void Build()
            {
                var indices  = new int[2 * Tesselation * 3];
                var vertices = new VertexPositionNormalTexture[(Tesselation + 1) * 3];

                int indexCount  = 0;
                int vertexCount = 0;

                // the two rings
                for (int j = 0; j < 3; j++)
                {
                    var rotation = Matrix.Identity;
                    if (j == 1)
                    {
                        rotation = Matrix.RotationX((float)Math.PI / 2);
                    }
                    else if (j == 2)
                    {
                        rotation = Matrix.RotationY((float)Math.PI / 2);
                    }

                    for (int i = 0; i <= Tesselation; i++)
                    {
                        var longitude = (float)(i * 2.0 * Math.PI / Tesselation);
                        var dx        = (float)Math.Cos(longitude);
                        var dy        = (float)Math.Sin(longitude);

                        var normal = new Vector3(dx, dy, 0);
                        Vector3.TransformNormal(ref normal, ref rotation, out normal);

                        if (i < Tesselation)
                        {
                            indices[indexCount++] = vertexCount;
                            indices[indexCount++] = vertexCount + 1;
                        }

                        vertices[vertexCount++] = new VertexPositionNormalTexture(normal, normal, new Vector2(0));
                    }
                }

                vertexBuffer = Buffer.Vertex.New(graphicsDevice, vertices);
                MeshDraw     = new MeshDraw
                {
                    PrimitiveType = PrimitiveType.LineList,
                    DrawCount     = indices.Length,
                    IndexBuffer   = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices), true, indices.Length),
                    VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount) },
                };
            }
        /// <inheritdoc/>
        protected override void InitializeCore()
        {
            base.InitializeCore();

            RenderFeatures.CollectionChanged += RenderFeatures_CollectionChanged;

            foreach (var renderFeature in RenderFeatures)
            {
                renderFeature.AttachRootRenderFeature(this);
                renderFeature.Initialize(Context);
            }

            // Create an empty buffer to compensate for missing vertex streams
            emptyBuffer = Buffer.Vertex.New(Context.GraphicsDevice, new Vector4[1]);
        }
        protected override void Destroy()
        {
            foreach (var renderFeature in RenderFeatures)
            {
                renderFeature.Dispose();
            }

            RenderFeatures.CollectionChanged -= RenderFeatures_CollectionChanged;

            descriptorSets.Dispose();

            emptyBuffer?.Dispose();
            emptyBuffer = null;

            base.Destroy();
        }
Exemple #20
0
        public void Dispose()
        {
            performStage = null;

            if (_vertexBuffer != null)
            {
                _vertexBuffer.Dispose();
            }
            if (_indexBuffer != null)
            {
                _indexBuffer.Dispose();
            }

            _vertexBuffer = null;
            _indexBuffer  = null;
        }
Exemple #21
0
        private static byte[] GetDataSafe(this Buffer buffer, CommandList commandList = null)
        {
            var data = buffer.GetSerializationData();

            if (data != null)
            {
                return(data.Content);
            }

            if (commandList == null)
            {
                throw new InvalidOperationException("Could not find underlying CPU buffer data and no command list was given to extract them from GPU");
            }

            return(buffer.GetData <byte>(commandList));
        }
        public override void Unload()
        {
            // Dispose GPU resources
            lightClusters?.Dispose();
            lightClusters = null;

            lightIndicesBuffer?.Dispose();
            lightIndicesBuffer = null;

            pointLightsBuffer?.Dispose();
            pointLightsBuffer = null;

            spotLightsBuffer?.Dispose();
            spotLightsBuffer = null;

            base.Unload();
        }
Exemple #23
0
        public void Dispose()
        {
            performStage = null;

            if (_vertexBuffer != null)
            {
                StagedBufferTrashBin.Enqueue(_vertexBuffer);
            }

            if (_indexBuffer != null)
            {
                StagedBufferTrashBin.Enqueue(_indexBuffer);
            }

            _vertexBuffer = null;
            _indexBuffer  = null;
        }
Exemple #24
0
            public void Build()
            {
                var indices  = new int[12 * 2];
                var vertices = new VertexPositionNormalTexture[8];

                vertices[0] = new VertexPositionNormalTexture(new Vector3(-1, 1, -1), Vector3.UnitY, Vector2.Zero);
                vertices[1] = new VertexPositionNormalTexture(new Vector3(-1, 1, 1), Vector3.UnitY, Vector2.Zero);
                vertices[2] = new VertexPositionNormalTexture(new Vector3(1, 1, 1), Vector3.UnitY, Vector2.Zero);
                vertices[3] = new VertexPositionNormalTexture(new Vector3(1, 1, -1), Vector3.UnitY, Vector2.Zero);

                int indexOffset = 0;

                // Top sides
                for (int i = 0; i < 4; i++)
                {
                    indices[indexOffset++] = i;
                    indices[indexOffset++] = (i + 1) % 4;
                }

                // Duplicate vertices and indices to bottom part
                for (int i = 0; i < 4; i++)
                {
                    vertices[i + 4]            = vertices[i];
                    vertices[i + 4].Position.Y = -vertices[i + 4].Position.Y;

                    indices[indexOffset++] = indices[i * 2] + 4;
                    indices[indexOffset++] = indices[i * 2 + 1] + 4;
                }

                // Sides
                for (int i = 0; i < 4; i++)
                {
                    indices[indexOffset++] = i;
                    indices[indexOffset++] = i + 4;
                }

                vertexBuffer = Buffer.Vertex.New(graphicsDevice, vertices);
                MeshDraw     = new MeshDraw
                {
                    PrimitiveType = PrimitiveType.LineList,
                    DrawCount     = indices.Length,
                    IndexBuffer   = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices), true, indices.Length),
                    VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount) },
                };
            }
        private void Init()
        {
            _tribuf = Buffer.New(GraphicsDevice, new[]
            {
                new Vector4(-0.5f, 0.5f, 0, 1),
                new Vector4(0.5f, 0.5f, 0, 1),
                new Vector4(0, -0.5f, 0, 1)
            }, BufferFlags.VertexBuffer, GraphicsResourceUsage.Immutable);

            simpleEffect = new EffectInstance(new Effect(GraphicsDevice, SpriteEffect.Bytecode));
            simpleEffect.Parameters.Set(SpriteBaseKeys.MatrixTransform, Matrix.Identity);
            simpleEffect.UpdateEffect(GraphicsDevice);

            pipelineState = new MutablePipelineState(GraphicsDevice);
            pipelineState.State.SetDefaults();
            pipelineState.State.InputElements = VertexDeclaration.CreateInputElements();
            pipelineState.State.PrimitiveType = PrimitiveType;
        }
Exemple #26
0
        public void Dispose()
        {
            performStage = null;

            if (_vertexBuffer != null)
            {
                _vertexBuffer.DestroyNow();
                _vertexBuffer.Dispose();
                Disposed++;
            }
            if (_indexBuffer != null)
            {
                _indexBuffer.DestroyNow();
                _indexBuffer.Dispose();
            }

            _vertexBuffer = null;
            _indexBuffer  = null;
        }
Exemple #27
0
        private Model CreateModel()
        {
            // https://doc.xenko.com/latest/en/manual/scripts/create-a-model-from-code.html
            var indexBuffer = new Buffer();

            var indexBufferBinding  = new IndexBufferBinding(indexBuffer, true, 10);
            var vertexBufferBinding = new VertexBufferBinding();

            VertexBufferBinding[] vertexBufferBindings = { vertexBufferBinding };

            var meshDraw = new MeshDraw
            {
                VertexBuffers = vertexBufferBindings,
                IndexBuffer   = indexBufferBinding
            };
            ParameterCollection parms = null;
            var mesh = new Xenko.Rendering.Mesh(meshDraw, parms);

            var model = new Model {
                mesh
            };

            return(model);
        }
Exemple #28
0
        private unsafe Mesh ConvertToMesh(GraphicsDevice graphicsDevice, PrimitiveType primitiveType, LightProbeRuntimeData lightProbeRuntimeData)
        {
            // Generate data for vertex buffer
            var vertices = new VertexPositionNormalColor[lightProbeRuntimeData.LightProbes.Length];

            for (var i = 0; i < lightProbeRuntimeData.LightProbes.Length; i++)
            {
                vertices[i] = new VertexPositionNormalColor(lightProbeRuntimeData.Vertices[i], Vector3.Zero, Color4.White);
            }

            // Generate data for index buffer
            var indices = new int[lightProbeRuntimeData.Faces.Count * 6];

            for (var i = 0; i < lightProbeRuntimeData.Faces.Count; ++i)
            {
                var currentFace = lightProbeRuntimeData.Faces[i];

                // Skip infinite edges to not clutter display
                // Maybe we could reenable it when we have better infinite nodes
                if (currentFace.Vertices[0] >= lightProbeRuntimeData.UserVertexCount ||
                    currentFace.Vertices[1] >= lightProbeRuntimeData.UserVertexCount ||
                    currentFace.Vertices[2] >= lightProbeRuntimeData.UserVertexCount)
                {
                    continue;
                }

                indices[i * 6 + 0] = currentFace.Vertices[0];
                indices[i * 6 + 1] = currentFace.Vertices[1];
                indices[i * 6 + 2] = currentFace.Vertices[1];
                indices[i * 6 + 3] = currentFace.Vertices[2];
                indices[i * 6 + 4] = currentFace.Vertices[2];
                indices[i * 6 + 5] = currentFace.Vertices[0];
            }

            var boundingBox = BoundingBox.Empty;

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

            // Compute bounding sphere
            BoundingSphere boundingSphere;

            fixed(void *verticesPtr = vertices)
            BoundingSphere.FromPoints((IntPtr)verticesPtr, 0, vertices.Length, VertexPositionNormalTexture.Size, out boundingSphere);

            var layout = vertices[0].GetLayout();

            var meshDraw = new MeshDraw
            {
                IndexBuffer   = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indices).RecreateWith(indices), true, indices.Length),
                VertexBuffers = new[] { new VertexBufferBinding(Buffer.New(graphicsDevice, vertices, BufferFlags.VertexBuffer).RecreateWith(vertices), layout, vertices.Length) },
                DrawCount     = indices.Length,
                PrimitiveType = primitiveType,
            };

            wireframeResources.Add(meshDraw.VertexBuffers[0].Buffer);
            wireframeResources.Add(meshDraw.IndexBuffer.Buffer);

            return(new Mesh {
                Draw = meshDraw, BoundingBox = boundingBox, BoundingSphere = boundingSphere
            });
        }
Exemple #29
0
        private static unsafe void ProcessMaterial(List <BatchingChunk> chunks, MaterialInstance material, Model prefabModel, HashSet <Entity> unbatched = null)
        {
            //actually create the mesh
            List <VertexPositionNormalTextureTangent> vertsNT = null;
            List <VertexPositionNormalColor>          vertsNC = null;
            List <uint> indiciesList = new List <uint>();
            BoundingBox bb           = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity),
                                                       new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity));
            uint indexOffset = 0;

            for (int i = 0; i < chunks.Count; i++)
            {
                BatchingChunk chunk = chunks[i];
                if (unbatched != null && unbatched.Contains(chunk.Entity))
                {
                    continue;                                                        // don't try batching other things in this entity if some failed
                }
                if (chunk.Entity != null)
                {
                    chunk.Entity.Transform.UpdateLocalMatrix();
                    chunk.Entity.Transform.UpdateWorldMatrixInternal(true, false);
                }
                Matrix worldMatrix = chunk.Entity == null ? (chunk.Transform ?? Matrix.Identity) : chunk.Entity.Transform.WorldMatrix;
                Matrix rot;
                if (worldMatrix != Matrix.Identity)
                {
                    worldMatrix.GetRotationMatrix(out rot);
                }
                else
                {
                    rot = Matrix.Identity;
                }
                for (int j = 0; j < chunk.Model.Meshes.Count; j++)
                {
                    Mesh modelMesh = chunk.Model.Meshes[j];
                    //process only right material
                    if (modelMesh.MaterialIndex == chunk.MaterialIndex)
                    {
                        Vector3[] positions = null, normals = null;
                        Vector4[] tangents  = null;
                        Vector2[] uvs       = null;
                        Color4[]  colors    = null;

                        //vertexes
                        if (CachedModelData.TryGet(modelMesh, out var information))
                        {
                            // clone positions and normals, since they may change
                            positions = (Vector3[])information.positions.Clone();
                            normals   = (Vector3[])information.normals.Clone();
                            tangents  = information.tangents;
                            uvs       = information.uvs;
                            colors    = information.colors;
                            for (int k = 0; k < information.indicies.Length; k++)
                            {
                                indiciesList.Add(information.indicies[k] + indexOffset);
                            }
                        }
                        else if (modelMesh.Draw is StagedMeshDraw)
                        {
                            StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                            object verts = smd.Verticies;

                            if (verts is VertexPositionNormalColor[])
                            {
                                VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                colors    = new Color4[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    colors[k]    = vpnc[k].Color;
                                }
                            }
                            else if (verts is VertexPositionNormalTexture[])
                            {
                                VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                uvs       = new Vector2[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    uvs[k]       = vpnc[k].TextureCoordinate;
                                }
                            }
                            else if (verts is VertexPositionNormalTextureTangent[])
                            {
                                VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                uvs       = new Vector2[vpnc.Length];
                                tangents  = new Vector4[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    uvs[k]       = vpnc[k].TextureCoordinate;
                                    tangents[k]  = vpnc[k].Tangent;
                                }
                            }
                            else
                            {
                                // unsupported StagedMeshDraw
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            // take care of indicies
                            for (int k = 0; k < smd.Indicies.Length; k++)
                            {
                                indiciesList.Add(smd.Indicies[k] + indexOffset);
                            }

                            // cache this for later
                            CachedModelData.Add(modelMesh,
                                                new CachedData()
                            {
                                colors    = colors,
                                indicies  = smd.Indicies,
                                normals   = (Vector3[])normals.Clone(),
                                positions = (Vector3[])positions.Clone(),
                                tangents  = tangents,
                                uvs       = uvs
                            }
                                                );
                        }
                        else
                        {
                            Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                            Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                            if (buf == null || buf.VertIndexData == null ||
                                ibuf == null || ibuf.VertIndexData == null)
                            {
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            if (UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                  out positions, out normals, out uvs, out colors, out tangents) == false)
                            {
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            CachedData cmd = new CachedData()
                            {
                                colors    = colors,
                                positions = (Vector3[])positions.Clone(),
                                normals   = (Vector3[])normals.Clone(),
                                uvs       = uvs,
                                tangents  = tangents
                            };

                            // indicies
                            fixed(byte *pdst = ibuf.VertIndexData)
                            {
                                int numIndices = modelMesh.Draw.IndexBuffer.Count;

                                cmd.indicies = new uint[numIndices];

                                if (modelMesh.Draw.IndexBuffer.Is32Bit)
                                {
                                    var dst = (uint *)(pdst + modelMesh.Draw.IndexBuffer.Offset);
                                    for (var k = 0; k < numIndices; k++)
                                    {
                                        // Offset indices
                                        cmd.indicies[k] = dst[k];
                                        indiciesList.Add(dst[k] + indexOffset);
                                    }
                                }
                                else
                                {
                                    var dst = (ushort *)(pdst + modelMesh.Draw.IndexBuffer.Offset);
                                    for (var k = 0; k < numIndices; k++)
                                    {
                                        // Offset indices
                                        cmd.indicies[k] = dst[k];
                                        indiciesList.Add(dst[k] + indexOffset);
                                    }
                                }
                            }

                            CachedModelData.Add(modelMesh, cmd);
                        }

                        // what kind of structure will we be making, if we haven't picked one already?
                        if (vertsNT == null && vertsNC == null)
                        {
                            if (uvs != null)
                            {
                                vertsNT = new List <VertexPositionNormalTextureTangent>(positions.Length);
                            }
                            else
                            {
                                vertsNC = new List <VertexPositionNormalColor>(positions.Length);
                            }
                        }

                        // bounding box/finish list
                        bool needmatrix = worldMatrix != Matrix.Identity;
                        for (int k = 0; k < positions.Length; k++)
                        {
                            if (needmatrix)
                            {
                                Vector3.Transform(ref positions[k], ref worldMatrix, out positions[k]);

                                if (normals != null)
                                {
                                    Vector3.TransformNormal(ref normals[k], ref rot, out normals[k]);
                                }
                            }

                            // update bounding box?
                            Vector3 pos = positions[k];
                            if (pos.X > bb.Maximum.X)
                            {
                                bb.Maximum.X = pos.X;
                            }
                            if (pos.Y > bb.Maximum.Y)
                            {
                                bb.Maximum.Y = pos.Y;
                            }
                            if (pos.Z > bb.Maximum.Z)
                            {
                                bb.Maximum.Z = pos.Z;
                            }
                            if (pos.X < bb.Minimum.X)
                            {
                                bb.Minimum.X = pos.X;
                            }
                            if (pos.Y < bb.Minimum.Y)
                            {
                                bb.Minimum.Y = pos.Y;
                            }
                            if (pos.Z < bb.Minimum.Z)
                            {
                                bb.Minimum.Z = pos.Z;
                            }

                            if (vertsNT != null)
                            {
                                vertsNT.Add(new VertexPositionNormalTextureTangent
                                {
                                    Position          = positions[k],
                                    Normal            = normals != null ? normals[k] : Vector3.UnitY,
                                    TextureCoordinate = uvs[k],
                                    Tangent           = tangents != null ? tangents[k] : Vector4.UnitW
                                });
                            }
                            else
                            {
                                vertsNC.Add(new VertexPositionNormalColor
                                {
                                    Position = positions[k],
                                    Normal   = normals != null ? normals[k] : Vector3.UnitY,
                                    Color    = colors != null ? colors[k] : Color4.White
                                });
                            }
                        }

                        indexOffset += (uint)positions.Length;
                    }
                }
            }

            if (indiciesList.Count <= 0)
            {
                return;
            }

            uint[] indicies = indiciesList.ToArray();

            // make stagedmesh with verts
            StagedMeshDraw md;

            if (vertsNT != null)
            {
                var vertsNTa = vertsNT.ToArray();
                md = StagedMeshDraw.MakeStagedMeshDraw <VertexPositionNormalTextureTangent>(ref indicies, ref vertsNTa, VertexPositionNormalTextureTangent.Layout);
            }
            else if (vertsNC != null)
            {
                var vertsNCa = vertsNC.ToArray();
                md = StagedMeshDraw.MakeStagedMeshDraw <VertexPositionNormalColor>(ref indicies, ref vertsNCa, VertexPositionNormalColor.Layout);
            }
            else
            {
                return;
            }

            Mesh m = new Mesh
            {
                Draw          = md,
                BoundingBox   = bb,
                MaterialIndex = prefabModel.Materials.Count
            };

            prefabModel.Add(m);
            if (material != null)
            {
                prefabModel.Add(material);
            }
        }
        public virtual void Collect(RenderContext Context, IShadowMapRenderer ShadowMapRenderer)
        {
            renderVoxelVolumes = Context.VisibilityGroup.Tags.Get(CurrentRenderVoxelVolumes);

            if (renderVoxelVolumes == null)
            {
                return;
            }

            Vector3 resolutionMax     = new Vector3(0, 0, 0);
            int     fragmentsMax      = 0;
            int     fragmentsCountMax = 0;

            //Create per-volume textures
            foreach (var pair in renderVoxelVolumes)
            {
                var volume = pair.Value;
                var bounds = volume.ClipMapMatrix.ScaleVector;

                var resolution = bounds / volume.AproxVoxelSize;

                //Calculate closest power of 2 on each axis
                resolution.X = (float)Math.Pow(2, Math.Round(Math.Log(resolution.X, 2)));
                resolution.Y = (float)Math.Pow(2, Math.Round(Math.Log(resolution.Y, 2)));
                resolution.Z = (float)Math.Pow(2, Math.Round(Math.Log(resolution.Z, 2)));

                resolution = new Vector3(resolution.X, resolution.Z, resolution.Y);//Temporary

                Vector3 ClipMapResolution = new Vector3(resolution.X, resolution.Y, resolution.Z * volume.ClipMapCount);
                Vector3 MipMapResolution  = resolution / 2;

                RenderVoxelVolumeData data;
                if (!renderVoxelVolumeData.TryGetValue(pair.Key, out data))
                {
                    renderVoxelVolumeData.Add(pair.Key, data = new RenderVoxelVolumeData());
                }

                data.ClipMapResolution = resolution;
                if (NeedToRecreateTexture(data.ClipMaps, ClipMapResolution))
                {
                    data.ClipMaps = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)ClipMapResolution.X, (int)ClipMapResolution.Y, (int)ClipMapResolution.Z, new MipMapCount(false), Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);
                }
                if (NeedToRecreateTexture(data.MipMaps, resolution))
                {
                    data.MipMaps = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)MipMapResolution.X, (int)MipMapResolution.Y, (int)MipMapResolution.Z, new MipMapCount(true), Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);
                }


                resolutionMax     = Vector3.Min(new Vector3(256), Vector3.Max(resolutionMax, resolution));
                fragmentsMax      = Math.Max(fragmentsMax, (int)(ClipMapResolution.X * ClipMapResolution.Y * ClipMapResolution.Z));
                fragmentsCountMax = Math.Max(fragmentsCountMax, (int)(ClipMapResolution.X * ClipMapResolution.Y) * volume.ClipMapCount);
            }

            //Create re-usable textures

            float resolutionMaxSide = Math.Max(Math.Max(resolutionMax.X, resolutionMax.Y), resolutionMax.Z);

            if (NeedToRecreateTexture(MSAARenderTarget, new Vector3(resolutionMaxSide, resolutionMaxSide, 1)))
            {
                MSAARenderTarget = Texture.New(Context.GraphicsDevice, TextureDescription.New2D((int)resolutionMaxSide, (int)resolutionMaxSide, new MipMapCount(false), PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget, 1, GraphicsResourceUsage.Default, MultisampleCount.X8), null);
            }

            if (NeedToRecreateBuffer(Fragments, fragmentsMax))
            {
                Fragments = Xenko.Graphics.Buffer.Structured.New(Context.GraphicsDevice, fragmentsMax, 24, true);
            }
            if (NeedToRecreateBuffer(FragmentsCounter, fragmentsCountMax))
            {
                FragmentsCounter = Xenko.Graphics.Buffer.Typed.New(Context.GraphicsDevice, fragmentsCountMax, PixelFormat.R32_SInt, true);
            }

            Vector3 MipMapResolutionMax = resolutionMax / 2;

            if (TempMipMaps == null || !TextureDimensionsEqual(TempMipMaps[0], MipMapResolutionMax))
            {
                if (TempMipMaps != null)
                {
                    for (int i = 0; i < TempMipMaps.Length; i++)
                    {
                        TempMipMaps[0].Dispose();
                    }
                }

                int mipCount = 1 + (int)Math.Floor(Math.Log(Math.Max(MipMapResolutionMax.X, Math.Max(MipMapResolutionMax.Y, MipMapResolutionMax.Z)), 2));

                TempMipMaps = new Xenko.Graphics.Texture[mipCount];

                for (int i = 0; i < TempMipMaps.Length; i++)
                {
                    TempMipMaps[i] = Xenko.Graphics.Texture.New3D(Context.GraphicsDevice, (int)MipMapResolutionMax.X, (int)MipMapResolutionMax.Y, (int)MipMapResolutionMax.Z, false, Xenko.Graphics.PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);

                    MipMapResolutionMax /= 2;
                    MipMapResolutionMax  = Vector3.Max(new Vector3(1), MipMapResolutionMax);
                }
            }
            if (Generate3DMipmaps == null)
            {
                Generate3DMipmaps = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "Generate3DMipmaps"
                };
                ClearBuffer = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "ClearBuffer"
                };
                ArrangeFragments = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(Context)
                {
                    ShaderSourceName = "ArrangeFragments"
                };
            }

            //Create all the views
            reflectiveVoxelViews.Clear();
            foreach (var pair in renderVoxelVolumes)
            {
                var volume = pair.Value;
                var data   = renderVoxelVolumeData[pair.Key];
                var bounds = volume.ClipMapMatrix.ScaleVector;

                var shadowRenderView = new RenderView();

                float nearClip = 0.1f;
                float farClip  = 999.7f;
                //Currently hard coded and kinda odd
                shadowRenderView.View       = Matrix.Translation(0.0f, 1.0f, 0.0f) * Matrix.RotationX(-3.1415f / 2.0f);
                shadowRenderView.Projection = Matrix.OrthoRH(bounds.X * (float)Math.Pow(2, volume.ClipMapCount), bounds.Z * (float)Math.Pow(2, volume.ClipMapCount), nearClip, farClip);
                Matrix.Multiply(ref shadowRenderView.View, ref shadowRenderView.Projection, out shadowRenderView.ViewProjection);
                shadowRenderView.Frustum     = new BoundingFrustum(ref shadowRenderView.ViewProjection);
                shadowRenderView.CullingMode = CameraCullingMode.Frustum;
                shadowRenderView.ViewSize    = new Vector2(1024, 1024);

                float maxRes = Math.Max(Math.Max(data.ClipMapResolution.X, data.ClipMapResolution.Y), data.ClipMapResolution.Z);

                var rotmat = new Matrix(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1);//xzy

                var viewToTexTrans = Matrix.Translation(0.5f, 0.5f, 0.5f);
                var viewToTexScale = Matrix.Scaling(0.5f, 0.5f, 0.5f);
                var viewportAspect = Matrix.Scaling(data.ClipMapResolution / maxRes);

                // Matrix BaseVoxelMatrix = transmat * scalemat * rotmat;
                Matrix BaseVoxelMatrix = volume.ClipMapMatrix * Matrix.Identity;
                BaseVoxelMatrix.Invert();
                BaseVoxelMatrix = BaseVoxelMatrix * Matrix.Scaling(2f, 2f, 2f) * rotmat;

                data.Matrix         = BaseVoxelMatrix * viewToTexScale * viewToTexTrans;
                data.ViewportMatrix = BaseVoxelMatrix * viewportAspect;
                data.ClipMapCount   = volume.ClipMapCount;

                shadowRenderView.NearClipPlane = nearClip;
                shadowRenderView.FarClipPlane  = farClip;
                shadowRenderView.RenderStages.Add(VoxelStage);

                reflectiveVoxelViews.Add(shadowRenderView, pair.Key);

                // Add the render view for the current frame
                Context.RenderSystem.Views.Add(shadowRenderView);

                // Collect objects in shadow views
                Context.VisibilityGroup.TryCollect(shadowRenderView);

                ShadowMapRenderer?.RenderViewsWithShadows.Add(shadowRenderView);
            }
        }