纹理映射
在DirectX中,纹理用接口IDirect3DTexture9来表示。纹理是类似于表面的一个像素矩阵,与表面不同的是它可被映射到三角开单元中。
Direct3D所使用的纹理 坐标第由沿水平方向的和垂直方向构成的(u,v)用坐标对标识的纹理元素为纹理元。
Direct3D 将纹理坐标做了规范化处理使这限定于[0,1].
修改顶点结构
{
flaot _x, _y, _z;
flaot _nx, _ny, _nz;
flaot _u, _v; //纹理坐标对.
static const DWORD FVF;
};
Const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DVFV_TXX1;
D3DVFV_TXX1 说明顶点含有一对纹理坐标。
创建并启用纹理
纹理数据通常从磁盘中的图像文件读入。再加载到IDirect3DTexure9对象中。
(
LPDIRECT3DDEVICE9 pDevice,//创建纹理的设备
LPCTSTR pSrcFile, //图像的路径和名称
LPDIRECT3DTEXTURE9 *ppTexture //
)
可以加载下格式的图像: BMP、DDS DIB、DIB、PNG、TGA。
使用:
D3DXCreateTectureFromFile(_device, “stonewall.bmp, &_stonewall);
注意第三个参数。
设置当前的方法:
D3DXHANDLE hParameter, //A value in the range 0-7 identyfying the texture可设置8层纹理
LPDIRECT3DBASETEXTURE9 *pTexture //ptr to the texture to set
);
纹理过滤器
理由:通常纹理的图形和屏幕的图形大小不一。要放大或缩小纹理图形。会有畸变。纹理就是为克服这这灯畸变。
Diect3D 提供了3三种类型的纹理过滤器(fileter), 每种过滤器都提供了一种水平。质量越高,运算开销越大,处理速度越慢。
方法:
DWORD Sampler, //0
D3DSAMPLERSTATETYPE Type, //设置过滤器和多级渐进的对象
DWORD Value//
);
1.最近点采样nearest point samping: 速度快 质量
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2.线性纹理过滤器linear filtering : (建议使用)
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
3.各向异性纹理过滤anisotropic filtering
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
如果设置为各向异性纹理要设置 其级别
多级渐进纹理
为了尽量消除畸变的差异, 可能创建一个多级渐进纹理链(chain of mipmap)
方法:由某一纹理创建一系分辨率逐渐减小的纹理图像,并且对每种分辨率下的纹理所采用的过滤方式进行定制,以便 保留那些较重要的细节。
多级渐进纹理过滤器
方法:
Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);
其中: Filer可取以下值。
·D3DTEXF_NONE 禁用多级渐进纹理过滤器
·D3DTTXF_PONT 通过作用该过滤器, Direct3D将选择尺寸与屏幕最接近的那一个纹理。 一旦选择了某一级纹理,Direct3D就会用指定的放大 过滤器和缩小 过滤器对该纹理进行过滤。
·D3DTEF_LINEAR Direct3D 将取与屏幕尺寸最接近的两个纹理,用指定的放大过滤器和缩小过滤器骊每级纹理进行过滤,然后再将这两级纹理进行线性组合,从而形成最终的颜色值。
寻址模式
Direct3D 定义了4种用来处理坐标值超出[0,1]区间的纹理映射模式。
·重复寻址模式(saddress mode)
·边界颜色寻址模式 (border color)
·箝位寻址模式 (claml)
·镜像寻址模式 (mirror)
if( ::GetAsyncKeyState('W') & 0x8000f )
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
// set border color address mode
if( ::GetAsyncKeyState('B') & 0x8000f )
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}
// set clamp address mode
if( ::GetAsyncKeyState('C') & 0x8000f )
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
}
// set mirror address mode
if( ::GetAsyncKeyState('M') & 0x8000f )
{
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
}
总结:
为场景添加纹理映射的步骤:
1 构造组成物体的顶点,并为其指定纹理坐标。
2 作函数D3DXCreateTeutureFromFile为IDirect3DTeuture9接口加载一种纹理。
3 设置缩小过滤器、 放大过滤器和多级渐进纹理过滤器。
4 绘制物体前,用函数IDirect3DDevice9::tTexure来设定与该物体关联的纹理。
《DirectX9.0 3D 游戏开发编程基础》笔记
江西理工大学 FangSH