Exemple #1
0
        public void Draw(Texture2D texture, Vector2 position, Rectangle?sourceRectangle, Color color)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = 0.0f;
            item.TextureID = (int)texture.ID;

            Rectangle rect;

            if (sourceRectangle.HasValue)
            {
                rect = sourceRectangle.Value;
            }
            else
            {
                rect = new Rectangle(0, 0, texture.Image.ImageWidth, texture.Image.ImageHeight);
            }

            Vector2 texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y);
            Vector2 texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height);

            item.Set(position.X, position.Y, rect.Width, rect.Height, color, texCoordTL, texCoordBR);
        }
Exemple #2
0
        public SpriteBatchItem CreateBatchItem()
        {
            SpriteBatchItem spriteBatchItem = this._freeBatchItemQueue.Count <= 0 ? new SpriteBatchItem() : this._freeBatchItemQueue.Dequeue();

            this._batchItemList.Add(spriteBatchItem);
            return(spriteBatchItem);
        }
Exemple #3
0
        public void Draw(Texture2D texture, Rectangle rectangle, Color color)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = 0;
            item.TextureID = (int)texture.ID;

            Vector2 texCoordTL = texture.Image.GetTextureCoord(0, 0);
            Vector2 texCoordBR = texture.Image.GetTextureCoord(texture.Image.ImageWidth, texture.Image.ImageHeight);

            item.Set
            (
                rectangle.X,
                rectangle.Y,
                rectangle.Width,
                rectangle.Height,
                color,
                texCoordTL,
                texCoordBR
            );
        }
Exemple #4
0
        public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle?sourceRectangle, Color color)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            // texture 0 is the texture beeing draw
            graphicsDevice.Textures[0] = texture;

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = 0.0f;
            item.TextureID = (int)texture.ID;

            if (sourceRectangle.HasValue)
            {
                tempRect = sourceRectangle.Value;
            }
            else
            {
                tempRect.X      = 0;
                tempRect.Y      = 0;
                tempRect.Width  = texture.Width;
                tempRect.Height = texture.Height;
            }

            if (texture.Image == null)
            {
                float texWidthRatio  = 1.0f / (float)texture.Width;
                float texHeightRatio = 1.0f / (float)texture.Height;
                // We are initially flipped vertically so we need to flip the corners so that
                //  the image is bottom side up to display correctly
                texCoordTL.X = tempRect.X * texWidthRatio;
                //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio;
                texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio;

                texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio;
                //texCoordBR.Y = tempRect.Y * texHeightRatio;
                texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio;
            }
            else
            {
                texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X);
                texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y);
                texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width);
                texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height);
            }

            item.Set(destinationRectangle.X,
                     destinationRectangle.Y,
                     destinationRectangle.Width,
                     destinationRectangle.Height,
                     color,
                     texCoordTL,
                     texCoordBR);
        }
Exemple #5
0
		public SpriteBatchItem CreateBatchItem()
		{
			SpriteBatchItem item;
			if ( _freeBatchItemQueue.Count > 0 )
				item = _freeBatchItemQueue.Dequeue();
			else
				item = new SpriteBatchItem();
			_batchItemList.Add(item);
			return item;
		}
Exemple #6
0
        public void Draw
        (
            Texture2D texture,
            Vector2 position,
            Color color
        )
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = 0;
            item.TextureID = (int)texture.ID;

            tempRect.X      = 0;
            tempRect.Y      = 0;
            tempRect.Width  = texture.Width;
            tempRect.Height = texture.Height;

            if (texture.Image == null)
            {
                float texWidthRatio  = 1.0f / (float)texture.Width;
                float texHeightRatio = 1.0f / (float)texture.Height;
                // We are initially flipped vertically so we need to flip the corners so that
                //  the image is bottom side up to display correctly
                texCoordTL.X = tempRect.X * texWidthRatio;
                //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio;
                texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio;

                texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio;
                //texCoordBR.Y = tempRect.Y * texHeightRatio;
                texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio;
            }
            else
            {
                texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X);
                texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y);
                texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width);
                texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height);
            }

            item.Set
            (
                position.X,
                position.Y,
                tempRect.Width,
                tempRect.Height,
                color,
                texCoordTL,
                texCoordBR
            );
        }
        public void Draw(Texture2D imgTexture, Texture2D locTexture, Vector2 position, Nullable <Rectangle> sourceRectangle, Color color, float rotation,
                         Vector2 origin, Vector2 scale, SpriteEffects effect, float depth)
        {//GG EDIT THIS IS NEW
            if (locTexture == null || imgTexture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = depth;
            item.TextureID = (int)imgTexture.ID;

            Rectangle rect;

            if (sourceRectangle.HasValue)
            {
                rect = sourceRectangle.Value;
            }
            else
            {
                rect = new Rectangle(0, 0, locTexture.Image.ImageWidth, locTexture.Image.ImageHeight);
            }

            Vector2 texCoordTL = locTexture.Image.GetTextureCoord(rect.X, rect.Y);
            Vector2 texCoordBR = locTexture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height);

            if ((effect & SpriteEffects.FlipVertically) != 0)
            {
                float temp = texCoordBR.Y;
                texCoordBR.Y = texCoordTL.Y;
                texCoordTL.Y = temp;
            }
            if ((effect & SpriteEffects.FlipHorizontally) != 0)
            {
                float temp = texCoordBR.X;
                texCoordBR.X = texCoordTL.X;
                texCoordTL.X = temp;
            }

            item.Set
            (
                position.X,
                position.Y,
                -origin.X * scale.X,
                -origin.Y * scale.Y,
                rect.Width * scale.X,
                rect.Height * scale.Y,
                (float)Math.Sin(rotation),
                (float)Math.Cos(rotation),
                color,
                texCoordTL,
                texCoordBR
            );
        }
