我认为* .DDS文件是要快速加载? [英] I thought *.DDS files were meant to be quick to load?

查看:307
本文介绍了我认为* .DDS文件是要快速加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以我试图权衡使用各种不同的纹理压缩技术的专业人士和骗子。我花了99.999%的时间编码2D精灵游戏为Windows机器使用DirectX。



到目前为止,我已经看过纹理打包(SpriteSheets)与alpha修剪,似乎像一个体面的方式,以获得更多的性能。现在我开始看看它们存储的纹理格式;



我听说过* .DDS文件很好,特别是在使用DXT5(/ 3/1,取决于任务)时,压缩随着纹理保持压缩在VRAM?还有人说,由于他们已经是DirectDraw表面,他们加载的速度也快得多。



所以我创建了一个应用程序来测试这个。我调用行以下20次,释放每次调用之间的纹理。

  for(int i = 0; i <20 ; i ++)
{
if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,LTest.dds,& g_pTexture)))
{
return E_FAIL;
}

g_pTexture-> Release();
g_pTexture = NULL;
}

现在,如果我使用DXT5纹理,比加载在一个简单的* .PNG。我听说,如果你不生成Mipmaps它可以走得慢,所以我仔细检查了。然后我改变了我用来生成* .DDS文件的程序,切换到NVIDIA自己的nvcompress.exe,但没有任何效果。



EDIT:我忘了提及文件(* .png和* .dds)都是相同的图片,只是保存为不同的格式。

编辑2:当使用以下参数时,它的加载速度几乎快2.5倍,并消耗一个LOT少于VRAM!

  D3DXCreateTextureFromFileEx(g_pd3dDevice,LTest.dds,D3DX_DEFAULT_NONPOW2,D3DX_DEFAULT_NONPOW2,D3DX_FROM_FILE,0,D3DFMT_FROM_FILE, D3DPOOL_MANAGED,D3DX_FILTER_NONE,D3DX_FILTER_NONE,0,NULL,NULL,& g_pTexture)

现在失去了我所有的透明度的纹理,我看看DXT5纹理,它看起来很好在Paint.NET和DirectX DDS查看器。然而,当加载在所有的透明度变成纯黑色。 ColorKey问题?



编辑3:忽略最后一点,我是愚蠢的,在我的快速示例急速我忘了在D3DXSprite-> Begin()上启用Alpha-Blending。 Doh!

解决方案

您需要区分文件存储在磁盘上的格式和纹理最终使用的格式在视频存储器中。 DXT压缩纹理提供内存使用和视频内存质量之间的良好平衡,但其他压缩技术,如PNG或Jpeg压缩通常导致较小的文件和/或更好的磁盘质量。



DDS文件的优点是它们直接支持DXT格式,并且以与DirectX期望将数据布置在内存中相同的方式布置在磁盘上,因此加载它们以将其转换为硬件可以使用的格式所需的最小CPU时间。它们还支持预生成的mipmap链,其格式像PNG不支持。将图像压缩为DXT格式是一个相当耗时的过程,因此您通常希望尽可能避免在加载时执行此操作。



具有预生成mipmap的DDS文件,与您计划从中创建的视频内存纹理相同的大小和使用相同的格式将使用任何标准格式的最少CPU时间。你需要确保你告诉D3DX不要执行任何缩放,过滤,格式转换或mipmap生成,以保证尽管。 D3DXCreateTextureFromFileEx 允许您指定防止任何内部转换发生的标志( D3DX_DEFAULT_NONPOW2 用于图像宽度和高度,功能的两个纹理, D3DFMT_FROM_FILE 以防止mipmap生成或格式转换, D3DX_FILTER_NONE 以防止任何过滤或缩放)。



CPU时间只是故事的一半。这些天CPU相当快,硬盘驱动器相对较慢,所以有时你的总加载时间可以更短,如果你加载较小的压缩文件格式,如PNG或JPG,然后做大量的CPU工作,以转换它,如果你加载一个更大的文件像一个DDS,只是做一个memcpy到视频内存。一个常见的方法,给出良好的结果是压缩DDS文件,解压缩它们从磁盘快速加载和最小的CPU成本格式转换。



