/// <summary>
        /// Adds a display object to the batch.
        /// </summary>
        /// <param name="displayObject">Display object to add.</param>
        /// <param name="drawer">Drawer of the batch.</param>
        public bool Add(ModelDisplayObject displayObject, InstancedModelDrawer drawer)
        {
            //In theory, don't need to test for dupliate entries since batch.Add
            //should only be called through a InstancedModelDrawer's add (which checks beforehand).
            if (displayObjects.Count == MaximumObjectsPerBatch ||
                ((indices.Length / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch &&
                 displayObjects.Count > 0))
            {
                return(false);
            }
            displayObjects.Add(displayObject);
            int instanceIndex = displayObjects.Count - 1;
            var textureIndex  = displayObject.TextureIndex;

            displayObject.GetVertexData(vertexList, indexList, this, (ushort)vertices.Length, indices.Length, instanceIndex);
            //Add the data to the batch.
            var newVertices = new VertexPositionNormalTexture[vertices.Length + vertexList.Count];

            vertices.CopyTo(newVertices, 0);
            vertexList.CopyTo(newVertices, vertices.Length);
            vertices = newVertices;

            var newIndices = new ushort[indices.Length + indexList.Count];

            indices.CopyTo(newIndices, 0);
            indexList.CopyTo(newIndices, indices.Length);
            indices = newIndices;

            var newInstancingVertices = new InstancedVertex[instancedVertices.Length + vertexList.Count];

            instancedVertices.CopyTo(newInstancingVertices, 0);
            for (int i = instancedVertices.Length; i < newInstancingVertices.Length; i++)
            {
                newInstancingVertices[i] = new InstancedVertex {
                    InstanceIndex = instanceIndex, TextureIndex = textureIndex
                }
            }
            ;
            instancedVertices = newInstancingVertices;

            vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
            instancingBuffer = new VertexBuffer(graphicsDevice, InstancedVertex.VertexDeclaration, instancedVertices.Length, BufferUsage.WriteOnly);
            instancingBuffer.SetData(instancedVertices);
            bindings    = new VertexBufferBinding[] { vertexBuffer, instancingBuffer };
            indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly);
            indexBuffer.SetData(indices);

            vertexList.Clear();
            indexList.Clear();
            return(true);
        }
Example #2
0
        /// <summary>
        /// Adds a display object to the batch.
        /// </summary>
        /// <param name="displayObject">Display object to add.</param>
        /// <param name="drawer">Drawer of the batch.</param>
        public unsafe bool Add(ModelDisplayObject displayObject, InstancedModelDrawer drawer)
        {
            //In theory, don't need to test for duplicate entries since batch.Add
            //should only be called through a InstancedModelDrawer's add (which checks beforehand).
            if (displayObjects.Count == MaximumObjectsPerBatch ||
                ((indexCount / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch &&
                 displayObjects.Count > 0))
            {
                return(false);
            }
            displayObjects.Add(displayObject);
            int instanceIndex = displayObjects.Count - 1;
            var textureIndex  = displayObject.TextureIndex;

            //OUegheogh, this could just directly write into the batch's vertex/index cache rather than going through a list and recopy.
            displayObject.GetVertexData(vertexList, indexList, this, (ushort)vertexCount, indexCount, instanceIndex);
            vertexList.CopyTo(vertices, vertexCount);
            indexList.CopyTo(indices, indexCount);

            var newIndexCount  = indexCount + indexList.Count;
            var newVertexCount = vertexCount + vertexList.Count;

            for (int i = vertexCount; i < newVertexCount; i++)
            {
                instancedVertices[i] = new InstancedVertex {
                    InstanceIndex = instanceIndex, TextureIndex = textureIndex
                }
            }
            ;

            vertexBuffer.SetData(sizeof(VertexPositionNormalTexture) * vertexCount, vertices, vertexCount, vertexList.Count, sizeof(VertexPositionNormalTexture));
            instancedBuffer.SetData(sizeof(InstancedVertex) * vertexCount, instancedVertices, vertexCount, vertexList.Count, sizeof(InstancedVertex));
            indexBuffer.SetData(sizeof(ushort) * indexCount, indices, indexCount, indexList.Count);

            vertexCount = newVertexCount;
            indexCount  = newIndexCount;

            vertexList.Clear();
            indexList.Clear();
            return(true);
        }
        /// <summary>
        /// Adds a display object to the batch.
        /// </summary>
        /// <param name="displayObject">Display object to add.</param>
        /// <param name="drawer">Drawer of the batch.</param>
        public bool Add(ModelDisplayObject displayObject, InstancedModelDrawer drawer)
        {
            //In theory, don't need to test for dupliate entries since batch.Add
            //should only be called through a InstancedModelDrawer's add (which checks beforehand).
            if (displayObjects.Count == MaximumObjectsPerBatch ||
                ((indices.Length / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch &&
                 displayObjects.Count > 0))
                return false;
            displayObjects.Add(displayObject);
            int instanceIndex = displayObjects.Count - 1;
            var textureIndex = displayObject.TextureIndex;
            displayObject.GetVertexData(vertexList, indexList, this, (ushort)vertices.Length, indices.Length, instanceIndex);
            //Add the data to the batch.
            var newVertices = new VertexPositionNormalTexture[vertices.Length + vertexList.Count];
            vertices.CopyTo(newVertices, 0);
            vertexList.CopyTo(newVertices, vertices.Length);
            vertices = newVertices;

            var newIndices = new ushort[indices.Length + indexList.Count];
            indices.CopyTo(newIndices, 0);
            indexList.CopyTo(newIndices, indices.Length);
            indices = newIndices;

            var newInstancingVertices = new InstancedVertex[instancedVertices.Length + vertexList.Count];
            instancedVertices.CopyTo(newInstancingVertices, 0);
            for (int i = instancedVertices.Length; i < newInstancingVertices.Length; i++)
                newInstancingVertices[i] = new InstancedVertex { InstanceIndex = instanceIndex, TextureIndex = textureIndex };
            instancedVertices = newInstancingVertices;

            vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
            instancingBuffer = new VertexBuffer(graphicsDevice, InstancedVertex.VertexDeclaration, instancedVertices.Length, BufferUsage.WriteOnly);
            instancingBuffer.SetData(instancedVertices);
            bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer };
            indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly);
            indexBuffer.SetData(indices);

            vertexList.Clear();
            indexList.Clear();
            return true;
        }