Exemple #8
0
        public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle?sourceRectangle, Color color)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = 0.0f;
            item.TextureID = (int)texture.ID;

            Rectangle rect;

            if (sourceRectangle.HasValue)
            {
                rect = sourceRectangle.Value;
            }
            else
            {
                rect = new Rectangle(0, 0, texture.Width, texture.Height);
            }

            Vector2 texCoordTL;            // = texture.Image.GetTextureCoord ( rect.X, rect.Y );
            Vector2 texCoordBR;            // = texture.Image.GetTextureCoord ( rect.X+rect.Width, rect.Y+rect.Height );


            if (texture.Image == null)
            {
                float texWidthRatio  = 1.0f / (float)texture.Width;
                float texHeightRatio = 1.0f / (float)texture.Height;
                // We are initially flipped vertically so we need to flip the corners so that
                //  the image is bottom side up to display correctly
                texCoordTL = new Vector2(rect.X * texWidthRatio, (rect.Y + rect.Height) * texHeightRatio);
                texCoordBR = new Vector2((rect.X + rect.Width) * texWidthRatio,
                                         rect.Y * texHeightRatio);
            }
            else
            {
                texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y);
                texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height);
            }

            item.Set
            (
                destinationRectangle.X,
                destinationRectangle.Y,
                destinationRectangle.Width,
                destinationRectangle.Height,
                color,
                texCoordTL,
                texCoordBR);
        }
Exemple #9
0
        private SpriteBatchItem CreateBatchItem(Color Tint, int texId, float Depth)
        {
            // allocate 4 vertices for this quad, and set the batch pointer to the right offset.
            var bi = new SpriteBatchItem()
            {
                Tint = Tint, TextureID = texId, Depth = Depth, VertexBase = _vertexArray.Count
            };

            _vertexArray.AddN(4);

            return(bi);
        }
        public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable <Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = depth;
            item.TextureID = (int)texture.ID;

            Rectangle rect;

            if (sourceRectangle.HasValue)
            {
                rect = sourceRectangle.Value;
            }
            else
            {
                rect = new Rectangle(0, 0, texture.Image.ImageWidth, texture.Image.ImageHeight);
            }

            Vector2 texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y);
            Vector2 texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height);

            if ((effect & SpriteEffects.FlipVertically) != 0)
            {
                float temp = texCoordBR.Y;
                texCoordBR.Y = texCoordTL.Y;
                texCoordTL.Y = temp;
            }
            if ((effect & SpriteEffects.FlipHorizontally) != 0)
            {
                float temp = texCoordBR.X;
                texCoordBR.X = texCoordTL.X;
                texCoordTL.X = temp;
            }

            item.Set
            (
                destinationRectangle.X,
                destinationRectangle.Y,
                -origin.X,
                -origin.Y,
                destinationRectangle.Width,
                destinationRectangle.Height,
                (float)Math.Sin(rotation),
                (float)Math.Cos(rotation),
                color,
                texCoordTL,
                texCoordBR);
        }
Exemple #11
0
        public SpriteBatcher(GraphicsDevice device)
        {
            _device = device;

            _batchItemList  = new SpriteBatchItem[InitialBatchSize];
            _batchItemCount = 0;

            for (int i = 0; i < InitialBatchSize; i++)
            {
                _batchItemList[i] = new SpriteBatchItem();
            }

            EnsureArrayCapacity(InitialBatchSize);
        }
        public SpriteBatchItem CreateBatchItem()
        {
            SpriteBatchItem item;

            if (_freeBatchItemQueue.Count > 0)
            {
                item = _freeBatchItemQueue.Dequeue();
            }
            else
            {
                item = new SpriteBatchItem();
            }
            _batchItemList.Add(item);
            return(item);
        }
