将较小的Texture2D放入较大的Texture2D中

本文关键字:Texture2D | 更新日期: 2023-09-27 18:10:43

类似于许多采用平铺地图的程序,就像在游戏Terraria中那样,并将地图变成整个地图的单个图片,我正在尝试做类似的事情。问题是,我的块纹理是在一个单一的大型纹理图集,并由索引引用,我有麻烦从单个块取颜色数据,并将其放置到正确的位置在更大的纹理。

这是我到目前为止的代码。

从索引中获取源代码(此代码有效):

public static Rectangle GetSourceForIndex(int index, Texture2D tex)
    {
        int dim = tex.Width / TEXTURE_MAP_DIM;
        int startx = index % TEXTURE_MAP_DIM;
        int starty = index / TEXTURE_MAP_DIM;
        return new Rectangle(startx * dim, starty * dim, dim, dim);
    }

在索引处获取纹理(问题开始的地方):

public static Texture2D GetTextureAtIndex(int index, Texture2D tex)
    {
        Rectangle source = GetSourceForIndex(index, tex);
        Texture2D texture = new Texture2D(_device, source.Width, source.Height);
        Color[] colors = new Color[tex.Width * tex.Height];
        tex.GetData<Color>(colors);
        Color[] colorData = new Color[source.Width * source.Height];
        for (int x = 0; x < source.Width; x++)
        {
            for (int y = 0; y < source.Height; y++)
            {
                colorData[x + y * source.Width] = colors[x + source.X + (y + source.Y) * tex.Width];
            }
        }
        texture.SetData<Color>(colorData);
        return texture;
    }

将纹理放入大图中(我确信这是完全错误的):

private void doSave()
    {
        int texWidth = this._rWidth * Region.REGION_DIM * 16;
        int texHeight = this._rHeight * Region.REGION_DIM * 16;
        Texture2D picture = new Texture2D(Game.GraphicsDevice, texWidth, texHeight);
        Color[] pictureData = new Color[picture.Width * picture.Height];
        for (int blockX = 0; blockX < texWidth / 16; blockX++)
        {
            for (int blockY = 0; blockY < texHeight / 16; blockY++)
            {
                Block b = this.GetBlockAt(blockX, blockY);
                Texture2D toCopy = TextureManager.GetTextureAtIndex(b.GetIndexBasedOnMetadata(b.GetMetadataForSurroundings(this, blockX, blockY)), b.GetTextureFile());
                Color[] copyData = new Color[toCopy.Width * toCopy.Height];
                Rectangle source = new Rectangle(blockX * 16, blockY * 16, 16, 16);
                toCopy.GetData<Color>(copyData);
                for (int x = 0; x < source.Width; x++)
                {
                    for (int y = 0; y < source.Height; y++)
                    {
                        pictureData[x + source.X + (y + source.Y) * picture.Width] = copyData[x + y * source.Width];
                    }
                }
            }
        }
        picture.SetData<Color>(pictureData);
        string fileName = "picture" + DateTime.Now.ToString(@"MM'-dd'-yyyy-h'-mm-tt");
        FileStream stream = File.Open(this.GetSavePath() + @"Pictures'" + fileName, FileMode.OpenOrCreate);
        picture.SaveAsPng(stream, picture.Width, picture.Height);

我找不到任何关于如何在纹理和一维颜色数组之间正确转换的良好描述。如果我知道如何简单而恰当地将一个正方形的颜色放入一个更大的二维纹理中,那就容易多了。

TL;DR:如何将较小的纹理放入较大的纹理中?

将较小的Texture2D放入较大的Texture2D中

创建一个最大纹理大小的RenderTarget2D,并将其设置为激活状态。先画大的纹理,再画小的纹理。将原始纹理的引用设置为您刚刚绘制的RenderTarget2D。

int texWidth = this._rWidth * Region.REGION_DIM * 16;
int texHeight = this._rHeight * Region.REGION_DIM * 16;
_renderTarget = new RenderTarget2D(GraphicsDevice, texWidth, texHeight);
GraphicsDevice.SetRenderTarget(_renderTarget);
GraphicsDevice.Clear(Color.Transparent);
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
for (int blockX = 0; blockX < texWidth / 16; blockX++)
{
    for (int blockY = 0; blockY < texHeight / 16; blockY++)
    {
         _spriteBatch.Draw(
            TextureManager.GetTextureAtIndex(b.GetIndexBasedOnMetadata(b.GetMetadataForSurroundings(this, blockX, blockY)), b.GetTextureFile()), 
         new Rectangle(blockX * 16, blockY * 16, 16, 16), 
         Color.White);
     }
}
_spriteBatch.End()
GraphicsDevice.SetRenderTarget(null);
var picture = _renderTarget;