示例#1
0
            private void UpdateVertexBuffer(GraphicsDevice device)
            {
                if (_disposed || _updateQueued)
                {
                    return;
                }

                var indices = Indices;
                PooledIndexBuffer currentBuffer = Buffer;

                if (indices.Length > 0 && (Buffer == null || currentBuffer.IndexCount != indices.Length))
                {
                    _updateQueued = true;

                    Alex.Instance.UIThreadQueue.Enqueue(
                        () =>
                    {
                        if (_disposed)
                        {
                            return;
                        }

                        PooledIndexBuffer buffer = GpuResourceManager.GetIndexBuffer(
                            this, device, IndexElementSize.SixteenBits, indices.Length, BufferUsage.None);

                        buffer.SetData(indices);
                        Buffer = buffer;

                        currentBuffer?.MarkForDisposal();

                        _updateQueued = false;
                    });
                }
            }
示例#2
0
            private void UpdateVertexBuffer(GraphicsDevice device)
            {
                var indices = Indices;

                PooledIndexBuffer currentBuffer = Buffer;

                if (indices.Length > 0 && (Buffer == null || currentBuffer.IndexCount != indices.Length))
                {
                    PooledIndexBuffer buffer = GpuResourceManager.GetIndexBuffer(this, device, IndexElementSize.SixteenBits,
                                                                                 indices.Length, BufferUsage.None);

                    buffer.SetData(indices);
                    Buffer = buffer;

                    currentBuffer?.MarkForDisposal();
                }
            }
示例#3
0
        private void SetVertices()
        {
            var b = _blockStates[_index];

            var vertices = b.Model
                           .GetVertices(World
                                        , Vector3.Zero, _blockStates[_index].Block);

            if (vertices.vertices.Length > 0 && vertices.indexes.Length > 0)
            {
                var oldBuffer      = _buffer;
                var oldIndexBuffer = _indexBuffer;

                var newBuffer = GpuResourceManager.GetBuffer(this, Alex.GraphicsDevice,
                                                             VertexPositionNormalTextureColor.VertexDeclaration,
                                                             vertices.vertices.Length, BufferUsage.None);

                var newIndexBuffer = GpuResourceManager.GetIndexBuffer(this, Alex.GraphicsDevice,
                                                                       IndexElementSize.ThirtyTwoBits,
                                                                       vertices.indexes.Length, BufferUsage.None);

                newBuffer.SetData(vertices.vertices);

                newIndexBuffer.SetData(vertices.indexes);

                _buffer      = newBuffer;
                _indexBuffer = newIndexBuffer;

                oldIndexBuffer?.MarkForDisposal();
                oldBuffer?.MarkForDisposal();

                GraphicsDevice.Indices = _indexBuffer;
                GraphicsDevice.SetVertexBuffer(_buffer);

                _canRender = true;
            }

            // _vertices = vertices.vertices;
            // _indices = vertices.indexes;
        }
