Exemple #1
0
        public void AddVertices <T>(BatchInfo material, VertexMode vertexMode, T[] vertexBuffer, int vertexCount) where T : struct, IVertexData
        {
            if (vertexCount == 0)
            {
                return;
            }
            if (vertexBuffer == null || vertexBuffer.Length == 0)
            {
                return;
            }
            if (vertexCount > vertexBuffer.Length)
            {
                vertexCount = vertexBuffer.Length;
            }
            if (material == null)
            {
                material = Material.Checkerboard.Res.InfoDirect;
            }

            if (this.pickingIndex != 0)
            {
                ColorRgba clr = new ColorRgba((this.pickingIndex << 8) | 0xFF);
                for (int i = 0; i < vertexCount; ++i)
                {
                    vertexBuffer[i].Color = clr;
                }

                material           = new BatchInfo(material);
                material.Technique = DrawTechnique.Picking;
                if (material.Textures == null)
                {
                    material.MainTexture = Texture.White;
                }
            }
            else if (material.Technique == null || !material.Technique.IsAvailable)
            {
                material           = new BatchInfo(material);
                material.Technique = DrawTechnique.Solid;
            }

            // When rendering without depth writing, use z sorting everywhere - there's no real depth buffering!
            bool zSort = !this.DepthWrite || material.Technique.Res.NeedsZSort;
            List <IDrawBatch> buffer     = zSort ? this.drawBufferZSort : this.drawBuffer;
            float             zSortIndex = zSort ? DrawBatch <T> .CalcZSortIndex(vertexBuffer, vertexCount) : 0.0f;

            if (buffer.Count > 0 && buffer[buffer.Count - 1].CanAppendJIT <T>(
                    zSort ? 1.0f / this.zSortAccuracy : 0.0f,
                    zSortIndex,
                    material,
                    vertexMode))
            {
                buffer[buffer.Count - 1].AppendJIT(vertexBuffer, vertexCount);
            }
            else
            {
                buffer.Add(new DrawBatch <T>(material, vertexMode, vertexBuffer, vertexCount, zSortIndex));
            }
            ++this.numRawBatches;
        }
Exemple #2
0
        /// <summary>
        /// Adds an already prepared batch to the drawing devices rendering schedule.
        /// </summary>
        /// <param name="batch"></param>
        public void AddBatch(DrawBatch batch)
        {
            bool sortByDepth = (this.projection == ProjectionMode.Screen) || batch.Material.Technique.Res.NeedsZSort;
            RawList <DrawBatch> batchBuffer = sortByDepth ? this.batchBufferBlended : this.batchBufferSolid;

            batchBuffer.Add(batch);
            ++this.numRawBatches;
        }
Exemple #3
0
        private void AggregateBatches(RawList <SortItem> sortItems, RawList <VertexDrawItem> drawItems, RawList <DrawBatch> batches)
        {
            VertexDrawItem[] drawData = drawItems.Data;
            SortItem[]       sortData = sortItems.Data;

            SortItem       activeSortItem  = sortData[0];
            VertexDrawItem activeItem      = drawData[activeSortItem.DrawItemIndex];
            int            beginBatchIndex = 0;

            // Find sequences of draw items that can be batched together
            int count = sortItems.Count;

            for (int sortIndex = 1; sortIndex <= count; sortIndex++)
            {
                // Skip items until we can no longer put the next one into the same batch
                if (sortIndex < count)
                {
                    SortItem sortItem = sortData[sortIndex];
                    if (activeItem.CanShareBatchWith(ref drawData[sortItem.DrawItemIndex]))
                    {
                        continue;
                    }
                }

                // Create a batch for all previous items
                VertexBuffer vertexBuffer = this.vertexBuffers[activeItem.TypeIndex][activeItem.BufferIndex];
                DrawBatch    batch        = new DrawBatch(
                    vertexBuffer,
                    this.batchIndexPool.Rent(sortIndex - beginBatchIndex),
                    activeItem.Mode,
                    activeItem.Material);

                for (int i = beginBatchIndex; i < sortIndex; i++)
                {
                    batch.VertexRanges.Add(new VertexDrawRange
                    {
                        Index = drawData[sortData[i].DrawItemIndex].Offset,
                        Count = drawData[sortData[i].DrawItemIndex].Count
                    });
                }

                batches.Add(batch);

                // Proceed with the current item being the new sharing reference
                if (sortIndex < count)
                {
                    beginBatchIndex = sortIndex;
                    activeSortItem  = sortData[sortIndex];
                    activeItem      = drawData[activeSortItem.DrawItemIndex];
                }
            }
        }
