Xna:将一个较大的纹理分割成一个较小的纹理数组

我想将一个较大的纹理分割成一个较小纹理的一维数组。 我应该怎么做?

你在说2D或3D纹理吗?

当您使用SpriteBatch.Draw()绘制2Dgraphics时,可以select设置源矩形和目标矩形。 为了跟踪一个较小纹理的集合,你需要一个数组/列表/任何Rectangle对象来表示你加载的Texture的源矩形。

请参阅MSDN SpriteBatch的文档: http : //msdn.microsoft.com/en-us/library/ff433987.aspx

我在XNA中没有做过任何3D,但我认为有一个类似的机制。

这是一个应该做你需要的方法:

/// <summary> /// Splits a texture into an array of smaller textures of the specified size. /// </summary> /// <param name="original">The texture to be split into smaller textures</param> /// <param name="partWidth">The width of each of the smaller textures that will be contained in the returned array.</param> /// <param name="partHeight">The height of each of the smaller textures that will be contained in the returned array.</param> public Texture2D[] Split(Texture2D original, int partWidth, int partHeight, out int xCount, out int yCount) { yCount = original.Height / partHeight + (partHeight % original.Height == 0 ? 0 : 1);//The number of textures in each horizontal row xCount = original.Height / partHeight + (partHeight % original.Height == 0 ? 0 : 1);//The number of textures in each vertical column Texture2D[] r = new Texture2D[xCount * yCount];//Number of parts = (area of original) / (area of each part). int dataPerPart = partWidth * partHeight;//Number of pixels in each of the split parts //Get the pixel data from the original texture: Color[] originalData = new Color[original.Width * original.Height]; original.GetData<Color>(originalData); int index = 0; for (int y = 0; y < yCount * partHeight; y += partHeight) for (int x = 0; x < xCount * partWidth; x += partWidth) { //The texture at coordinate {x, y} from the top-left of the original texture Texture2D part = new Texture2D(original.GraphicsDevice, partWidth, partHeight); //The data for part Color[] partData = new Color[dataPerPart]; //Fill the part data with colors from the original texture for (int py = 0; py < partHeight; py++) for (int px = 0; px < partWidth; px++) { int partIndex = px + py * partWidth; //If a part goes outside of the source texture, then fill the overlapping part with Color.Transparent if (y + py >= original.Height || x + px >= original.Width) partData[partIndex] = Color.Transparent; else partData[partIndex] = originalData[(x + px) + (y + py) * original.Width]; } //Fill the part with the extracted data part.SetData<Color>(partData); //Stick the part in the return array: r[index++] = part; } //Return the array of parts. return r; } 

这里有一个如何使用它的例子:

  protected override void LoadContent() { //Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); Texture2D tex = Content.Load<Texture2D>("MyTexture"); parts = Split(tex, 10, 10, out xCount, out yCount); } Texture2D[] parts; int xCount, yCount, partWidth = 10; protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(SpriteSortMode.Texture, BlendState.Opaque); for (int y = 0; y < yCount; y++) for (int x = 0; x < xCount; x++) spriteBatch.Draw(parts[x + y * xCount], new Rectangle(10 + x * 40 + x * 10, 10 + y * 40 + y * 10, 40, 40), Color.White); spriteBatch.End(); base.Draw(gameTime); } 

请认识到,这不是完成你想要的最有效的方法,但它是非常可维护和容易理解的(我希望)。

如果你正在寻找更多的效率,并有一些XNA的经验,我会建议使用RenderTargets 1 。 只需将数组中的每个纹理“部分”设置为渲染目标,然后绘制原始大纹理,并由您正在绘制的部分的位置偏移。 请注意,此方法需要您的XNA项目在99%的时间内定位到Hi-Defconfiguration文件,这就是为什么我无法为您提供该方法的工作示例(我当前的计算机不支持Hi-Defconfiguration文件)。 不过,我曾经使用过RenderTargets来做这个事情,所以这是可能的。 现在比以前版本的XNA更容易2 ,这要感谢XNA Game Studio 4.0 3中的RenderTarget更改。

请随时评论,如果你需要任何澄清或更多的帮助:)

链接(对不起,我是一个新用户,所以我不能发布超链接):

  1. http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.rendertarget%28v=xnagamestudio.31%29.aspx
  2. http://blogs.msdn.com/b/shawnhar/archive/2007/02/04/xna-rendertarget-semantics.aspx
  3. http://blogs.msdn.com/b/shawnhar/archive/2010/03/26/rendertarget-changes-in-xna-game-studio-4-0.aspx