D3D中的纹理映射(1)

纹理映射是一种允许我们为三角形赋予图象数据的技术;这让我们能够更细腻更真实地表现我们的场景。例如,我们能够创建一个立方体并且通过对它的每个面创建一个纹理来把它变成一个木箱(如图6.1)。

在Direct3D中一个纹理是通过IDirect3DTexture9接口来表现的。一个纹理是一个类似像素矩阵的表面它能够被映射到三角形上。

6.1 纹理坐标

Direct3D使用一个纹理坐标系统,它是由用水平方向的u轴和竖直方向v轴构成。由u,v坐标决定纹理上的元素,它被叫做texel。注意v轴是向下的(如图6.2)。

同样,注意规格化的坐标间隔,[0,1],它被使用是因为它给Direct3D一个固定的范围用于在不同尺寸的纹理上工作。

对每一个3D三角形,我们都希望在给它贴图的纹理上定义一个用相应的三角形。(如图6.3)。

我们再一次修改原来的顶点结构,添加一个用于在纹理上定位的纹理坐标。

struct Vertex

{

       float _x, _y, _z;

       float _nx, _ny, _nz;

       float _u, _v; // texture coordinates

       static const DWORD FVF;

};

const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

我们在顶点格式中添加了一个D3DFVF_TEX1,它是说我们的顶点结构中包含了一个纹理坐标。

现在每个三角形都通过顶点的三个对象来建立,同时也通过纹理坐标定义了一个相应的纹理三角形。

6.2创建并赋予材质

纹理数据通常是从存储在磁盘中的图片文件中读取的,且被读进IDirect3DTexture9对象中。我们能够使用下面的D3DX函数完成这项工作:

Creates a texture from a file.

HRESULT D3DXCreateTextureFromFile(
LPDIRECT3DDEVICE9 pDevice,
LPCTSTR pSrcFile,
LPDIRECT3DTEXTURE9 * ppTexture
);
Parameters
pDevice
[in] Pointer to an IDirect3DDevice9 interface, representing the device to be associated with the texture.
pSrcFile
[in] Pointer to a string that specifies the filename. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
ppTexture
[out] Address of a pointer to an IDirect3DTexture9 interface, representing the created texture object.
Return Values

If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following:

D3DERR_NOTAVAILABLED3DERR_OUTOFVIDEOMEMORYD3DERR_INVALIDCALLD3DXERR_INVALIDDATAE_OUTOFMEMORY

Remarks

The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateTextureFromFileW. Otherwise, the function call resolves to D3DXCreateTextureFromFileA because ANSI strings are being used.

This function supports the following file formats: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga. See D3DXIMAGE_FILEFORMAT.

The function is equivalent to D3DXCreateTextureFromFileEx(pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture).

Mipmapped textures automatically have each level filled with the loaded texture.

When loading images into mipmapped textures, some devices are unable to go to a 1x1 image and this function will fail. If this happens, the images need to be loaded manually.

Note that a resource created with this function will be placed in the memory class denoted by D3DPOOL_MANAGED.

Filtering is automatically applied to a texture created using this method. The filtering is equivalent to D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER in D3DX_FILTER.

For the best performance when using D3DXCreateTextureFromFile:

  1. Doing image scaling and format conversion at load time can be slow. Store images in the format and resolution they will be used. If the target hardware requires power of two dimensions, create and store images using power of two dimensions.
  2. Consider using DirectDraw surface (DDS) files. Because DDS files can be used to represent any Direct3D 9 texture format, they are very easy for D3DX to read. Also, they can store mipmaps, so any mipmap-generation algorithms can be used to author the images.

这个函数能够读取下面图片格式中的任意一种:BMP,DDS,DIB,JPG,PNG,TGA。

例如,用一个名为stonewall.bmp的图片创建一个纹理,我们将按照下面的例子来写:

IDirect3Dtexture9* _stonewall;

D3DXCreateTextureFromFile(_device, "stonewall.bmp", &_stonewall);

设置当前纹理,我们使用下面的方法:

Assigns a texture to a stage for a device.

