我目前正在为我的游戏项目寻找性能优化。我的初始化过程的瓶颈是加载我的模型的纹理。加载和指定大纹理需要100毫秒。这是一个问题,因为我有很多。我分析了我的代码并发现,大部分时间(大约96%)用于调用 CopyPixels (见下文)。
我附加了用于导入下面所有纹理的函数。此功能类似于魅力,基于官方的 SharpDX-samples-master 示例代码。首先,我从自定义文件格式加载图像字节(对于大纹理,大约花费2毫秒)。然后,我创建格式转换器并使用它将像素复制到数据流。但是,复制像素非常慢。
有没有更快的方法来实现同样的目标?
public static Resources.Texture ImportTexture(Resources.AResourceManager resourceManager, string resourcePackFileName, int bytePosition, out string resourceItemName)
{
// Load image bytes from file.
FileReader fileReader = new FileReader();
DataTypes.Content.ResourceItem resourceItem = fileReader.ImportTextureFromCollection(resourcePackFileName, bytePosition);
resourceItemName = resourceItem.Name;
// Create texture.
Resources.Texture tex = null;
using (SharpDX.WIC.BitmapDecoder bitmapDecoder = new SharpDX.WIC.BitmapDecoder(resourceManager.ImagingFactory, new MemoryStream(resourceItem.Data, false), SharpDX.WIC.DecodeOptions.CacheOnDemand))
{
using (SharpDX.WIC.FormatConverter formatConverter = new SharpDX.WIC.FormatConverter(resourceManager.ImagingFactory))
{
formatConverter.Initialize(bitmapDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, SharpDX.WIC.BitmapDitherType.None, null, 0.0, SharpDX.WIC.BitmapPaletteType.Custom);
SharpDX.DataStream dataStream = new SharpDX.DataStream(formatConverter.Size.Height * formatConverter.Size.Width * 4, true, true);
// This takes most of the time!
formatConverter.CopyPixels(formatConverter.Size.Width * 4, dataStream);
// Creating texture data structure.
tex = new Resources.Texture(formatConverter.Size.Width, formatConverter.Size.Height, formatConverter.Size.Width * 4)
{
DataStream = dataStream
};
}
}
return tex;
}
答案 0 :(得分:1)
看起来您正在使用位图。您是否考虑过使用DDS文件?它支持压缩和未压缩格式 - Asesh
Asesh是对的。起初,我持怀疑态度,但我做了一些研究,发现一篇较旧的文章指出,平均PNG纹理在硬盘上占用的内存比同等DDS纹理少。但是,PNG纹理需要在运行时转换,这比使用DDS纹理要慢。
昨晚我花了很多时间寻找合适的转换工具,在测试了一些东西(比如GIMP的插件)后,我使用AMD的Compressonator将我的所有PNG纹理转换为DDS纹理。新文件在我的硬盘驱动器上的内存比PNG文件(1.7 GB而不是2.1 GB)更少。
我在初始帖子中提到的纹理加载方法仍然有效,并且稍快一点。但是,我决定根据我在网上找到的几个代码示例对DDS导入器进行编码。
结果:导入大纹理只需要1 ms而不是103 ms。我认为你可以改进。 :-D
非常感谢,Asesh!