Exemple #13
0
        public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color)
        {
            if (spriteFont == null)
            {
                throw new ArgumentException("spriteFont");
            }

            Vector2 p = position;

            foreach (char c in text)
            {
                if (c == '\n')
                {
                    p.Y += spriteFont.LineSpacing;
                    p.X  = position.X;
                    continue;
                }
                if (spriteFont.characterData.ContainsKey(c) == false)
                {
                    continue;
                }
                GlyphData g = spriteFont.characterData[c];

                SpriteBatchItem item = _batcher.CreateBatchItem();

                item.Depth     = 0.0f;
                item.TextureID = (int)spriteFont._texture.ID;

                texCoordTL.X = spriteFont._texture.Image.GetTextureCoordX(g.Glyph.X);
                texCoordTL.Y = spriteFont._texture.Image.GetTextureCoordY(g.Glyph.Y);
                texCoordBR.X = spriteFont._texture.Image.GetTextureCoordX(g.Glyph.X + g.Glyph.Width);
                texCoordBR.Y = spriteFont._texture.Image.GetTextureCoordY(g.Glyph.Y + g.Glyph.Height);

                item.Set
                (
                    p.X,
                    p.Y + g.Cropping.Y,
                    g.Glyph.Width,
                    g.Glyph.Height,
                    color,
                    texCoordTL,
                    texCoordBR
                );

                p.X += (g.Kerning.Y + g.Kerning.Z + spriteFont.Spacing);
            }
        }
        /// <summary>
        /// Sorts the batch items and then groups batch drawing into maximal allowed batch sets that do not
        /// overflow the 16 bit array indices for vertices.
        /// </summary>
        /// <param name="sortMode">The type of depth sorting desired for the rendering.</param>
        /// <param name="effect">The custom effect to apply to the drawn geometry</param>
        public void DrawBatch(SpriteSortMode sortMode, Effect effect)
        {
            // nothing to do
            if (_batchItemList.Count == 0)
            {
                return;
            }

            // sort the batch items
            switch (sortMode)
            {
            case SpriteSortMode.Texture:
                // TODO: this is a quick inline sorting algorithm because the monogame sorting is broken
                // Not sure if this is the fastest way to do it but it has proven to be adequate for now.
                Texture2D current_tex = null;
                for (int point = 0; point < _batchItemList.Count; point++)
                {
                    current_tex = _batchItemList[point].Texture;
                    for (int i = point + 1; i < _batchItemList.Count; i++)
                    {
                        if (ReferenceEquals(current_tex, _batchItemList[i].Texture))
                        {
                            SpriteBatchItem temp = _batchItemList[point];
                            _batchItemList[point] = _batchItemList[i];
                            _batchItemList[i]     = temp;
                            point++;
                        }
                    }
                }
                //_batchItemList.Sort(CompareTexture);
                break;

            case SpriteSortMode.FrontToBack:
                _batchItemList.Sort(CompareDepth);
                break;

            case SpriteSortMode.BackToFront:
                _batchItemList.Sort(CompareReverseDepth);
                break;
            }

            DrawList(_batchItemList);
            _freeBatchItemPool.RestoreAll();
        }
Exemple #15
0
        /// <summary>
        /// Reuse a previously allocated SpriteBatchItem from the item pool.
        /// if there is none available grow the pool and initialize new items.
        /// </summary>
        /// <returns></returns>
        public SpriteBatchItem CreateBatchItem()
        {
            if (_batchItemCount >= _batchItemList.Length)
            {
                var oldSize = _batchItemList.Length;
                var newSize = oldSize + oldSize / 2; // grow by x1.5
                newSize = (newSize + 63) & (~63);    // grow in chunks of 64.
                Array.Resize(ref _batchItemList, newSize);
                for (int i = oldSize; i < newSize; i++)
                {
                    _batchItemList[i] = new SpriteBatchItem();
                }

                EnsureArrayCapacity(Math.Min(newSize, MaxBatchSize));
            }
            var item = _batchItemList[_batchItemCount++];

            return(item);
        }