HRESULT SetTexture(
DWORD Sampler,
IDirect3DBaseTexture9 * pTexture
);
Parameters
Sampler

Zero based sampler number. Textures are bound to samplers; samplers define sampling state such as the filtering mode and the address wrapping mode. Textures are referenced differently by the programmable and the fixed function pipeline:

  • Programmable shaders reference textures using the sampler number. The number of samplers available to a programmable shader is dependent on the shader version. .
  • The fixed function pipeline on the other hand, references textures by texture stage number. The maximum number of samplers is determined from two caps: MaxSimultaneousTextures and MaxTextureBlendStages of the D3DCAPS9 structure.
[in] There are two other special cases for stage/sampler numbers.
  • A special number called D3DDMAPSAMPLER is used for Displacement Mapping (Direct3D 9).
  • A programmable vertex shader uses a special number defined by a D3DVERTEXTEXTURESAMPLER when accessing Vertex Textures in vs_3_0 (Direct3D 9).

pTexture
[in] Pointer to an IDirect3DBaseTexture9 interface, representing the texture being set.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

IDirect3DDevice9::SetTexture is not allowed if the texture is created with a pool type of D3DPOOL_SCRATCH. IDirect3DDevice9::SetTexture is not allowed with a pool type of D3DPOOL_SYSTEMMEM texture unless DevCaps is set with D3DDEVCAPS_TEXTURESYSTEMMEMORY.

例子:

Device->SetTexture(0, _stonewall);

注意:在Direct3D中,你能够设置八个纹理,它们能够组合起来创建更多细节的图象。这又被叫做多重纹理。

为了销毁一个纹理,我们设置pTexture为0。例如,假如不想用一个纹理来渲染物体,那么我们就这样写:

Device->SetTexture(0, 0);

renderObjectWithoutTexture();

假如场景中有使用不同纹理的三角形,我们就必须添加与下面类似的一些代码:

Device->SetTexture(0, _tex0);

drawTrisUsingTex0();

Device->SetTexture(0, _tex1);

drawTrisUsingTex1();

6.3过滤器

       就象以前提及的,纹理被映射到屏幕中的三角形上。通常纹理三角形和屏幕三角形是不一样大的。当纹理三角形比屏幕三角形小时,纹理三角形会被适当放大。当纹理三角形比屏幕三角形大时,纹理三角形会被适当缩小。这两种情况,变形都将会出现。过滤(Filtering)是一种Direct3D用它来帮助这些变形变的平滑的技术。

       Direct3D提供了三种不同的过滤器;每种都提供了一个不同的品质级别。越好的品质越慢,因此你必须在品质与速度之间取得一个平衡。纹理过滤器是用IDirect3DDevice9::SetSamplerState方法来设置的。

Sets the sampler state value.

HRESULT SetSamplerState(
DWORD Sampler,
D3DSAMPLERSTATETYPE Type,
DWORD Value
);
Parameters
Sampler
[in] The sampler stage index.
Type
[in] This parameter can be any member of the D3DSAMPLERSTATETYPE enumerated type.
Value
[in] State value to set. The meaning of this value is determined by the Type parameter.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

  • Nearest point sampling——这是默认的过滤方法且返回最差的效果,但是它的计算是最快的。下面的代码就是设置Nearest point sampling作为缩小放大的过滤器:

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

  • Linear filtering——这种过滤产生还算比较好的效果,在今天的硬件上处理它还是非常快的。它是被推荐使用的。下面的代码就是设置Linear filtering作为缩小放大的过滤器。

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

  • Anisotropic filtering——这种过滤产生最好的效果,但是处理时间也是最长的。下面的代码就是设置Anisotropic filtering作为缩小放大的过滤器。

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

当使用Anisotropic filtering时,我们必须设置D3DSAMP_MAXANISOTROPY等级,它决定处理的质量。该值越高处理的效果越好。检查D3DCAPS9结构确认你的显卡是否支持此功能。下面的代码设置该值为4:

Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

posted @ 2008-03-20 21:22  至尊王者  阅读(2837)  评论(0编辑  收藏  举报