Exemple #4
0
        public void Append(DrawBatch <T> other)
        {
            if (this.vertexCount + other.vertexCount > this.vertices.Length)
            {
                int newArrSize = MathF.Max(16, this.vertexCount * 2, this.vertexCount + other.vertexCount);
                Array.Resize(ref this.vertices, newArrSize);
            }
            Array.Copy(other.vertices, 0, this.vertices, this.vertexCount, other.vertexCount);
            this.vertexCount += other.vertexCount;

            if (this.material.Technique.Res.NeedsZSort)
            {
                CalcZSortIndex();
            }
        }
Exemple #5
0
        public void UploadToVBO(List <IDrawBatch> batches)
        {
            int vertexCount = 0;

            T[] vertexData = null;

            if (batches.Count == 1)
            {
                // Only one batch? Don't bother copying data
                DrawBatch <T> b = batches[0] as DrawBatch <T>;
                vertexData  = b.vertices;
                vertexCount = b.vertices.Length;
            }
            else
            {
                // Check how many vertices we got
                vertexCount = batches.Sum(t => t.VertexCount);

                // Allocate a static / shared buffer for uploading vertices
                if (uploadBuffer == null)
                {
                    uploadBuffer = new T[Math.Max(vertexCount, 64)];
                }
                else if (uploadBuffer.Length < vertexCount)
                {
                    Array.Resize(ref uploadBuffer, Math.Max(vertexCount, uploadBuffer.Length * 2));
                }

                // Collect vertex data in one array
                int curVertexPos = 0;
                vertexData = uploadBuffer;
                for (int i = 0; i < batches.Count; i++)
                {
                    DrawBatch <T> b = batches[i] as DrawBatch <T>;
                    Array.Copy(b.vertices, 0, vertexData, curVertexPos, b.vertexCount);
                    curVertexPos += b.vertexCount;
                }
            }

            // Submit vertex data to GPU
            this.vertices[0].UploadToVBO(vertexData, vertexCount);
        }
Exemple #6
0
        public void AddVertices <T>(BatchInfo material, VertexMode vertexMode, T[] vertexBuffer, int vertexCount) where T : struct, IVertexData
        {
            if (vertexCount == 0)
            {
                return;
            }
            if (vertexBuffer == null || vertexBuffer.Length == 0)
            {
                return;
            }
            if (vertexCount > vertexBuffer.Length)
            {
                vertexCount = vertexBuffer.Length;
            }
            if (material == null)
            {
                material = Material.Checkerboard.Res.InfoDirect;
            }

            if (this.pickingIndex != 0)
            {
                ColorRgba clr = new ColorRgba((this.pickingIndex << 8) | 0xFF);
                for (int i = 0; i < vertexCount; ++i)
                {
                    vertexBuffer[i].Color = clr;
                }

                material           = new BatchInfo(material);
                material.Technique = DrawTechnique.Picking;
                if (material.Textures == null)
                {
                    material.MainTexture = Texture.White;
                }
            }
            else if (material.Technique == null || !material.Technique.IsAvailable)
            {
                material           = new BatchInfo(material);
                material.Technique = DrawTechnique.Solid;
            }

            // When rendering without depth writing, use z sorting everywhere - there's no real depth buffering!
            bool zSort = !this.DepthWrite || material.Technique.Res.NeedsZSort;
            List <IDrawBatch> buffer     = zSort ? this.drawBufferZSort : this.drawBuffer;
            float             zSortIndex = zSort ? DrawBatch <T> .CalcZSortIndex(vertexBuffer, vertexCount) : 0.0f;

            // Determine if we can append the incoming vertices into the previous batch
            IDrawBatch prevBatch = buffer.Count > 0 ? buffer[buffer.Count - 1] : null;

            if (prevBatch != null &&
                // ToDo: Move into CanAppendJIT on next major version step:
                // Make sure to not generate batches that will be in the Large Object Heap (>= 85k bytes)
                // because this will trigger lots and lots of Gen2 collections over time.
                vertexCount + prevBatch.VertexCount < 1024 &&
                // Check if the batches do match enough for being merged
                prevBatch.CanAppendJIT <T>(
                    zSort ? 1.0f : 0.0f,                     // Obsolete as of 2016-06-17, can be replcaed with zSort bool.
                    zSortIndex,
                    material,
                    vertexMode))
            {
                prevBatch.AppendJIT(vertexBuffer, vertexCount);
            }
            else
            {
                buffer.Add(new DrawBatch <T>(material, vertexMode, vertexBuffer, vertexCount, zSortIndex));
            }
            ++this.numRawBatches;
        }