示例#4
0
        internal bool UpdateChunk(ChunkCoordinates coordinates, IChunkColumn c)
        {
            var chunk = c as ChunkColumn;

            if (!Monitor.TryEnter(chunk.UpdateLock))
            {
                Interlocked.Decrement(ref _chunkUpdates);
                return(false); //Another thread is already updating this chunk, return.
            }

            var       scheduleType = chunk.Scheduled;
            var       profiler     = MiniProfiler.StartNew("chunk.update");
            ChunkData data         = null;
            bool      force        = !_chunkData.TryGetValue(coordinates, out data);

            try
            {
                //chunk.UpdateChunk(Graphics, World);

                var currentChunkY = Math.Min(((int)Math.Round(_cameraPosition.Y)) >> 4, (chunk.GetHeighest() >> 4) - 2);
                if (currentChunkY < 0)
                {
                    currentChunkY = 0;
                }

                List <ChunkMesh> meshes = new List <ChunkMesh>();
                using (profiler.Step("chunk.sections"))
                {
                    for (var i = chunk.Sections.Length - 1; i >= 0; i--)
                    {
                        if (i < 0)
                        {
                            break;
                        }
                        var section = chunk.Sections[i] as ChunkSection;
                        if (section == null || section.IsEmpty())
                        {
                            continue;
                        }

                        if (i != currentChunkY && i != 0)
                        {
                            using (profiler.Step("chunk.neighboring"))
                            {
                                if (i > 0 && i < chunk.Sections.Length - 1)
                                {
                                    var neighbors = chunk.CheckNeighbors(section, i, World).ToArray();

                                    if (!section.HasAirPockets && neighbors.Length == 6) //All surrounded by solid.
                                    {
                                        // Log.Info($"Found section with solid neigbors, skipping.");
                                        continue;
                                    }

                                    if (i < currentChunkY && neighbors.Length >= 6)
                                    {
                                        continue;
                                    }
                                }
                                else if (i < currentChunkY)
                                {
                                    continue;
                                }
                            }
                        }

                        //if (i == 0) force = true;

                        if (force || !section.ScheduledUpdates.IsZero || section.IsDirty)
                        {
                            using (profiler.Step("chunk.meshing"))
                            {
                                var sectionMesh = GenerateSectionMesh(World, scheduleType,
                                                                      new Vector3(chunk.X * 16f, 0, chunk.Z * 16f), ref section, i);

                                meshes.Add(sectionMesh);
                            }
                        }
                    }
                }

                List <VertexPositionNormalTextureColor> vertices = new List <VertexPositionNormalTextureColor>();
                List <int> transparentIndexes = new List <int>();
                List <int> solidIndexes       = new List <int>();
                List <int> animatedIndexes    = new List <int>();

                foreach (var mesh in meshes)
                {
                    var startVerticeIndex = vertices.Count;
                    vertices.AddRange(mesh.Vertices);

                    solidIndexes.AddRange(mesh.SolidIndexes.Select(a => startVerticeIndex + a));

                    transparentIndexes.AddRange(mesh.TransparentIndexes.Select(a => startVerticeIndex + a));

                    animatedIndexes.AddRange(mesh.AnimatedIndexes.Select(a => startVerticeIndex + a));
                }

                if (vertices.Count > 0)
                {
                    ProfilerService.ReportCount("chunk.vertexCount", vertices.Count);

                    using (profiler.Step("chunk.buffer"))
                    {
                        var vertexArray      = vertices.ToArray();
                        var solidArray       = solidIndexes.ToArray();
                        var transparentArray = transparentIndexes.ToArray();
                        var animatedArray    = animatedIndexes.ToArray();

                        if (data == null)
                        {
                            data = new ChunkData()
                            {
                                Buffer = GpuResourceManager.GetBuffer(this, Graphics,
                                                                      VertexPositionNormalTextureColor.VertexDeclaration, vertexArray.Length,
                                                                      BufferUsage.WriteOnly),
                                SolidIndexBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                     IndexElementSize.ThirtyTwoBits,
                                                                                     solidArray.Length, BufferUsage.WriteOnly),
                                TransparentIndexBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                           IndexElementSize.ThirtyTwoBits,
                                                                                           transparentArray.Length, BufferUsage.WriteOnly),
                                AnimatedIndexBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                        IndexElementSize.ThirtyTwoBits,
                                                                                        animatedArray.Length, BufferUsage.WriteOnly)
                            };
                        }

                        PooledVertexBuffer oldBuffer = data.Buffer;

                        PooledVertexBuffer newVertexBuffer           = null;
                        PooledIndexBuffer  newsolidIndexBuffer       = null;
                        PooledIndexBuffer  newTransparentIndexBuffer = null;
                        PooledIndexBuffer  newAnimatedIndexBuffer    = null;

                        PooledIndexBuffer oldAnimatedIndexBuffer    = data.AnimatedIndexBuffer;
                        PooledIndexBuffer oldSolidIndexBuffer       = data.SolidIndexBuffer;
                        PooledIndexBuffer oldTransparentIndexBuffer = data.TransparentIndexBuffer;

                        using (profiler.Step("chunk.buffer.check"))
                            if (vertexArray.Length >= data.Buffer.VertexCount)
                            {
                                // var oldBuffer = data.Buffer;
                                PooledVertexBuffer newBuffer = GpuResourceManager.GetBuffer(this, Graphics,
                                                                                            VertexPositionNormalTextureColor.VertexDeclaration, vertexArray.Length,
                                                                                            BufferUsage.WriteOnly);

                                newBuffer.SetData(vertexArray);
                                newVertexBuffer = newBuffer;
                                //  data.Buffer = newBuffer;
                                //  oldBuffer?.Dispose();

                                ProfilerService.ReportCount("chunk.bufferSize", data.Buffer.MemoryUsage);

                                ProfilerService.TriggerCounter("chunk.bufferResize");
                            }
                            else
                            {
                                data.Buffer.SetData(vertexArray);
                                ProfilerService.ReportCount("chunk.bufferSize", data.Buffer.MemoryUsage);
                            }

                        using (profiler.Step("Chunk Solid indexbuffer check"))
                            if (solidArray.Length > data.SolidIndexBuffer.IndexCount)
                            {
                                //  var old = data.SolidIndexBuffer;
                                var newSolidBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                       IndexElementSize.ThirtyTwoBits,
                                                                                       solidArray.Length,
                                                                                       BufferUsage.WriteOnly);

                                newSolidBuffer.SetData(solidArray);
                                newsolidIndexBuffer = newSolidBuffer;
                                //  data.SolidIndexBuffer = newSolidBuffer;
                                //   old?.Dispose();
                            }
                            else
                            {
                                data.SolidIndexBuffer.SetData(solidArray);
                            }

                        using (profiler.Step("Chunk Transparent indexbuffer check"))
                            if (transparentArray.Length > data.TransparentIndexBuffer.IndexCount)
                            {
                                //  var old = data.TransparentIndexBuffer;
                                var newTransparentBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                             IndexElementSize.ThirtyTwoBits,
                                                                                             transparentArray.Length,
                                                                                             BufferUsage.WriteOnly);

                                newTransparentBuffer.SetData(transparentArray);
                                newTransparentIndexBuffer = newTransparentBuffer;
                            }
                            else
                            {
                                data.TransparentIndexBuffer.SetData(transparentArray);
                            }

                        using (profiler.Step("Chunk Animated indexbuffer check"))
                            if (animatedArray.Length > data.AnimatedIndexBuffer.IndexCount)
                            {
                                //  var old = data.TransparentIndexBuffer;
                                var newTransparentBuffer = GpuResourceManager.GetIndexBuffer(this, Graphics,
                                                                                             IndexElementSize.ThirtyTwoBits,
                                                                                             animatedArray.Length,
                                                                                             BufferUsage.WriteOnly);

                                newTransparentBuffer.SetData(animatedArray);
                                newAnimatedIndexBuffer = newTransparentBuffer;
                            }
                            else
                            {
                                data.AnimatedIndexBuffer.SetData(animatedArray);
                            }

                        using (profiler.Step("chunk.buffer.dispose"))
                        {
                            if (newVertexBuffer != null)
                            {
                                data.Buffer = newVertexBuffer;
                                oldBuffer?.MarkForDisposal();
                            }

                            if (newTransparentIndexBuffer != null)
                            {
                                data.TransparentIndexBuffer = newTransparentIndexBuffer;
                                oldTransparentIndexBuffer?.MarkForDisposal();
                            }

                            if (newAnimatedIndexBuffer != null)
                            {
                                data.AnimatedIndexBuffer = newAnimatedIndexBuffer;
                                oldAnimatedIndexBuffer?.MarkForDisposal();
                            }

                            if (newsolidIndexBuffer != null)
                            {
                                data.SolidIndexBuffer = newsolidIndexBuffer;
                                oldSolidIndexBuffer?.MarkForDisposal();
                            }
                        }
                    }
                }
                else
                {
                    if (data != null)
                    {
                        data.Dispose();
                        data = null;
                    }
                }

                chunk.IsDirty   = chunk.HasDirtySubChunks; //false;
                chunk.Scheduled = ScheduleType.Unscheduled;

                if (data != null)
                {
                    data.Coordinates = coordinates;
                }

                _chunkData.AddOrUpdate(coordinates, data, (chunkCoordinates, chunkData) => data);

                return(true);
            }
            catch (Exception ex)
            {
                Log.Error(ex, $"Exception while updating chunk: {ex.ToString()}");
            }
            finally
            {
                //Enqueued.Remove(new ChunkCoordinates(chunk.X, chunk.Z));
                Interlocked.Decrement(ref _chunkUpdates);
                Monitor.Exit(chunk.UpdateLock);

                profiler.Stop();

                //   Log.Info(MiniProfiler.Current.RenderPlainText());
            }

            return(false);
        }