在运行时从图像内容加载纹理

基本上我写了一个我正在做的游戏的世界编辑。 outlook未来,我正在集思广益的方式来拯救创建的世界,包括瓦片集(这个游戏将依靠瓦片引擎)。

我希望将每个图块组的图像数据保存在包含图块位置的同一文件中,并将图像数据加载到具有XNA的Texture中。

可能吗? 像这样的事情是我要去的。

Texture2D tileset = Content.LoadFromString<Texture2D>("png tileset data"); 

正如在注释中提到的,您可以从stream中加载纹理。 与此唯一的问题是内容处理器预乘alpha是必要的,除非在创建SpriteBatch时使用BlendState.NonPremultiplied作为BlendState参数。

下面是我用来预加alpha通过stream加载的纹理的一段代码。 它将工作推到GPU上,比通过颜色数组迭代并以这种方式倍增要快得多。

  Texture2D file; RenderTarget2D result; using (var titleStream = TitleContainer.OpenStream(loc)) { file = Texture2D.FromStream(graphicsDevice, titleStream); } //Setup a render target to hold our final texture which will have premulitplied alpha values result = new RenderTarget2D(graphicsDevice, file.Width, file.Height); graphicsDevice.SetRenderTarget(result); graphicsDevice.Clear(Color.Black); //Multiply each color by the source alpha, and write in just the color values into the final texture var blendColor = new BlendState { ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue, AlphaDestinationBlend = Blend.Zero, ColorDestinationBlend = Blend.Zero, AlphaSourceBlend = Blend.SourceAlpha, ColorSourceBlend = Blend.SourceAlpha }; var spriteBatch = new SpriteBatch(graphicsDevice); spriteBatch.Begin(SpriteSortMode.Immediate, blendColor); spriteBatch.Draw(file, file.Bounds, Color.White); spriteBatch.End(); //Now copy over the alpha values from the PNG source texture to the final one, without multiplying them var blendAlpha = new BlendState { ColorWriteChannels = ColorWriteChannels.Alpha, AlphaDestinationBlend = Blend.Zero, ColorDestinationBlend = Blend.Zero, AlphaSourceBlend = Blend.One, ColorSourceBlend = Blend.One }; spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha); spriteBatch.Draw(file, file.Bounds, Color.White); spriteBatch.End(); //Release the GPU back to drawing to the screen graphicsDevice.SetRenderTarget(null); return result as Texture2D; 

以ClassicThunder为例。 下面这个类是XNA / MonorGame新手的更完整的例子。 基本上,把它放到你的项目中,你可以从磁盘加载纹理到一个列表或字典。

您可能会想要利用.NET zip库手动压缩/解压缩资源并减less混乱。 如果你在.NET 4.0以上,你可以访问相当健壮的zip类。 对此进行一些encryption,并且你已经获得了一个不错的纹理加载器。

 public class TextureLoader { public static List<Texture2D> LoadTextureList(string directory, GraphicsDevice graphicsDevice) { List<Texture2D> blendedTextures = new List<Texture2D>(); //load any valid files in directory foreach (var fileName in Directory.GetFiles(directory, "*.jpg|*.png|*.gif")) { var blendedTexture = LoadFromFileStream(fileName, graphicsDevice); if (blendedTexture != null) blendedTextures.Add(blendedTexture); } return blendedTextures; } public static Dictionary<string, Texture2D> LoadTextureDictionary(string directory, GraphicsDevice graphicsDevice) { Dictionary<string, Texture2D> blendedTextures = new Dictionary<string, Texture2D>(); //load any valid files in directory foreach (var fileName in Directory.GetFiles(directory, "*.jpg|*.png|*.gif")) { var blendedTexture = LoadFromFileStream(fileName, graphicsDevice); if (blendedTexture != null) blendedTextures.Add(fileName, blendedTexture); } return blendedTextures; } public static Texture2D LoadFromFileStream(string fileName , GraphicsDevice graphicsDevice) { Texture2D file; RenderTarget2D result; using(var fileStream = new FileStream(fileName, FileMode.Open)) { file = Texture2D.FromStream(graphicsDevice, fileStream); } //Setup a render target to hold our final texture which will have premulitplied alpha values result = new RenderTarget2D(graphicsDevice, file.Width, file.Height); graphicsDevice.SetRenderTarget(result); graphicsDevice.Clear(Color.Black); //Multiply each color by the source alpha, and write in just the color values into the final texture var blendColor = new BlendState { ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue, AlphaDestinationBlend = Blend.Zero, ColorDestinationBlend = Blend.Zero, AlphaSourceBlend = Blend.SourceAlpha, ColorSourceBlend = Blend.SourceAlpha }; var spriteBatch = new SpriteBatch(graphicsDevice); spriteBatch.Begin(SpriteSortMode.Immediate, blendColor); spriteBatch.Draw(file, file.Bounds, Color.White); spriteBatch.End(); //Now copy over the alpha values from the PNG source texture to the final one, without multiplying them var blendAlpha = new BlendState { ColorWriteChannels = ColorWriteChannels.Alpha, AlphaDestinationBlend = Blend.Zero, ColorDestinationBlend = Blend.Zero, AlphaSourceBlend = Blend.One, ColorSourceBlend = Blend.One }; spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha); spriteBatch.Draw(file, file.Bounds, Color.White); spriteBatch.End(); //Release the GPU back to drawing to the screen graphicsDevice.SetRenderTarget(null); return result as Texture2D; } }