关于纹理使用
1 纹理的创建
2 纹理的寻址方式
3 纹理的过滤方式
1 纹理的创建
<1> D3DXCreateTexture函数
创建一个空的纹理。
HRESULT D3DXCreateTexture(
__in LPDIRECT3DDEVICE9 pDevice,
__in UINT Width,
__in UINT Height,
__in UINT MipLevels,
__in DWORD Usage,
__in D3DFORMAT Format,
__in D3DPOOL Pool,
__out LPDIRECT3DTEXTURE9 *ppTexture
);
<2> D3DXCreateTextureFromFile函数
从文件创建一个纹理,支持各种格式bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, .tga
HRESULT D3DXCreateTextureFromFile(
__in LPDIRECT3DDEVICE9 pDevice,
__in LPCTSTR pSrcFile,
__out LPDIRECT3DTEXTURE9 *ppTexture
);
<3> D3DXCreateTextureFromFileEx函数
这个是比综合了D3DXCreateTexture和D3DXCreateTextureFromFile函数功能的强大的纹理创建函数。
HRESULT D3DXCreateTextureFromFileEx(
__in LPDIRECT3DDEVICE9 pDevice,
__in LPCTSTR pSrcFile,
__in UINT Width,
__in UINT Height,
__in UINT MipLevels,
__in DWORD Usage,
__in D3DFORMAT Format,
__in D3DPOOL Pool,
__in DWORD Filter,
__in DWORD MipFilter,
__in D3DCOLOR ColorKey,
__inout D3DXIMAGE_INFO *pSrcInfo,
__out PALETTEENTRY *pPalette,
__out LPDIRECT3DTEXTURE9 *ppTexture
);
纹理创建完毕后,要启动纹理就要使用函数SetTexture。
HRESULT SetTexture(
[in] DWORD Sampler,
[in] IDirect3DBaseTexture9 *pTexture
);
参数Sampler :指定了第几个纹理层,sampler(采样器)指定了采样的状态值,例如滤波方式,寻址方式。
参数pTexture:指定了欲加载的纹理指针。
2 纹理的寻址方式
纹理的寻址方式,常见的有重复寻址模式,镜像寻址模式,夹取寻址模式,边框寻址模式,一次镜像寻址,设置寻址方式的函数为:
HRESULT SetSamplerState(
[in] DWORD Sampler,
[in] D3DSAMPLERSTATETYPE Type,
[in] DWORD Value
);
Sampler:采样器的编号
D3DSAMPLERSTATETYPE:采样器状态类型
Value:采样器指定状态的值
从枚举类型D3DSAMPLERSTATETYPE中可以找到关于寻址模式设置的三个枚举变量是:
D3DSAMP_ADDRESSU = 1,
D3DSAMP_ADDRESSV = 2,
D3DSAMP_ADDRESSW = 3,
对应的Value的值要从枚举变量中取值D3DTEXTUREADDRESS
typedef enum D3DTEXTUREADDRESS {
D3DTADDRESS_WRAP = 1,
D3DTADDRESS_MIRROR = 2,
D3DTADDRESS_CLAMP = 3,
D3DTADDRESS_BORDER = 4,
D3DTADDRESS_MIRRORONCE = 5,
D3DTADDRESS_FORCE_DWORD = 0x7fffffff
} D3DTEXTUREADDRESS, *LPD3DTEXTUREADDRESS;
<1> D3DTADDRESS_WRAP
重复寻址方式
<2> D3DTADDRESS_MIRROR
镜像寻址方式
<3> D3DTADDRESS_CLAMP
夹取寻址方式
<4> D3DTADDRESS_BORDER
边框颜色寻址方式
<5>
D3DTADDRESS_MIRRORONCE
这是镜像寻址和夹取寻址的组合,取纹理坐标的绝对值,从0处镜像寻址,从最大处夹取寻址。
就是以0为边界,把负的坐标和正的坐标做镜像。所以说是[-1,1]内是做镜像,这个范围之外就是夹取了。另外如果纹理坐标中如果没有负坐标值的话,那么效果就和夹取寻址模式一模一样了。
<6> Texture Wrapping
系统绘制多边形的时候,会在顶点的纹理坐标值之间进行插值依次来决定多边形中的每一个像素的纹理坐标值。在通常情况下,系统会把纹理当做一个2D平面,插值的时候是通过顶点之间的最短路线进行插值,那么在2D平面下,它将会是一个线段。
纹理包装就是指纹理在进行插值的时候,不再是一个2D平面,例如在U方向进行包装,就是把纹理围成一个圆柱面,这个时候两个顶点之间最短的距离是圆柱面上距离最短的距离而不再是平面上距离最短的距离。如下图所示:
A和B之间的最小距离就不是像平面上两点之间的线段。当同时两个方向UV都采取包裹的时候,可以想象为面包圈的形式
3 纹理的过滤方式
纹理的过滤也是通过函数SetSamplerState来设置的。现在继续看看D3DSAMPLERSTATETYPE
的枚举类型的中所有的类型,如下所示:
typedef enum D3DSAMPLERSTATETYPE {
D3DSAMP_ADDRESSU = 1,
D3DSAMP_ADDRESSV = 2,
D3DSAMP_ADDRESSW = 3,
D3DSAMP_BORDERCOLOR = 4, //设置纹理边界颜色
D3DSAMP_MAGFILTER = 5, //放大滤波
D3DSAMP_MINFILTER = 6, //缩小滤波
D3DSAMP_MIPFILTER = 7, //MIP滤波
D3DSAMP_MIPMAPLODBIAS = 8, //多级纹理映射的偏移值
D3DSAMP_MAXMIPLEVEL = 9, //最大纹理过滤级数
D3DSAMP_MAXANISOTROPY = 10,//设置各项异性最大值,越大越好
D3DSAMP_SRGBTEXTURE = 11,//
D3DSAMP_ELEMENTINDEX = 12,//
D3DSAMP_DMAPOFFSET = 13,//
D3DSAMP_FORCE_DWORD = 0x7fffffff
} D3DSAMPLERSTATETYPE, *LPD3DSAMPLERSTATETYPE;
具体滤波的值从枚举类型D3DTEXTUREFILTERTYPE
typedef enum D3DTEXTUREFILTERTYPE {
D3DTEXF_NONE = 0,
D3DTEXF_POINT = 1,
D3DTEXF_LINEAR = 2,
D3DTEXF_ANISOTROPIC = 3,
D3DTEXF_PYRAMIDALQUAD = 6,
D3DTEXF_GAUSSIANQUAD = 7,
D3DTEXF_CONVOLUTIONMONO = 8,
D3DTEXF_FORCE_DWORD = 0x7fffffff
} D3DTEXTUREFILTERTYPE, *LPD3DTEXTUREFILTERTYPE;
<1> D3DTEXF_POINT
最近点采样
Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT)
Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT);
<2> D3DTEXF_LINEAR
线性纹理过滤
Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR)
Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
<3> D3DTEXF_ANISOTROPIC
各项异性纹理过滤,使用之前必须设置D3DSAMP_MAXANISOTROPIC,该值决定各项异性过滤的水平,值越大效果越好
Device->SetSamplerState(0,D3DSAMP_MAXANISOTROPIC,4);
Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC)
Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
D3DTEXF_NONE
当使用D3DSAMP_MIPFILTER的时候,禁止多级渐进纹理过滤
<4>多级纹理渐进
这个不能必须配合其他纹理过滤方式使用,利用SetSamplerState函数,第二个参数是D3DSAMP_MIPFILTER,第三个参数选取
D3DTEXF_NONE
D3DTEXF_POINT
D3DTEXF_LINEAR
其中D3DTEXF_NONE表示禁用多级纹理过滤。