Exemple #16
0
        /// <summary>
        /// Writes a string that is preprocessed as a vertex list (including rotation, scaling, flipping, etc). The
        /// characterVertices array must contain at least numVertices instances (each 4 representing a single sprite,
        /// which will be copied to the SpriteBatch's internal buffer.
        /// Vertices are expected in the order [TopLeft, TopRight, BottomLeft, BottomRight], repeated.
        ///
        /// The specified color is applied to the vertices in this function, the Red channel on each vertex is used as
        /// an index to the specified font texture array.
        /// </summary>
        public void DrawStringUnity(Texture2D[] fontTextures, int numVertices, VertexPositionColorTexture[] characterVertices, Color color)
        {
            // prepare texture instances
            for (int i = 0; i < numVertices;)
            {
                SpriteBatchItem item = _batcher.CreateBatchItem();
                // use the vertex color R channel as index for the texture array (avoids an extra parameter)
                item.Texture = fontTextures[characterVertices[i].Color.R];
                item.Depth   = 0;

                item.vertexTL = characterVertices[i++];
                item.vertexTR = characterVertices[i++];
                item.vertexBL = characterVertices[i++];
                item.vertexBR = characterVertices[i++];

                item.vertexTL.Color = color;
                item.vertexTR.Color = color;
                item.vertexBL.Color = color;
                item.vertexBR.Color = color;
            }
        }
