dds纹理

来源:互联网 发布:mysql front mac 编辑:程序博客网 时间:2024/05/01 00:24

要渲染看起来真实的场景,最好是使用高分辨率而且颜色丰富的纹理,但这样的纹理可能会耗费大量的内存,例如,一张每像素16位颜色的256 x 256纹理将使用128KB的内存。如果在该纹理中使用多级渐进纹理,还需要额外的43KB内存。一个使用50张这种纹理的场景将需要8MB的内存,如果需要更强的真实性,可以使用每像素32位颜色的512 x 512纹理,但那就需要8倍的内存。

为了减少纹理消耗的系统带宽和内存空间,Direct3D支持纹理压缩和实时解压,即DXT纹理压缩。压缩后的纹理被存储在Direct3D纹理指针中,当Direct3D渲染物体时,Direct3D引擎自动对纹理进行解压。应用DXT压缩纹理不仅可以节省内存空间,而且能有效地降低纹理传输带宽,提高图形系统的整体性能。

随着DirectX对纹理压缩格式的推广,目前大部分显卡都支持DXT压缩纹理,而且DXT压缩纹理在图形质量和运行速度之间取得了很好的平衡。

 

DXT纹理压缩格式

DXT是一种DirectDraw表面,它以压缩形式存储图形数据,该表面可以节省大量的系统带宽和内存。即使不直接使用DXT表面渲染,也可以通过DXT格式创建纹理的方法节省磁盘空间。Direct3D提供了D3DFMT_DXT1 ~ D3DFMT_DXT5共5种压缩纹理格式。其中,D3DFMT_DXT1支持15位RGB和1位alpha图形格式,D3DFMT_DXT2、D3DFMT_DXT3支持12位RGB和4位alpha,D3DFMT_DXT4、D3DFMT_DXT5则采取了线性插值方式生成alpha。

DXT1格式的压缩比例是4 : 1(4x4块16位RGB纹理元素可压缩为64位,2个16位RGB565值和16个2位索引),这样的压缩比并不很高,但足以有效地将3D加速卡用于存储纹理的容量提高4倍,如下图所示:

Direct3D支持5中DXT格式压缩:

FOURCCDescriptionAlpha premultiplied?DXT1Opaque/1-bit alphaN/ADXT2Explicit alphaYesDXT3Explicit alphaNoDXT4Interpolated alphaYesDXT5Interpolated alphaNo

 

使用DXT压缩纹理

使用DXT压缩纹理前,必须先调用IDirect3D9::CheckDeviceFormat(),将表面格式设置为D3DFMT_DXT1 ~ D3DFMT_DXT5中的任意值,查询当前设备是否支持DXT压缩纹理:

// check whether device support DXT compressed textureif(FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, 0, D3DRTYPE_TEXTURE,    D3DFMT_DXT1)))return false;

如果当前设备支持DXT压缩纹理,就可以直接创建DXT压缩纹理,并可以通过IDirect3DDevice9::SetTexture()函数设置DXT压缩纹理,将其映射到物体表面。如果当前设备不支持DXT压缩纹理,仍然可以DXT压缩格式存储纹理,但在使用该纹理渲染图形前,必须将DXT压缩格式的纹理转换为当前设备支持的格式。

在使用函数IDirect3DDevice9::CreateTexture()创建纹理时,将参数Format设置为压缩纹理格式D3DFMT_DXT1 ~ D3DFMT_DXT5中的任意值,可以创建指定压缩格式的纹理,也可以通过函数D3DXCreateTextureFromFileEx()从磁盘文件中生成DXT压缩纹理:

V_RETURN(D3DXCreateTextureFromFileExW(pd3dDevice, L"texture.jpg", 0, 0, 5, 0, D3DFMT_DXT1, D3DPOOL_MANAGED,
      D3DX_DEFAULT, D3DX_DEFAULT, 0xFF000000, NULL, NULL, &g_texture));

可以通过DirectX SDK提供的纹理编辑工具"DirectX Texture Editor",创建压缩格式的纹理文件(后缀为DDS的纹理文件),或将其他格式的纹理文件转换为压缩格式的纹理文件。

在创建好压缩纹理之后,就可以和前面一样设置纹理及各项纹理渲染状态,最后进行渲染。如果当前设备支持DXT压缩纹理,那么在使用DXT纹理渲染图形时,Direct3D引擎会自动进行纹理压缩,如果当前设备不支持DXT压缩纹理,这时使用DXT压缩纹理和使用普通的非压缩纹理完全相同。

当使用大量纹理贴图渲染复杂场景时,通过使用DXT压缩纹理可以有效提高程序运行性能。

 

纹理管理

如果显卡中只有64MB的视频内存,就应该考虑将哪些纹理加载和保留在内存中。可以编写一个算法让计算机来自动考虑这些问题,那么这个算法的任务是什么呢?它需要跟踪可用的纹理内存总数,并了解哪些纹理是经常用到的,而哪些纹理是很少用到的。至少,这个纹理管理算法必须能决定哪些现有的纹理资源可以通过一张纹理图来重新加载,以及应该销毁哪些表面,然后由新的纹理资源取而代之。

Direct3D有一个自动的纹理管理系统,当通过CreateTexture()创建一个纹理对象时,将Pool参数指定为D3DPOOL_MANAGED,就是向Direct3D请求该系统的支持。纹理管理器通过一个时间戳来跟踪纹理的使用情况,这个时间戳用于记录每个纹理对象最后被使用的时间。纹理管理器通过"最近最少使用"算法来决定哪些纹理应从视频内存中移除,若有两个纹理对象同时满足移除条件,则根据纹理属性来做进一步的判断。如果它们具有相同的优先级,则移除最近最少使用的纹理,如果它们具有相同的时间戳,则移除低优先级的纹理。

通过为纹理表面调用IDirect3DResource9::SetPriority()函数,可以给托管的纹理赋予一个优先级,该函数声明如下:

Assigns the resource-management priority for this resource.

DWORD SetPriority(  DWORD PriorityNew);

Parameters

PriorityNew
[in] DWORD value that specifies the new resource-management priority for the resource.

Return Values

Returns the previous priority value for the resource.

Remarks

SetPriority is used for priority control of managed resources. This method returns 0 on non-managed resources.

Priorities are used to determine when managed resources are to be removed from memory. A resource assigned a low priority is removed before a resource with a high priority. If two resources have the same priority, the resource that was used more recently is kept in memory; the other resource is removed. Managed resources have a default priority of 0.

 

原图:

 

DXT压缩后:

 

主程序:

 

0 0
原创粉丝点击