After Writing to a RenderTarget, How to Efficiently Clone the Output?

前端 未结 3 1973
陌清茗
陌清茗 2021-01-17 23:46

XNA noob here, learning every day. I just worked out how to composite multiple textures into one using a RenderTarget2D. However, while I can use the RenderTarget2D as a Te

3条回答
  •  野的像风
    2021-01-18 00:06

    Replace

    Texture2D  mergedTexture = new Texture2D(_device, width, height);
    Color[]    content       = new Color[width * height];
    buffer.GetData(content);
    mergedTexture.SetData(content);
    return mergedTexture;
    

    with

    return buffer;
    

    Because RenderTarget2D extends Texture2D you will just get Texture2D class data returned. Also in case you are interested here's a class i made for building my GUI library's widgets out of multiple textures. In case you need to be doing this sort of thing a lot.

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using System.IO;
    
    namespace Voodo.Utils {
    
        /// 
        /// 
        /// 
        public class TextureBaker {
    
            private readonly SpriteBatch _batch;
            private readonly RenderTarget2D _renderTarget;
            private readonly GraphicsDevice _graphicsDevice;
    
            /// 
            /// 
            /// 
            public Rectangle Bounds {
                get { return _renderTarget.Bounds; }
            }
    
            /// 
            /// 
            /// 
            /// 
            /// 
            public TextureBaker(GraphicsDevice graphicsDevice, Vector2 size) {
    
                _graphicsDevice = graphicsDevice;
    
                _batch = new SpriteBatch(_graphicsDevice);
                _renderTarget = new RenderTarget2D(
                    _graphicsDevice, 
                    (int)size.X, 
                    (int)size.Y);
    
                _graphicsDevice.SetRenderTarget(_renderTarget);
    
                _graphicsDevice.Clear(Color.Transparent);
    
                _batch.Begin(
                    SpriteSortMode.Immediate, 
                    BlendState.AlphaBlend, 
                    SamplerState.LinearClamp,
                    DepthStencilState.Default, 
                    RasterizerState.CullNone);
            }
    
            #region Texture2D baking
    
            /// 
            /// 
            /// 
            /// 
            public void BakeTexture(Texture2D texture) {
    
                _batch.Draw(
                    texture,
                    new Rectangle(0, 0, Bounds.Width, Bounds.Height), 
                    Color.White);
            }
    
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeTexture(Texture2D texture, Rectangle destination) {
    
                _batch.Draw(
                    texture,
                    destination,
                    Color.White);
            }        
    
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeTexture(Texture2D texture, Rectangle destination, Rectangle source) {
    
                _batch.Draw(
                    texture,
                    destination,
                    source,
                    Color.White);
            }
    
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeTexture(Texture2D texture, System.Drawing.RotateFlipType sourceModification, Rectangle destination) {
    
                Stream sourceBuffer = new MemoryStream();
                texture.SaveAsPng(sourceBuffer, texture.Width, texture.Height);
    
                System.Drawing.Image sourceImage = System.Drawing.Image.FromStream(sourceBuffer);
    
                sourceBuffer = new MemoryStream();
                sourceImage.RotateFlip(sourceModification);
                sourceImage.Save(sourceBuffer, System.Drawing.Imaging.ImageFormat.Png);                       
    
                _batch.Draw(
                    Texture2D.FromStream(_graphicsDevice, sourceBuffer),
                    destination,
                    Color.White);
            }
    
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeTexture(Texture2D texture, System.Drawing.RotateFlipType sourceModification, Rectangle destination, Rectangle source) {
    
                Stream sourceBuffer = new MemoryStream();
                texture.SaveAsPng(sourceBuffer, texture.Width, texture.Height);
    
                System.Drawing.Image sourceImage = System.Drawing.Image.FromStream(sourceBuffer);
    
                sourceBuffer = new MemoryStream();
                sourceImage.RotateFlip(sourceModification);
                sourceImage.Save(sourceBuffer, System.Drawing.Imaging.ImageFormat.Png);
    
                _batch.Draw(
                    Texture2D.FromStream(_graphicsDevice, sourceBuffer),
                    destination,
                    source,
                    Color.White);
            }
    
            #endregion
    
            #region SpriteFont baking
    
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeText(SpriteFont font, string text, Vector2 location, Color textColor) {
    
                _batch.DrawString(font, text, location, textColor);
            }
    
            /// 
            /// 
            /// 
            /// 
            /// 
            /// 
            public void BakeTextCentered(SpriteFont font, string text, Vector2 location, Color textColor) {
    
                var shifted = new Vector2 {
                    X = location.X - font.MeasureString(text).X / 2,
                    Y = location.Y - font.MeasureString(text).Y / 2
                };
    
                _batch.DrawString(font, text, shifted, textColor);
            }
    
            #endregion
    
            /// 
            /// 
            /// 
            /// 
            public Texture2D GetTexture() {
    
                _batch.End();
                _graphicsDevice.SetRenderTarget(null);
    
                return _renderTarget;
            }
        }
    }
    

提交回复
热议问题