Exemple #17
0
        internal void DrawInternal(Texture2D texture, Vector4 destinationRectangle, Rectangle?sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth)
        {
            SpriteBatchItem batchItem = this._batcher.CreateBatchItem();

            batchItem.Depth   = depth;
            batchItem.Texture = texture;
            if (sourceRectangle.HasValue)
            {
                this._tempRect = sourceRectangle.Value;
            }
            else
            {
                this._tempRect.X      = 0;
                this._tempRect.Y      = 0;
                this._tempRect.Width  = texture.Width;
                this._tempRect.Height = texture.Height;
            }
            this._texCoordTL.X = (float)this._tempRect.X / (float)texture.Width;
            this._texCoordTL.Y = (float)this._tempRect.Y / (float)texture.Height;
            this._texCoordBR.X = (float)(this._tempRect.X + this._tempRect.Width) / (float)texture.Width;
            this._texCoordBR.Y = (float)(this._tempRect.Y + this._tempRect.Height) / (float)texture.Height;
            if ((effect & SpriteEffects.FlipVertically) != SpriteEffects.None)
            {
                float num = this._texCoordBR.Y;
                this._texCoordBR.Y = this._texCoordTL.Y;
                this._texCoordTL.Y = num;
            }
            if ((effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None)
            {
                float num = this._texCoordBR.X;
                this._texCoordBR.X = this._texCoordTL.X;
                this._texCoordTL.X = num;
            }
            batchItem.Set(destinationRectangle.X, destinationRectangle.Y, -origin.X, -origin.Y, destinationRectangle.Z, destinationRectangle.W, (float)Math.Sin((double)rotation), (float)Math.Cos((double)rotation), color, this._texCoordTL, this._texCoordBR);
            if (this._sortMode != SpriteSortMode.Immediate)
            {
                return;
            }
            this._batcher.DrawBatch(this._sortMode);
        }
Exemple #18
0
        public SpriteBatcher(GraphicsDevice device, int capacity = 0)
        {
            _device = device;

            if (capacity <= 0)
            {
                capacity = InitialBatchSize;
            }
            else
            {
                capacity = (capacity + 63) & (~63); // ensure chunks of 64.
            }
            _batchItemList  = new SpriteBatchItem[capacity];
            _batchItemCount = 0;

            for (int i = 0; i < capacity; i++)
            {
                _batchItemList[i] = new SpriteBatchItem();
            }

            EnsureArrayCapacity(capacity);
        }
Exemple #19
0
        internal void DrawInternal(
            Texture2D texture,
            Vector4 destinationRectangle,
            Rectangle?sourceRectangle,
            Color color,
            float rotation,
            Vector2 origin,
            SpriteEffects effect,
            float depth,
            bool autoFlush
            )
        {
            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth   = depth;
            item.Texture = texture;

            if (sourceRectangle.HasValue)
            {
                _tempRect = sourceRectangle.Value;
            }
            else
            {
                _tempRect.X      = 0;
                _tempRect.Y      = 0;
                _tempRect.Width  = texture.Width;
                _tempRect.Height = texture.Height;
            }

            _texCoordTL.X = _tempRect.X / (float)texture.Width;
            _texCoordTL.Y = _tempRect.Y / (float)texture.Height;
            _texCoordBR.X = (_tempRect.X + _tempRect.Width) / (float)texture.Width;
            _texCoordBR.Y = (_tempRect.Y + _tempRect.Height) / (float)texture.Height;

            if ((effect & SpriteEffects.FlipVertically) != 0)
            {
                float temp = _texCoordBR.Y;
                _texCoordBR.Y = _texCoordTL.Y;
                _texCoordTL.Y = temp;
            }
            if ((effect & SpriteEffects.FlipHorizontally) != 0)
            {
                float temp = _texCoordBR.X;
                _texCoordBR.X = _texCoordTL.X;
                _texCoordTL.X = temp;
            }

            item.Set(
                destinationRectangle.X,
                destinationRectangle.Y,
                -origin.X,
                -origin.Y,
                destinationRectangle.Z,
                destinationRectangle.W,
                (float)Math.Sin(rotation),
                (float)Math.Cos(rotation),
                color,
                _texCoordTL,
                _texCoordBR
                );

            if (autoFlush)
            {
                FlushIfNeeded();
            }
        }
Exemple #20
0
 int CompareTexture( SpriteBatchItem a, SpriteBatchItem b )
 {
     return a.TextureID.CompareTo(b.TextureID);
 }
Exemple #21
0
        /// <summary>
        /// Sorts the batch items and then groups batch drawing into maximal allowed batch sets that do not
        /// overflow the 16 bit array indices for vertices.
        /// </summary>
        /// <param name="sortMode">The type of depth sorting desired for the rendering.</param>
        public void DrawBatch(SpriteSortMode sortMode)
        {
            // nothing to do
            if (_batchItemList.Count == 0)
            {
                return;
            }

            // sort the batch items
            switch (sortMode)
            {
            case SpriteSortMode.Texture:
                _batchItemList.Sort(CompareTexture);
                break;

            case SpriteSortMode.FrontToBack:
                _batchItemList.Sort(CompareDepth);
                break;

            case SpriteSortMode.BackToFront:
                _batchItemList.Sort(CompareReverseDepth);
                break;
            }

            // Determine how many iterations through the drawing code we need to make
            int batchIndex = 0;
            int batchCount = _batchItemList.Count;

            // Iterate through the batches, doing short.MaxValue sets of vertices only.
            while (batchCount > 0)
            {
                // setup the vertexArray array
                int       startIndex = 0;
                int       index      = 0;
                Texture2D tex        = null;

                int numBatchesToProcess = batchCount;
                if (numBatchesToProcess > MaxBatchSize)
                {
                    numBatchesToProcess = MaxBatchSize;
                }
                EnsureArrayCapacity(numBatchesToProcess);
                // Draw the batches
                for (int i = 0; i < numBatchesToProcess; i += 1, batchIndex += 1)
                {
                    SpriteBatchItem item = _batchItemList[batchIndex];
                    // if the texture changed, we need to flush and bind the new texture
                    bool shouldFlush = !ReferenceEquals(item.Texture, tex);
                    if (shouldFlush)
                    {
                        FlushVertexArray(startIndex, index);

                        tex                 = item.Texture;
                        startIndex          = index = 0;
                        _device.Textures[0] = tex;
                    }

                    // store the SpriteBatchItem data in our vertexArray
                    _vertexArray[index++] = item.vertexTL;
                    _vertexArray[index++] = item.vertexTR;
                    _vertexArray[index++] = item.vertexBL;
                    _vertexArray[index++] = item.vertexBR;

                    // Release the texture and return the item to the queue.
                    item.Texture = null;
                    _freeBatchItemQueue.Enqueue(item);
                }
                // flush the remaining vertexArray data
                FlushVertexArray(startIndex, index);
                // Update our batch count to continue the process of culling down
                // large batches
                batchCount -= numBatchesToProcess;
            }
            _batchItemList.Clear();
        }
        private void DrawList(List <SpriteBatchItem> list)
        {
            // Determine how many iterations through the drawing code we need to make
            int batchIndex = 0;
            int batchCount = list.Count;

            // Iterate through the batches, doing short.MaxValue sets of vertices only.
            while (batchCount > 0)
            {
                // setup the vertexArray array
                var       startIndex = 0;
                var       index      = 0;
                Texture2D tex        = null;

                int numBatchesToProcess = batchCount;
                if (numBatchesToProcess > MaxBatchSize)
                {
                    numBatchesToProcess = MaxBatchSize;
                }
                EnsureArrayCapacity(numBatchesToProcess);
                // Draw the batches
                for (int i = 0; i < numBatchesToProcess; i++, batchIndex++)
                {
                    SpriteBatchItem item = list[batchIndex];
                    // if the texture changed, we need to flush and bind the new texture
                    var shouldFlush = !ReferenceEquals(item.Texture, tex);
                    if (shouldFlush)
                    {
                        FlushVertexArray(startIndex, index);

                        tex        = item.Texture;
                        startIndex = index = 0;

                        _device.Textures[0] = tex;
                    }

                    // store the SpriteBatchItem data in our vertexArray
                    _vertexArray[index++] = item.vertexTL;
                    _vertexArray[index++] = item.vertexTR;
                    _vertexArray[index++] = item.vertexBL;
                    _vertexArray[index++] = item.vertexBR;

                    /*logCount++;
                     * if (logCount > 300)
                     * {
                     *      logCount = 0;
                     *      Console.WriteLine("Item vertex TL(x:" + item.vertexTL.Position.X + " y: " + item.vertexTL.Position.Y + ") --- " +
                     *              "vertex TR(x:" + item.vertexTR.Position.X + " y: " + item.vertexTR.Position.Y + ") --- " +
                     *              "vertex BL(x:" + item.vertexBL.Position.X + " y: " + item.vertexBL.Position.Y + ") --- " +
                     *              "vertex BR(x:" + item.vertexBR.Position.X + " y: " + item.vertexBR.Position.Y + ")");
                     * }*/

                    // Release the texture ( return the item to the queue later)
                    item.Texture = null;
                }
                // flush the remaining vertexArray data
                FlushVertexArray(startIndex, index);
                // Update our batch count to continue the process of culling down
                // large batches
                batchCount -= numBatchesToProcess;
            }
            list.Clear();
        }
 int CompareTexture(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(a.TextureID.CompareTo(b.TextureID));
 }
 int CompareReverseDepth(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(b.Depth.CompareTo(a.Depth));
 }
Exemple #25
0
		public SpriteBatcher (GraphicsDevice device)
		{
            _device = device;

			_batchItemList = new SpriteBatchItem[InitialBatchSize];
            _batchItemCount = 0;

            for (int i = 0; i < InitialBatchSize; i++)
                _batchItemList[i] = new SpriteBatchItem();

            EnsureArrayCapacity(InitialBatchSize);
		}
Exemple #26
0
        public void Draw(Texture2D texture,
                         Rectangle destinationRectangle,
                         Nullable <Rectangle> sourceRectangle,
                         Color color,
                         float rotation,
                         Vector2 origin,
                         SpriteEffects effect,
                         float depth)
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            // texture 0 is the texture beeing draw
            graphicsDevice.Textures[0] = texture;

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = depth;
            item.TextureID = (int)texture.ID;

            if (sourceRectangle.HasValue)
            {
                tempRect = sourceRectangle.Value;
            }
            else
            {
                tempRect.X      = 0;
                tempRect.Y      = 0;
                tempRect.Width  = texture.Width;
                tempRect.Height = texture.Height;
            }

            if (texture.Image == null)
            {
                float texWidthRatio  = 1.0f / (float)texture.Width;
                float texHeightRatio = 1.0f / (float)texture.Height;
                // We are initially flipped vertically so we need to flip the corners so that
                //  the image is bottom side up to display correctly
                texCoordTL.X = tempRect.X * texWidthRatio;
                //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio;
                texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio;

                texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio;
                //texCoordBR.Y = tempRect.Y * texHeightRatio;
                texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio;
            }
            else
            {
                texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X);
                texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y);
                texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width);
                texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height);
            }

            if ((effect & SpriteEffects.FlipVertically) != 0)
            {
                float temp = texCoordBR.Y;
                texCoordBR.Y = texCoordTL.Y;
                texCoordTL.Y = temp;
            }
            if ((effect & SpriteEffects.FlipHorizontally) != 0)
            {
                float temp = texCoordBR.X;
                texCoordBR.X = texCoordTL.X;
                texCoordTL.X = temp;
            }

            item.Set(destinationRectangle.X,
                     destinationRectangle.Y,
                     -origin.X,
                     -origin.Y,
                     destinationRectangle.Width,
                     destinationRectangle.Height,
                     (float)Math.Sin(rotation),
                     (float)Math.Cos(rotation),
                     color,
                     texCoordTL,
                     texCoordBR);
        }
