纹理映射基础(1)
为了使渲染的图形看起来更真实,Direct3D提供了在物体表面绘制纹理的功能。一般说来,纹理是表示物体表面细节的一幅或几幅二维图形,也称纹理贴图(texture)。当把纹理按照特定的方式映射到物体表面的时候,能使物体看上去更加真实。当前流行的图形系统中,纹理绘制已经成为一种必不可少的渲染方法。在理解纹理映射时,可以将纹理看作应用程序在物体表面的像素颜色。在真实世界中,纹理表示一个对象的颜色、图案以及触觉特征。但在Direct3D中,纹理只表示对象表面的彩色图案,它不能改变对象的几何形式。更进一步说,它只是一种高强度计算行为。
纹理位图
Direct3D纹理位图是用来表示物体表面图案的二维数组,数组的每一个元素都存储有一个颜色值,称为纹理元素(texel)。经常见到的后缀名为bmp、jpg、tga的图形文件都可以作为纹理位图。
纹理对象
在Direct3D中,纹理是以COM对象的形式存在的,要对物体表面进行纹理映射,首先需要创建纹理对象,创建时需要指定纹理的宽度、高度、格式等属性,然后还需要将图形文件加载到纹理对象中,整个过程比较复杂,为此,Direct3D提供了一个辅助函数D3DXCreateTextureFromFile(),可以直接方便地从磁盘上的图形文件中创建纹理对象,并使用默认设置。如果从文件创建纹理时不想使用各种默认设置,还可以使用另外一个辅助函数D3DXCreateTextureFromFileEx(),该函数也可以直接从磁盘上的图形文件中创建纹理对象,而且还可以指定创建的纹理对象的宽度、高度、格式等。
纹理坐标与纹理元素
纹理相当于一幅位图,在使用时贴到物体表面上。纹理位图是一个二维数组,数组的每一个元素称为纹理元素,它存储有一个颜色值。
纹理元素在表示纹理的数组中的二维下标(即它在位图中的二维坐标)称为纹理坐标。一般以字母(u, v)表示,可以想象成纹理元素所对应的行数和列数,也称实际纹理坐标。假设位图的宽、高分别为w、h,显然
0 ≤ u ≤ w, 0 ≤ v ≤ h
纹理坐标是指纹理空间坐标,即纹理坐标是相对于纹理空间原点而言的。
由于在一个图形显示系统中往往存在多幅不同的纹理,它们的宽、高也不尽相同,用实际纹理坐标表示纹理元素的位置在计算上很难统一,例如在同一个物体表面应用两幅大小不同的纹理。所以经常使用相对纹理坐标(u', v')代替实际纹理坐标(在下文中如无特别说明,纹理坐标就是指相对纹理坐标),u'、v'分别表示u、v所占宽、高的百分比:
u' = u/w, v' = v/h
一般情况下,所有的纹理元素相对坐标的地址都在[0.0, 1.0]范围内,当然从技术上讲,可以使用[0.0, 1.0]范围之外的纹理坐标实现特殊效果。
Direct3D将纹理空间中的纹理元素映射到屏幕空间像素的映射过程常常是一个反映射。也就是说,对于屏幕空间的每个像素,计算其中纹理空间中相应的纹理元素的位置,然后采样该点或该点附近的纹理颜色。这个映射过程称为纹理过滤。
为了将纹理映射到物体表面,需要为物体顶点指定纹理坐标。
创建纹理对象
图形显示的纹理大都存储在磁盘图形文件中(诸如.bmp、.tga、.jpg文件),要想使用它们,必须创建Direct3D纹理对象,并载入图形文件内容。
函数IDirect3DDevice9::CreateTexture()用来创建一个Direct3D纹理对象,该函数声明如下:
Creates a texture resource.
HRESULT CreateTexture(
UINT Width,
UINT Height,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DTexture9** ppTexture,
HANDLE* pSharedHandle
);
Parameters
- Width
- [in] Width of the top-level of the texture, in pixels. The pixel dimensions of subsequent levels will be the truncated value of half of the previous level's pixel dimension (independently). Each dimension clamps at a size of 1 pixel. Thus, if the division by 2 results in 0, 1 will be taken instead.
- Height
- [in] Height of the top-level of the texture, in pixels. The pixel dimensions of subsequent levels will be the truncated value of half of the previous level's pixel dimension (independently). Each dimension clamps at a size of 1 pixel. Thus, if the division by 2 results in 0, 1 will be taken instead.
- Levels
- [in] Number of levels in the texture. If this is zero, Direct3D will generate all texture sublevels down to 1 by 1 pixels for hardware that supports mipmapped textures. Call IDirect3DBaseTexture9::GetLevelCount to see the number of levels generated.
- Usage
- [in] Usage can be 0, which indicates no usage value. However, if usage is desired, use a combination of one or more D3DUSAGE constants. It is good practice to match the usage parameter with the behavior flags in IDirect3D9::CreateDevice.
- Format
- [in] Member of the D3DFORMAT enumerated type, describing the format of all levels in the texture.
- Pool
- [in] Member of the D3DPOOL enumerated type, describing the memory class into which the texture should be placed.
- ppTexture
- [out, retval] Pointer to an IDirect3DTexture9 interface, representing the created texture resource.
- pSharedHandle
- [in] Reserved. Set this parameter to NULL.
Return Values
If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY.
Remarks
An application can discover support for Automatic Generation of Mipmaps (Direct3D 9) in a particular format by calling IDirect3D9::CheckDeviceFormat with D3DUSAGE_AUTOGENMIPMAP. If IDirect3D9::CheckDeviceFormat returns D3DOK_NOAUTOGEN, IDirect3DDevice9::CreateTexture will succeed but it will return a one-level texture.
Usages
The following table summarizes the available usage options.
#define | Description | |
---|---|---|
D3DUSAGE_AUTOGENMIPMAP | The resource will automatically generate mipmaps. See Automatic Generation of Mipmaps (Direct3D 9). Automatic generation of mipmaps is not supported for volume textures and depth stencil surfaces/textures. This usage is not valid for a resource in system memory (D3DPOOL_SYSTEMMEM). | |
D3DUSAGE_DEPTHSTENCIL | The resource will be a depth stencil buffer. D3DUSAGE_DEPTHSTENCIL can only be used with D3DPOOL_DEFAULT. | |
D3DUSAGE_DMAP | The resource will be a displacement map. | |
D3DUSAGE_DONOTCLIP | Set to indicate that the vertex buffer content will never require clipping. When rendering with buffers that have this flag set, the D3DRS_CLIPPING render state must be set to false. | |
D3DUSAGE_DYNAMIC | Set to indicate that the vertex buffer requires dynamic memory use. This is useful for drivers because it enables them to decide where to place the buffer. In general, static vertex buffers are placed in video memory and dynamic vertex buffers are placed in AGP memory. Note that there is no separate static use. If you do not specify D3DUSAGE_DYNAMIC, the vertex buffer is made static. D3DUSAGE_DYNAMIC is strictly enforced through the D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE locking flags. As a result, D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE are valid only on vertex buffers created with D3DUSAGE_DYNAMIC. They are not valid flags on static vertex buffers. For more information, see Managing Resources (Direct3D 9). For more information about using dynamic vertex buffers, see Performance Optimizations (Direct3D 9). D3DUSAGE_DYNAMIC and D3DPOOL_MANAGED are incompatible and should not be used together. See D3DPOOL. Textures can specify D3DUSAGE_DYNAMIC. However, managed textures cannot use D3DUSAGE_DYNAMIC. For more information about dynamic textures, see Using Dynamic Textures. |
|
D3DUSAGE_NONSECURE | Allow a shared surface created by a secure application to be opened by a non-secure application that has the shared handle.
|
|
D3DUSAGE_NPATCHES | Set to indicate that the vertex buffer is to be used for drawing N-patches. | |
D3DUSAGE_POINTS | Set to indicate that the vertex or index buffer will be used for drawing point sprites. The buffer will be loaded in system memory if software vertex processing is needed to emulate point sprites. | |
D3DUSAGE_RENDERTARGET | The resource will be a render target. D3DUSAGE_RENDERTARGET can only be used with D3DPOOL_DEFAULT. | |
D3DUSAGE_RTPATCHES | Set to indicate that the vertex buffer is to be used for drawing high-order primitives. | |
D3DUSAGE_SOFTWAREPROCESSING | If this flag is used, vertex processing is done in software. If this flag is not used, vertex processing is done in hardware. The D3DUSAGE_SOFTWAREPROCESSING flag can be set when mixed-mode or software vertex processing (D3DCREATE_MIXED_VERTEXPROCESSING / D3DCREATE_SOFTWARE_VERTEXPROCESSING) is enabled for that device. D3DUSAGE_SOFTWAREPROCESSING must be set for buffers to be used with software vertex processing in mixed mode, but it should not be set for the best possible performance when using hardware index processing in mixed mode (D3DCREATE_HARDWARE_VERTEXPROCESSING). However, setting D3DUSAGE_SOFTWAREPROCESSING is the only option when a single buffer is used with both hardware and software vertex processing. D3DUSAGE_SOFTWAREPROCESSING is allowed for mixed and software devices. D3DUSAGE_SOFTWAREPROCESSING is used with IDirect3D9::CheckDeviceFormat to find out if a particular texture format can be used as a vertex texture during software vertex processing. If it can, the texture must be created in D3DPOOL_SCRATCH. |
|
D3DUSAGE_TEXTAPI | This usage flag must be specified for vertex buffers and source surfaces, used in calls to IDirect3DDevice9Ex::ComposeRect. Textures created with this usage flag cannot be used for texture filtering. Vertex buffers, created with this usage flag, cannot be used as input stream sources.
|
|
D3DUSAGE_WRITEONLY | Informs the system that the application writes only to the vertex buffer. Using this flag enables the driver to choose the best memory location for efficient write operations and rendering. Attempts to read from a vertex buffer that is created with this capability will fail. Buffers created with D3DPOOL_DEFAULT that do not specify D3DUSAGE_WRITEONLY might suffer a severe performance penalty. |