我所遭遇过的游戏中间件---nvDXTLib
nvDXTLib是Nvidia提供的一套用于DXT纹理压缩SDK.接口十分简洁,就是提供了几个纹理压缩的函数,其中我使用最多的函数是:
DXTLIB_API NV_ERROR_CODE nvDXTcompress(
const unsigned char * srcImage,
size_t width,
size_t height,
size_t byte_pitch,
nvPixelOrder pixelOrder,
nvCompressionOptions * options,
DXTWriteCallback fileWriteRoutine, // call to .dds write routine
const RECT * rect = );
其含义是输入一套未压缩的纹理图像数据,在回调函数DXTWriteCallback中会输出压缩后的图像数据.pixelOrder为像素格式,byte_pitch这个东西我始终不太明白它存在的意义,它是图像中每行数据的内存大小,也就等于图像的宽度width乘以每个像素的大小,即byte_pitch == width * sizeof(pixel).除非有byte_pitch != width * sizeof(pixel)的可能,否则没有必要再传个byte_pitch进去,而实际上我下过断点,从没碰到过不相等的情况.
nvDXTLib最大的特点是线程安全,这也是我使用它的理由.否则Direct3D本来就有DXT纹理生成的方法,没必要再搞另一套压缩库.其算法压缩效率不算太高,之前测试过,但具体的性能数值已经不见了,记得大概512*512的图像压缩时间为3秒左右,1024*1024的图像压缩时间为15秒左右,2048*2048的约为1分钟.这个时间是异步处理下的时间,同步处理下的时间没有测.而且我也不记得这是在DEBUG下做的测试还是在RELEASE下做的测试.好在是异步处理,所以压缩时间长点也能接收.在游戏中的逻辑是,混合生成一张纹理,将其提交压缩任务.在压缩完成之前,使用未压缩的纹理进行渲染,当压缩完成后,使用压缩后的纹理渲染,并释放未压缩的纹理.
前几天碰到一个崩溃的问题,头疼了很久,调用nvDXTcompress时崩溃了,这套代码我已经写了很久了,突然莫名其妙的崩了,而且是小概率的难以重现的崩溃.查这种崩溃最头疼,这也是使用中间件的一个弊端,崩溃后无法跟入它的代码中,不知道崩在何处,有种束手无策的感觉.最后通过打LOG的方式发现,崩溃时正在压缩的纹理是2048*2048大小,应该是nvDXTcompress中申请了一块比较大的内存失败了导致的.
我没有找到nvDXTLib的源码,应该是它没有开源.而且这套库已经成为Nvidia历史,Nvidia现在有另一套纹理处理的SDK是nvidia-texture-tools(NVTT),开源的,比nvDXTLib要强大很多.我想以后再有纹理压缩的需求,我会用NVTT.多提一句:nvDXTLib没有获得压缩后数据大小的方法,所以在为输出数据申请内存时,不好确定,我使用的办法是按输入数据大小的一半申请输出数据内存.NVTT提供了一个接口是Compressor::estimateSize(),但estimate是估算的意思,这也不太好确定,希望其返回值永远比实际值大,否则没办法使用它.
nvDXTLib的下载地址:
https://developer.nvidia.com/sites/default/files/akamai/tools/files/DDS_Utilities_8.31.1127.1645.exe
NVTT的下载地址:
http://code.google.com/p/nvidia-texture-tools/