Exemple #27
0
 /// <summary>
 /// Comparison of the underlying Texture objects for each given SpriteBatchitem.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns>0 if they are equal, -1 or 1 if not.</returns>
 static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(a.Texture.SortingKey.CompareTo(b.Texture.SortingKey));
 }
Exemple #28
0
        /// <summary>
        /// Sorts the batch items and then groups batch drawing into maximal allowed batch sets that do not
        /// overflow the 16 bit array indices for vertices.
        /// </summary>
        /// <param name="sortMode">The type of depth sorting desired for the rendering.</param>
        /// <param name="effect">The custom effect to apply to the drawn geometry</param>
        public unsafe void DrawBatch(SpriteSortMode sortMode, Effect effect)
        {
            // nothing to do
            if (_batchItemCount == 0)
            {
                return;
            }

            // sort the batch items
            switch (sortMode)
            {
            case SpriteSortMode.Texture:
            case SpriteSortMode.FrontToBack:
            case SpriteSortMode.BackToFront:
                Array.Sort(_batchItemList, 0, _batchItemCount);
                break;
            }

            // Determine how many iterations through the drawing code we need to make
            int batchIndex = 0;
            int batchCount = _batchItemCount;


            unchecked
            {
                _device._graphicsMetrics._spriteCount += (ulong)batchCount;
            }

            // Iterate through the batches, doing short.MaxValue sets of vertices only.
            while (batchCount > 0)
            {
                // setup the vertexArray array
                var       startIndex = 0;
                var       index      = 0;
                Texture2D tex        = null;

                int numBatchesToProcess = batchCount;
                if (numBatchesToProcess > MaxBatchSize)
                {
                    numBatchesToProcess = MaxBatchSize;
                }

                // Avoid the array checking overhead by using pointer indexing!
                fixed(VertexPositionColorTexture *vertexArrayFixedPtr = _vertexArray)
                {
                    var vertexArrayPtr = vertexArrayFixedPtr;

                    // Draw the batches
                    for (int i = 0; i < numBatchesToProcess; i++, batchIndex++, index += 4, vertexArrayPtr += 4)
                    {
                        SpriteBatchItem item = _batchItemList[batchIndex];
                        // if the texture changed, we need to flush and bind the new texture
                        var shouldFlush = !ReferenceEquals(item.Texture, tex);
                        if (shouldFlush)
                        {
                            FlushVertexArray(startIndex, index, effect, tex);

                            tex                 = item.Texture;
                            startIndex          = index = 0;
                            vertexArrayPtr      = vertexArrayFixedPtr;
                            _device.Textures[0] = tex;
                        }

                        // store the SpriteBatchItem data in our vertexArray
                        *(vertexArrayPtr + 0) = item.vertexTL;
                        *(vertexArrayPtr + 1) = item.vertexTR;
                        *(vertexArrayPtr + 2) = item.vertexBL;
                        *(vertexArrayPtr + 3) = item.vertexBR;

                        // Release the texture.
                        item.Texture = null;
                    }
                }

                // flush the remaining vertexArray data
                FlushVertexArray(startIndex, index, effect, tex);
                // Update our batch count to continue the process of culling down
                // large batches
                batchCount -= numBatchesToProcess;
            }
            // return items to the pool.
            _batchItemCount = 0;
        }