像PNG和JPG的压缩格式比其他图像更有效地压缩一些图像。 DDS是固定压缩比 - 给定的图像分辨率和格式将总是压缩到相同的大小(这就是为什么它更适合在硬件中解压缩)。如果你使用简单的非代表性的图像进行测试(例如统一的颜色或简单的模式),那么你的PNG文件很可能是非常小的,所以将从磁盘加载比一个典型的游戏图像。


Ok, so I'm trying to weigh up the pro's and con's of using various different texture compression techniques. I spend 99.999% of my time coding 2D sprite games for Windows machines using DirectX.

So far I have looked at texture packing (SpriteSheets) with alpha-trimming and that seems like a decent way to get a bit more performance. Now I am starting to look at the texture format that they are stored in; currently everything is stored as *.PNGs.

I have heard that *.DDS files are good, especially when used with DXT5 (/3/1 depending on the task) compression as the texture remains compressed in VRAM? Also people say that as they are already DirectDraw Surfaces they load in much, much quicker too.

So I created an application to test this out; I call the line below 20 times, releasing the texture between each call.

    for (int i = 0; i < 20; i++)
 {
  if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"Test.dds", &g_pTexture ) ) )
  {
   return E_FAIL;
  }

  g_pTexture->Release();
  g_pTexture = NULL;
 }

Now if I try this with a DXT5 texture, it takes 5x longer to complete than with loading in a simple *.PNG. I've heard that if you don't generate Mipmaps it can go slower, so I double checked that. Then I changed the program that I was using to generate the *.DDS file, switching to NVIDIA's own nvcompress.exe, but none of it had any effect.

EDIT: I forgot to mention that the files (both *.png and *.dds) are both the same image, just saved in different formats. (Same size, amount of alpha, everything!)

EDIT 2: When using the following parameters it loads in almost 2.5x faster AND consumes a LOT less VRAM!

 D3DXCreateTextureFromFileEx( g_pd3dDevice, L"Test.dds", D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, D3DX_FROM_FILE, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, NULL, NULL, &g_pTexture )

However, I'm now losing all my transparency in the texture, I've looked at the DXT5 texture and it looks fine in Paint.NET and DirectX DDS Viewer. However when loaded in all the transparency turns to solid black. ColorKey issue?

EDIT 3: Ignore that last bit, I was being idiotic and in my "quick example" haste I'd forgotten to enable Alpha-Blending on the D3DXSprite->Begin(). Doh!

解决方案

You need to distinguish between the format that your files are stored in on disk and the format that the textures ultimately use in video memory. DXT compressed textures offer a good balance between memory usage and quality in video memory but other compression techniques like PNG or Jpeg compression generally result in smaller files and/or better quality on disk.

DDS files have the advantage that they support DXT formats directly and are laid out on disk in the same way that DirectX expects the data to be laid out in memory so there is minimal CPU time required after they are loaded to convert them into a format the hardware can use. They also support pre-generated mipmap chains which formats like PNG do not support. Compressing an image to DXT formats is a fairly time consuming process so you generally want to avoid doing it on load if possible.

A DDS file with pre-generated mipmaps that is the same size as and uses the same format as the video memory texture you plan to create from it will use the least CPU time of any standard format. You need to make sure you tell D3DX not to perform any scaling, filtering, format conversion or mipmap generation to guarantee that though. D3DXCreateTextureFromFileEx allows you to specify flags that prevent any internal conversions happening (D3DX_DEFAULT_NONPOW2 for image width and height if your hardware supports non power of two textures, D3DFMT_FROM_FILE to prevent mipmap generation or format conversion, D3DX_FILTER_NONE to prevent any filtering or scaling).

CPU time is only half the story though. These days CPUs are pretty fast and hard drives are relatively slow so sometimes your total load time can be shorter if you load a smaller compressed file format like PNG or JPG and then do lots of CPU work to convert it than if you load a larger file like a DDS and just do a memcpy into video memory. A common approach that gives good results is to zip DDS files and decompress them for fast loading from disk and minimal CPU cost for format conversion.

Compression formats like PNG and JPG will compress some images more effectively than others. DDS is a fixed compression ratio - a given image resolution and format will always compress to the same size (this is why it is more suitable for decompression in hardware). If you're using simple non-representative images for testing (e.g. a uniform colour or simple pattern) then your PNG file is likely to be very small and so will load from disk faster than a typical game image would.

这篇关于我认为* .DDS文件是要快速加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