Exemple #29
0
 int CompareTexture(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(ReferenceEquals(a.Texture, b.Texture) ? 0 : 1);
 }
Exemple #30
0
 private static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(!object.ReferenceEquals((object)a.Texture, (object)b.Texture) ? 1 : 0);
 }
Exemple #31
0
		int CompareTexture ( SpriteBatchItem a, SpriteBatchItem b )
		{
            return ReferenceEquals( a.Texture, b.Texture ) ? 0 : 1;
		}
Exemple #32
0
 private static int CompareDepth(SpriteBatchItem a, SpriteBatchItem b)
 {
     return(a.Depth.CompareTo(b.Depth));
 }
Exemple #33
0
        /// <summary>
        /// Comparison of the underlying Texture objects for each given SpriteBatchitem.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns>0 if they are equal, -1 or 1 if not.</returns>
	    static int CompareTexture ( SpriteBatchItem a, SpriteBatchItem b )
		{
            return a.Texture.SortingKey.CompareTo(b.Texture.SortingKey);
		}
Exemple #34
0
 int CompareDepth( SpriteBatchItem a, SpriteBatchItem b )
 {
     return a.Depth.CompareTo(b.Depth);
 }
Exemple #35
0
        private SpriteBatchItem CreateBatchItem(Color Tint, int texId, float Depth)
        {
            // allocate 4 vertices for this quad, and set the batch pointer to the right offset.
            var bi = new SpriteBatchItem() { Tint = Tint, TextureID = texId, Depth = Depth, VertexBase = _vertexArray.Count };
            _vertexArray.AddN(4);

            return bi;
        }
Exemple #36
0
 int CompareReverseDepth( SpriteBatchItem a, SpriteBatchItem b )
 {
     return b.Depth.CompareTo(a.Depth);
 }
Exemple #37
0
        public void DrawString
        (
            SpriteFont spriteFont,
            string text,
            Vector2 position,
            Color color,
            float rotation,
            Vector2 origin,
            Vector2 scale,
            SpriteEffects effects,
            float depth
        )
        {
            if (spriteFont == null)
            {
                throw new ArgumentException("spriteFont");
            }

            Vector2 p = new Vector2(-origin.X, -origin.Y);

            float sin = (float)Math.Sin(rotation);
            float cos = (float)Math.Cos(rotation);

            foreach (char c in text)
            {
                if (c == '\n')
                {
                    p.Y += spriteFont.LineSpacing;
                    p.X  = -origin.X;
                    continue;
                }
                if (spriteFont.characterData.ContainsKey(c) == false)
                {
                    continue;
                }
                GlyphData g = spriteFont.characterData[c];

                SpriteBatchItem item = _batcher.CreateBatchItem();

                item.Depth     = depth;
                item.TextureID = (int)spriteFont._texture.ID;

                Vector2 texCoordTL = spriteFont._texture.Image.GetTextureCoord(g.Glyph.X, g.Glyph.Y);
                Vector2 texCoordBR = spriteFont._texture.Image.GetTextureCoord(g.Glyph.X + g.Glyph.Width, g.Glyph.Y + g.Glyph.Height);

                if (effects == SpriteEffects.FlipVertically)
                {
                    float temp = texCoordBR.Y;
                    texCoordBR.Y = texCoordTL.Y;
                    texCoordTL.Y = temp;
                }
                else if (effects == SpriteEffects.FlipHorizontally)
                {
                    float temp = texCoordBR.X;
                    texCoordBR.X = texCoordTL.X;
                    texCoordTL.X = temp;
                }

                item.Set
                (
                    position.X,
                    position.Y,
                    p.X * scale.X,
                    (p.Y + g.Cropping.Y) * scale.Y,
                    g.Glyph.Width * scale.X,
                    g.Glyph.Height * scale.Y,
                    sin,
                    cos,
                    color,
                    texCoordTL,
                    texCoordBR
                );

                p.X += (g.Kerning.Y + g.Kerning.Z + spriteFont.Spacing);
            }
        }
Exemple #38
0
 private static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b)
 {
   return object.ReferenceEquals((object) a.Texture, (object) b.Texture) ? 0 : 1;
 }
Exemple #39
0
        /// <summary>
        /// Reuse a previously allocated SpriteBatchItem from the item pool. 
        /// if there is none available grow the pool and initialize new items.
        /// </summary>
        /// <returns></returns>
        public SpriteBatchItem CreateBatchItem()
        {
            if (_batchItemCount >= _batchItemList.Length)
            {
                var oldSize = _batchItemList.Length;
                var newSize = oldSize + oldSize/2; // grow by x1.5
                newSize = (newSize + 63) & (~63); // grow in chunks of 64.
                Array.Resize(ref _batchItemList, newSize);
                for(int i=oldSize; i<newSize; i++)
                    _batchItemList[i]=new SpriteBatchItem();

                EnsureArrayCapacity(Math.Min(newSize, MaxBatchSize));
            }
            var item = _batchItemList[_batchItemCount++];
            return item;
        }
Exemple #40
0
        public void Draw(
            Texture2D texture,
            Rectangle destinationRectangle,
            Nullable <Rectangle> sourceRectangle,
            Color color,
            float rotation,
            Vector2 origin,
            SpriteEffects effect,
            float depth
            )
        {
            if (texture == null)
            {
                throw new ArgumentException("texture");
            }

            SpriteBatchItem item = _batcher.CreateBatchItem();

            item.Depth     = depth;
            item.TextureID = (int)texture.ID;

            Rectangle rect;

            if (sourceRectangle.HasValue)
            {
                rect = sourceRectangle.Value;
            }
            else
            {
                rect = new Rectangle(0, 0, texture.Width, texture.Height);
            }

            Vector2 texCoordTL;            // = texture.Image.GetTextureCoord ( rect.X, rect.Y );
            Vector2 texCoordBR;            // = texture.Image.GetTextureCoord ( rect.X+rect.Width, rect.Y+rect.Height );


            if (texture.Image == null)
            {
                float texWidthRatio  = 1.0f / (float)texture.Width;
                float texHeightRatio = 1.0f / (float)texture.Height;
                // We are initially flipped vertically so we need to flip the corners so that
                //  the image is bottom side up to display correctly
                texCoordTL = new Vector2(rect.X * texWidthRatio, (rect.Y + rect.Height) * texHeightRatio);
                texCoordBR = new Vector2((rect.X + rect.Width) * texWidthRatio,
                                         rect.Y * texHeightRatio);
            }
            else
            {
                texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y);
                texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height);
            }
            if (effect == SpriteEffects.FlipVertically)
            {
                float temp = texCoordBR.Y;
                texCoordBR.Y = texCoordTL.Y;
                texCoordTL.Y = temp;
            }
            else if (effect == SpriteEffects.FlipHorizontally)
            {
                float temp = texCoordBR.X;
                texCoordBR.X = texCoordTL.X;
                texCoordTL.X = temp;
            }

            item.Set
            (
                destinationRectangle.X,
                destinationRectangle.Y,
                -origin.X,
                -origin.Y,
                destinationRectangle.Width,
                destinationRectangle.Height,
                (float)Math.Sin(rotation),
                (float)Math.Cos(rotation),
                color,
                texCoordTL,
                texCoordBR);
        }