本篇是D3D中的Alpha颜色混合(2)的后续篇。
另一种实现实现背景透明显示的简便方法是直接应用渲染管道流水线的Alpha测试功能进行,D3D中的Alpha颜色混合(2)介绍的接口方法实际就是对Alpha测试的一个包装。Alpha测试是对需要写入绘图表面的像素颜色Alpha值进行测试,判断该Alpha值是否满足预先设定的条件,如果满足条件,则将该像素颜色值写入绘图表面,否则不写入。
如上图所示,瞄准器的背景色为标准绿色,为了使瞄准镜可以背景透明地显示在其他图象的上面,需要把瞄准镜的绿色部分镂空。为此,可调用
D3DXCreateTextureFromFileEx函数,相应的创建一个背景为黑色的纹理对象,这个黑色的Alpha值为 0,它的RGBA颜色值则为(0, 0,
0,
0)。然后,开启渲染管道流水线的Alpha测试,并使Alpha测试仅对Alpha值大于或等于某个值的像素颜色值进行写入,以使Alpha值为0的瞄准镜背景黑色不能写入绘图表面,从而使得瞄准镜图象贴在老虎背景画面上时,背景可透明地显示出来。
来看看 D3DXCreateTextureFromFileEx的具体使用说明:
Creates a texture from a file. This is a more advanced function than
D3DXCreateTextureFromFile.
HRESULT D3DXCreateTextureFromFileEx(
LPDIRECT3DDEVICE9 pDevice,
LPCTSTR pSrcFile,
UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
DWORD Filter,
DWORD MipFilter,
D3DCOLOR ColorKey,
D3DXIMAGE_INFO * pSrcInfo,
PALETTEENTRY * pPalette,
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.
- Width
- [in] Width in pixels. If this value is zero or D3DX_DEFAULT, the
dimensions are taken from the file and rounded up to a power of two. If the
device supports non-power of 2 textures and D3DX_DEFAULT_NONPOW2 is
specified, the size will not be rounded.
- Height
- [in] Height, in pixels. If this value is zero or D3DX_DEFAULT, the
dimensions are taken from the file and rounded up to a power of two. If the
device supports non-power of 2 textures and D3DX_DEFAULT_NONPOW2 is
sepcified, the size will not be rounded.
- MipLevels
- [in] Number of mip levels requested. If this value is zero or
D3DX_DEFAULT, a complete mipmap chain is created. If D3DX_FROM_FILE, the
size will be taken exactly as it is in the file, and the call will fail if
this violates device capabilities.
- Usage
- [in] 0, D3DUSAGE_RENDERTARGET, or D3DUSAGE_DYNAMIC. Setting this
flag to D3DUSAGE_RENDERTARGET indicates that the surface is to be
used as a render target. The resource can then be passed to the
pNewRenderTarget parameter of the IDirect3DDevice9::SetRenderTarget method.
If either D3DUSAGE_RENDERTARGET or D3DUSAGE_DYNAMIC is
specified, Pool must be set to D3DPOOL_DEFAULT, and the application should
check that the device supports this operation by calling
IDirect3D9::CheckDeviceFormat. D3DUSAGE_DYNAMIC indicates that the
surface should be handled dynamically. See Using Dynamic Textures.
- Format
- [in] Member of the D3DFORMAT enumerated type, describing the requested
pixel format for the texture. The returned texture might have a different
format from that specified by Format. Applications should check the format
of the returned texture. If D3DFMT_UNKNOWN, the format is taken from the
file. If D3DFMT_FROM_FILE, the format is taken exactly as it is in the file,
and the call will fail if this violates device capabilities.
- Pool
- [in] Member of the D3DPOOL enumerated type, describing the memory class
into which the texture should be placed.
- Filter
- [in] A combination of one or more D3DX_FILTER constants controlling how
the image is filtered. Specifying D3DX_DEFAULT for this parameter is
the equivalent of specifying D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER.
- MipFilter
- [in] A combination of one or more D3DX_FILTER constants
controlling how the image is filtered. Specifying D3DX_DEFAULT for this
parameter is the equivalent of specifying D3DX_FILTER_BOX. In addition, use
bits 27-31 to specify the number of mip levels to be skipped (from the top
of the mipmap chain) when a .dds texture is loaded into memory; this allows
you to skip up to 32 levels.
- ColorKey
- [in] D3DCOLOR value to replace with transparent black, or 0 to disable
the color key. This is always a 32-bit ARGB color, independent of the source
image format. Alpha is significant and should usually be set to FF for
opaque color keys. Thus, for opaque black, the value would be equal to
0xFF000000.
- pSrcInfo
- [in, out] Pointer to a D3DXIMAGE_INFO structure to be filled in with a
description of the data in the source image file, or NULL.
- pPalette
- [out] Pointer to a PALETTEENTRY structure, representing a 256-color
palette to fill in, or NULL.
- 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_INVALIDCALL.
D3DERR_NOTAVAILABLED3DERR_OUTOFVIDEOMEMORYD3DXERR_INVALIDDATAE_OUTOFMEMORY
Remarks
The compiler setting also determines the function version. If Unicode is
defined, the function call resolves to D3DXCreateTextureFromFileExW. Otherwise,
the function call resolves to D3DXCreateTextureFromFileExA because ANSI strings
are being used.
Use D3DXCheckTextureRequirements to determine if your device can support the
texture given the current state.
This function supports the following file formats: .bmp, .dds, .dib, .hdr,
.jpg, .pfm, .png, .ppm, and .tga. See D3DXIMAGE_FILEFORMAT.
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, then the images
need to be loaded manually.
For the best performance when using D3DXCreateTextureFromFileEx:
- 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 2 dimensions, then create and store images using
power of 2 dimensions.
- For mipmap image creation at load time, filter using D3DX_FILTER_BOX.
A box filter is much faster than other filter types such as
D3DX_FILTER_TRIANGLE.
- Consider using DDS files. Since 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.
When skipping mipmap levels while loading a .dds file, use the
D3DX_SKIP_DDS_MIP_LEVELS macro to generate the MipFilter value. This macro takes
the number of levels to skip and the filter type and returns the filter value,
which would then be passed into the MipFilter parameter.
再来看看参数Usage可以使用的枚举类型D3DUSAGE_RENDERTARGET的详细说明:
Usage options that identify
how resources are to be used.
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_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_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. |
Usage and Resource Combinations
Usages are either specified when a resource is created, or specified with
IDirect3D9::CheckDeviceType to test the capability of an existing resource. The
following table identifies which usages can be applied to which resource types.
Usage |
Vertex
buffer create |
Index buffer
create |
Texture
create |
Cube texture
create |
Volume
texture create |
Surface
create |
Check device
format |
D3DUSAGE_AUTOGENMIPMAP |
|
|
x |
x |
|
|
x |
D3DUSAGE_DEPTHSTENCIL |
|
|
x |
x |
|
x |
x |
D3DUSAGE_DMAP |
|
|
x |
|
|
|
x |
D3DUSAGE_DONOTCLIP |
x |
x |
|
|
|
|
|
D3DUSAGE_DYNAMIC |
x |
x |
x |
x |
x |
|
x |
D3DUSAGE_NPATCHES |
x |
x |
|
|
|
|
|
D3DUSAGE_POINTS |
x |
x |
|
|
|
|
|
D3DUSAGE_RTPATCHES |
x |
x |
|
|
|
|
|
D3DUSAGE_RENDERTARGET |
|
|
x |
x |
|
x |
x |
D3DUSAGE_SOFTWAREPROCESSING |
x |
x |
x |
x |
x |
|
x |
D3DUSAGE_WRITEONLY |
x |
x |
|
|
|
|
|
Use IDirect3D9::CheckDeviceFormat to check hardware support for these
usages.
Each of the resource creation methods is listed here.
- IDirect3DDevice9::CreateCubeTexture
- IDirect3DDevice9::CreateDepthStencilSurface
- IDirect3DDevice9::CreateIndexBuffer
- IDirect3DDevice9::CreateOffscreenPlainSurface
- IDirect3DDevice9::CreateRenderTarget
- IDirect3DDevice9::CreateTexture
- IDirect3DDevice9::CreateVertexBuffer
- IDirect3DDevice9::CreateVolumeTexture
The D3DXCreatexxx texturing functions also use some of these constant values
for resource creation.
For more information about pool types and their restrictions with certain
usages, see D3DPOOL.
再来看看参数Pool的D3DPOOL枚举类型的详细信息:
Defines the memory class that holds the buffers
for a resource.
typedef enum D3DPOOL
{
D3DPOOL_DEFAULT = 0,
D3DPOOL_MANAGED = 1,
D3DPOOL_SYSTEMMEM = 2,
D3DPOOL_SCRATCH = 3,
D3DPOOL_FORCE_DWORD = 0x7fffffff,
} D3DPOOL, *LPD3DPOOL;
Constants
- D3DPOOL_DEFAULT
- Resources are placed in the memory pool most appropriate for the set of
usages requested for the given resource. This is usually video memory,
including both local video memory and AGP memory. The D3DPOOL_DEFAULT pool
is separate from D3DPOOL_MANAGED and D3DPOOL_SYSTEMMEM, and it specifies
that the resource is placed in the preferred memory for device access. Note
that D3DPOOL_DEFAULT never indicates that either D3DPOOL_MANAGED or
D3DPOOL_SYSTEMMEM should be chosen as the memory pool type for this
resource. Textures placed in the D3DPOOL_DEFAULT pool cannot be locked
unless they are dynamic textures or they are private, FOURCC, driver
formats. To access unlockable textures, you must use functions such as
IDirect3DDevice9::UpdateSurface, IDirect3DDevice9::UpdateTexture,
IDirect3DDevice9::GetFrontBufferData, and
IDirect3DDevice9::GetRenderTargetData. D3DPOOL_MANAGED is probably a better
choice than D3DPOOL_DEFAULT for most applications. Note that some textures
created in driver-proprietary pixel formats, unknown to the Direct3D
runtime, can be locked. Also note that - unlike textures - swap chain back
buffers, render targets, vertex buffers, and index buffers can be locked.
When a device is lost, resources created using D3DPOOL_DEFAULT must be
released before calling IDirect3DDevice9::Reset. For more information, see
Lost Devices (Direct3D 9).
When creating resources with D3DPOOL_DEFAULT, if video card memory is
already committed, managed resources will be evicted to free enough memory
to satisfy the request.
- D3DPOOL_MANAGED
- Resources are copied automatically to device-accessible memory as
needed. Managed resources are backed by system memory and do not need to be
recreated when a device is lost. See Managing Resources (Direct3D 9) for
more information. Managed resources can be locked. Only the system-memory
copy is directly modified. Direct3D copies your changes to driver-accessible
memory as needed.
- D3DPOOL_SYSTEMMEM
- Resources are placed in memory that is not typically accessible by the
Direct3D device. This memory allocation consumes system RAM but does not
reduce pageable RAM. These resources do not need to be recreated when a
device is lost. Resources in this pool can be locked and can be used as the
source for a IDirect3DDevice9::UpdateSurface or
IDirect3DDevice9::UpdateTexture operation to a memory resource created
with D3DPOOL_DEFAULT.
- D3DPOOL_SCRATCH
- Resources are placed in system RAM and do not need to be recreated when
a device is lost. These resources are not bound by device size or format
restrictions. Because of this, these resources cannot be accessed by the
Direct3D device nor set as textures or render targets. However, these
resources can always be created, locked, and copied.
- D3DPOOL_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in size. Without this
value, some compilers would allow this enumeration to compile to a size
other than 32 bits. This value is not used.
Remarks
All pool types are valid with all resources. This includes: vertex buffers,
index buffers, textures, and surfaces.
The following tables indicate restrictions on pool types for render targets,
depth stencils, and dynamic and mipmap usages. An x indicates a compatible
combination; lack of an x indicates incompatibility.
Pool |
D3DUSAGE_RENDERTARGET |
D3DUSAGE_DEPTHSTENCIL |
D3DPOOL_DEFAULT |
x |
x |
D3DPOOL_MANAGED |
|
|
D3DPOOL_SCRATCH |
|
|
D3DPOOL_SYSTEMMEM |
|
|
Pool |
D3DUSAGE_DYNAMIC |
D3DUSAGE_AUTOGENMIPMAP |
D3DPOOL_DEFAULT |
x |
x |
D3DPOOL_MANAGED |
|
x |
D3DPOOL_SCRATCH |
|
|
D3DPOOL_SYSTEMMEM |
x |
|
For more information about usage types, see D3DUSAGE.
Pools cannot be mixed for different objects contained within one resource (mip
levels in a mipmap) and, when a pool is chosen, it cannot be changed.
Applications should use D3DPOOL_MANAGED for most static resources because
this saves the application from having to deal with lost devices. (Managed
resources are restored by the runtime.) This is especially beneficial for
unified memory architecture (UMA) systems. Other dynamic resources are not a
good match for D3DPOOL_MANAGED. In fact, index buffers and vertex buffers cannot
be created using D3DPOOL_MANAGED together with D3DUSAGE_DYNAMIC.
For dynamic textures, it is sometimes desirable to use a pair of video memory
and system memory textures, allocating the video memory using D3DPOOL_DEFAULT
and the system memory using D3DPOOL_SYSTEMMEM. You can lock and modify the bits
of the system memory texture using a locking method. Then you can update the
video memory texture using IDirect3DDevice9::UpdateTexture.
再来看看参数Filter与MipFilter可以使用的枚举类型D3DX_FILTER的详细说明:
The following flags are used to specify which channels in a texture to
operate on.
#define |
Description |
D3DX_FILTER_NONE |
No
scaling or filtering will take place. Pixels outside the bounds of the
source image are assumed to be transparent black. |
D3DX_FILTER_POINT |
Each
destination pixel is computed by sampling the nearest pixel from the
source image. |
D3DX_FILTER_LINEAR |
Each
destination pixel is computed by sampling the four nearest pixels from
the source image. This filter works best when the scale on both axes is
less than two. |
D3DX_FILTER_TRIANGLE |
Every
pixel in the source image contributes equally to the destination image.
This is the slowest of the filters. |
D3DX_FILTER_BOX |
Each
pixel is computed by averaging a 2x2(x2) box of pixels from the source
image. This filter works only when the dimensions of the destination are
half those of the source, as is the case with mipmaps. |
D3DX_FILTER_MIRROR_U |
Pixels
off the edge of the texture on the u-axis should be mirrored, not
wrapped. |
D3DX_FILTER_MIRROR_V |
Pixels
off the edge of the texture on the v-axis should be mirrored, not
wrapped. |
D3DX_FILTER_MIRROR_W |
Pixels
off the edge of the texture on the w-axis should be mirrored, not
wrapped. |
D3DX_FILTER_MIRROR |
Specifying this flag is the same as specifying the D3DX_FILTER_MIRROR_U,
D3DX_FILTER_MIRROR_V, and D3DX_FILTER_MIRROR_W flags. |
D3DX_FILTER_DITHER |
The
resulting image must be dithered using a 4x4 ordered dither algorithm. |
D3DX_FILTER_SRGB_IN |
Input
data is in sRGB (gamma 2.2) color space. |
D3DX_FILTER_SRGB_OUT |
The
output data is in sRGB (gamma 2.2) color space. |
D3DX_FILTER_SRGB |
Same as
specifying D3DX_FILTER_SRGB_IN | D3DX_FILTER_SRGB_OUT. |
Each valid filter must contain exactly one of the following flags:
D3DX_FILTER_NONE, D3DX_FILTER_POINT, D3DX_FILTER_LINEAR, D3DX_FILTER_TRIANGLE,
or D3DX_FILTER_BOX. In addition, you can use the OR operator to specify zero or
more of the following optional flags with a valid filter: D3DX_FILTER_MIRROR_U,
D3DX_FILTER_MIRROR_V, D3DX_FILTER_MIRROR_W, D3DX_FILTER_MIRROR,
D3DX_FILTER_DITHER, D3DX_FILTER_SRGB_IN, D3DX_FILTER_SRGB_OUT or
D3DX_FILTER_SRGB.
Specifying D3DX_DEFAULT for this parameter is usually the equivalent of
specifying D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER. However, D3DX_DEFAULT can
have different meanings, depending on which method uses the filter. For example:
- When using D3DXCreateTextureFromFileEx, D3DX_DEFAULT maps to
D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER.
- When using D3DXFilterTexture, D3DX_DEFAULT maps to D3DX_FILTER_BOX if
the texture size is a power of two, and D3DX_FILTER_BOX | D3DX_FILTER_DITHER
otherwise.
Reference each method to check for information about how D3DX_DEFAULT filter
is mapped.
参数pSrcInfo的类型D3DXIMAGE_INFO详细说明:
Returns a description of the original
contents of an image file.
typedef struct D3DXIMAGE_INFO {
UINT Width;
UINT Height;
UINT Depth;
UINT MipLevels;
D3DFORMAT Format;
D3DRESOURCETYPE ResourceType;
D3DXIMAGE_FILEFORMAT ImageFileFormat;
} D3DXIMAGE_INFO, *LPD3DXIMAGE_INFO;
Members
- Width
- Width of original image in pixels.
- Height
- Height of original image in pixels.
- Depth
- Depth of original image in pixels.
- MipLevels
- Number of mip levels in original image.
- Format
- A value from the D3DFORMAT enumerated type that most closely describes
the data in the original image.
- ResourceType
- Represents the type of the texture stored in the file. It is either
D3DRTYPE_TEXTURE, D3DRTYPE_VOLUMETEXTURE, or D3DRTYPE_CubeTexture.
- ImageFileFormat
- Represents the format of the image file.
参数pPalette的类型PALETTEENTRY的详细说明:
Specifies the color and usage of an entry in a
logical palette.
typedef struct PALETTEENTRY {
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
} PALETTEENTRY, *LPPALETTEENTRY;
Members
- peRed
- The red intensity value for the palette entry.
- peGreen
- The green intensity value for the palette entry.
- peBlue
- The blue intensity value for the palette entry.
- peFlags
- The alpha intensity value for the palette entry. Note that as of DirectX
8, this member is treated differently than documented in the Platform SDK.
当背景色为透明黑色的纹理创建以后,就可以将该纹理对象所表示的图象透明地显示在其他图象的上面。
此时,需要设置渲染管道流水线的D3DRS_ALPHATESTENABLE状态值为TRUE,以开启Alpha测试。
D3DRS_ALPHATESTENABLE
TRUE to enable per pixel alpha testing. If the test passes, the pixel is
processed by the frame buffer. Otherwise, all frame-buffer processing is
skipped for the pixel.
The test is done by comparing the incoming alpha value with the reference
alpha value, using the comparison function provided by the D3DRS_ALPHAFUNC
render state. The reference alpha value is determined by the value set for
D3DRS_ALPHAREF. For more information, see Alpha Testing State (Direct3D 9).
The default value of this parameter is FALSE.
// enable per pixel alpha testing
_d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
接着设置D3DRS_ALPHAREF的状态为一个0~255范围内的整数值。
// specifies a reference alpha value against which pixels are tested
_d3d_device->SetRenderState(D3DRS_ALPHAREF, 0x01);
再接着设置3DRS_ALPHAFUNC状态为D3DCMPFUNC的枚举值,决定测试将使用比较方式。
Defines the supported
compare functions.
typedef enum D3DCMPFUNC
{
D3DCMP_NEVER = 1,
D3DCMP_LESS = 2,
D3DCMP_EQUAL = 3,
D3DCMP_LESSEQUAL = 4,
D3DCMP_GREATER = 5,
D3DCMP_NOTEQUAL = 6,
D3DCMP_GREATEREQUAL = 7,
D3DCMP_ALWAYS = 8,
D3DCMP_FORCE_DWORD = 0x7fffffff,
} D3DCMPFUNC, *LPD3DCMPFUNC;
Constants
- D3DCMP_NEVER
- Always fail the test.
- D3DCMP_LESS
- Accept the new pixel if its value is less than the value of the current
pixel.
- D3DCMP_EQUAL
- Accept the new pixel if its value equals the value of the current pixel.
- D3DCMP_LESSEQUAL
- Accept the new pixel if its value is less than or equal to the value of
the current pixel.
- D3DCMP_GREATER
- Accept the new pixel if its value is greater than the value of the
current pixel.
- D3DCMP_NOTEQUAL
- Accept the new pixel if its value does not equal the value of the
current pixel.
- D3DCMP_GREATEREQUAL
- Accept the new pixel if its value is greater than or equal to the value
of the current pixel.
- D3DCMP_ALWAYS
- Always pass the test.
- D3DCMP_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in size. Without this
value, some compilers would allow this enumeration to compile to a size
other than 32 bits. This value is not used.
Remarks
The values in this enumerated type define the supported compare functions for
the D3DRS_ZFUNC, D3DRS_ALPHAFUNC, and D3DRS_STENCILFUNC render states.
// Accept the new pixel if its value is greater than the value of the current pixel
_d3d_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
好了,该死的DirectX API 使用说明介绍终于可以结束了,来看一个具体的例子。
需要在工程中设置链接d3dx9.lib d3d9.lib dinput8.lib
dxguid.lib。
由于文件中用到了GE_APP和GE_INPUT这两个类,它的具体使用说明请参阅
主窗口和DirectInput的封装。
若发现代码中存在错误,敬请指出。
源码及素材下载
来看看头文件TransparentBlend.h的定义:
/*************************************************************************************
[Include File]
PURPOSE:
Defines for Transparent blend.
*************************************************************************************/
#ifndef TRANSPARENT_BLEND_H
#define TRANSPARENT_BLEND_H
struct CUSTOM_VERTEX
{
float x, y, z, rhw;
float u, v;
};
#define CUSTOM_VERTEX_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
class TRANSPARENT_BLEND
{
private:
IDirect3D9* _d3d;
IDirect3DDevice9* _d3d_device;
IDirect3DVertexBuffer9* _tiger_vertex_buffer;
IDirect3DVertexBuffer9* _gun_vertex_buffer;
IDirect3DTexture9* _tiger_texture;
IDirect3DTexture9* _gun_texture;
public:
float m_gun_pos_x, m_gun_pos_y;
public:
TRANSPARENT_BLEND();
~TRANSPARENT_BLEND();
bool Create_D3D_Device(HWND hwnd, bool full_screen = true);
bool Init_Tiger_Vertex_Buffer();
bool Init_Gun_Vertex_Buffer();
bool Create_All_Texture();
void Render();
void Release_COM_Object();
};
#endif
再来看看TransparentBlend.cpp的定义:
/*************************************************************************************
[Implement File]
PURPOSE:
Defines for Transparent blend.
*************************************************************************************/
#include "GE_COMMON.h"
#include "TransparentBlend.h"
//------------------------------------------------------------------------------------
// Constructor, initialize data.
//------------------------------------------------------------------------------------
TRANSPARENT_BLEND::TRANSPARENT_BLEND()
{
_d3d = NULL;
_d3d_device = NULL;
_tiger_vertex_buffer = NULL;
_gun_vertex_buffer = NULL;
_tiger_texture = NULL;
_gun_texture = NULL;
m_gun_pos_x = 500.0f;
m_gun_pos_y = 180.0f;
}
//------------------------------------------------------------------------------------
// Destructor, release COM object.
//------------------------------------------------------------------------------------
TRANSPARENT_BLEND::~TRANSPARENT_BLEND()
{
Release_COM_Object();
}
//------------------------------------------------------------------------------------
// Create direct3D interface and direct3D device.
//------------------------------------------------------------------------------------
bool TRANSPARENT_BLEND::Create_D3D_Device(HWND hwnd, bool full_screen)
{
// Create a IDirect3D9 object and returns an interace to it.
_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(_d3d == NULL)
return false;
// retrieve adapter capability
D3DCAPS9 d3d_caps;
_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3d_caps);
bool hardware_process_enable = (d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? true : false);
// Retrieves the current display mode of the adapter.
D3DDISPLAYMODE display_mode;
if(FAILED(_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &display_mode)))
return false;
// set present parameter for direct3D device
D3DPRESENT_PARAMETERS present_param;
ZeroMemory(&present_param, sizeof(present_param));
present_param.BackBufferWidth = WINDOW_WIDTH;
present_param.BackBufferHeight = WINDOW_HEIGHT;
present_param.BackBufferFormat = display_mode.Format;
present_param.BackBufferCount = 1;
present_param.hDeviceWindow = hwnd;
present_param.Windowed = !full_screen;
present_param.SwapEffect = D3DSWAPEFFECT_FLIP;
present_param.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
// Creates a device to represent the display adapter.
DWORD behavior_flags;
behavior_flags = hardware_process_enable ?
D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if(FAILED(_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, behavior_flags,
&present_param, &_d3d_device)))
{
return false;
}
// create successfully
return true;
}
//------------------------------------------------------------------------------------
// Initialize vertex buffer for tiger image.
//------------------------------------------------------------------------------------
bool TRANSPARENT_BLEND::Init_Tiger_Vertex_Buffer()
{
CUSTOM_VERTEX tiger_vertex[] =
{
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
{800.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
{0.0f, 600.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{800.0f, 600.0f, 0.0f, 1.0f, 1.0f, 1.0f}
};
BYTE* vertex_data;
// create vertex buffer
if(FAILED(_d3d_device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX), 0, CUSTOM_VERTEX_FVF,
D3DPOOL_MANAGED, &_tiger_vertex_buffer, NULL)))
{
return false;
}
// get data pointer to vertex buffer
if(FAILED(_tiger_vertex_buffer->Lock(0, 0, (void **) &vertex_data, 0)))
return false;
// copy custom vertex data into vertex buffer
memcpy(vertex_data, tiger_vertex, sizeof(tiger_vertex));
// unlock vertex buffer
_tiger_vertex_buffer->Unlock();
return true;
}
//------------------------------------------------------------------------------------
// Initialize vertex buffer for gun image.
//------------------------------------------------------------------------------------
bool TRANSPARENT_BLEND::Init_Gun_Vertex_Buffer()
{
CUSTOM_VERTEX gun_vertex[] =
{
{m_gun_pos_x, m_gun_pos_y, 0.0f, 1.0f, 0.0f, 0.0f},
{m_gun_pos_x+130.0f, m_gun_pos_y, 0.0f, 1.0f, 1.0f, 0.0f},
{m_gun_pos_x, m_gun_pos_y+130.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{m_gun_pos_x+130.0f, m_gun_pos_y+130.0f, 0.0f, 1.0f, 1.0f, 1.0f}
};
BYTE* vertex_data;
// create vertex buffer
if(FAILED(_d3d_device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX), 0, CUSTOM_VERTEX_FVF,
D3DPOOL_MANAGED, &_gun_vertex_buffer, NULL)))
{
return false;
}
// get data pointer to vertex buffer
if(FAILED(_gun_vertex_buffer->Lock(0, 0, (void **) &vertex_data, 0)))
return false;
// copy custom vertex data into vertex buffer
memcpy(vertex_data, gun_vertex, sizeof(gun_vertex));
// unlock vertex buffer
_gun_vertex_buffer->Unlock();
return true;
}
//------------------------------------------------------------------------------------
// Create all texture interfaces from file.
//------------------------------------------------------------------------------------
bool TRANSPARENT_BLEND::Create_All_Texture()
{
// Creates tiger texture from file
if(FAILED(D3DXCreateTextureFromFile(_d3d_device, "tiger.jpg", &_tiger_texture)))
{
MessageBox(NULL, "Create texture interface for image tiger failed.", "ERROR", MB_OK);
return false;
}
// Creates gun texture from file
if(FAILED(D3DXCreateTextureFromFileEx(
_d3d_device, // Pointer to an IDirect3DDevice9 interface
"gun.bmp", // Pointer to a string that specifies the filename
D3DX_DEFAULT, // Width in pixels
D3DX_DEFAULT, // Height in pixels.
D3DX_DEFAULT, // Number of mip levels requested, D3DX_DEFAULT means a complete mipmap chain is created.
0, // Usage
D3DFMT_A8R8G8B8, // describing the requested pixel format for the texture
D3DPOOL_MANAGED, // describing the memory class into which the texture should be placed
D3DX_FILTER_TRIANGLE, // how the image is filtered (Filter)
D3DX_FILTER_TRIANGLE, // how the image is filtered (MipFilter)
D3DCOLOR_RGBA(0, 255, 0, 255), // D3DCOLOR value to replace with transparent black
NULL, // Pointer to a D3DXIMAGE_INFO structure to be filled in with a description of the data
// in the source image file
NULL, // Pointer to a PALETTEENTRY structure, representing a 256-color palette to fill in
&_gun_texture))) // Address of a pointer to an IDirect3DTexture9 interface
{
MessageBox(NULL, "Create texture interface for image gun failed.", "ERROR", MB_OK);
return false;
}
return true;
}
//------------------------------------------------------------------------------------
// Render image tiger and gun.
//------------------------------------------------------------------------------------
void TRANSPARENT_BLEND::Render()
{
if(_d3d_device == NULL)
return;
// clear back surface with color black
_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
// indicate d3d device begin draw scene
_d3d_device->BeginScene();
// 1) draw for image tiger
// Binds a vertex buffer to a device data stream.
_d3d_device->SetStreamSource(0, _tiger_vertex_buffer, 0, sizeof(CUSTOM_VERTEX));
// Sets the current vertex stream declaration.
_d3d_device->SetFVF(CUSTOM_VERTEX_FVF);
// Assigns a texture to a stage for a device.
_d3d_device->SetTexture(0, _tiger_texture);
// draw tiger image
_d3d_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// 2) draw for image gun
// Binds a vertex buffer to a device data stream
_d3d_device->SetStreamSource(0, _gun_vertex_buffer, 0, sizeof(CUSTOM_VERTEX));
// Assigns a texture to a stage for a device
_d3d_device->SetTexture(0, _gun_texture);
// enable per pixel alpha testing
_d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
// specifies a reference alpha value against which pixels are tested
_d3d_device->SetRenderState(D3DRS_ALPHAREF, 0x01);
// Accept the new pixel if its value is greater than the value of the current pixel
_d3d_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
// draw gun image
_d3d_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// disable per pixel alpha testing now
_d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
// indicate d3d device to end scene
_d3d_device->EndScene();
// Presents the contents of the next buffer in the sequence of back buffers owned by the device.
_d3d_device->Present(NULL, NULL, NULL, NULL);
}
//------------------------------------------------------------------------------------
// Release all COM object.
//------------------------------------------------------------------------------------
void TRANSPARENT_BLEND::Release_COM_Object()
{
Safe_Release(_tiger_texture);
Safe_Release(_gun_texture);
Safe_Release(_tiger_vertex_buffer);
Safe_Release(_gun_vertex_buffer);
Safe_Release(_d3d_device);
Safe_Release(_d3d);
}
注释很详尽,看懂应该没问题了。
来看看测试文件main.cpp的定义:
/*************************************************************************************
[Implement File]
PURPOSE:
Test for transparent blending.
*************************************************************************************/
#define DIRECTINPUT_VERSION 0x0800
#include "GE_COMMON.h"
#include "GE_APP.h"
#include "GE_INPUT.h"
#include "TransparentBlend.h"
#pragma warning(disable : 4305 4996)
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
GE_APP ge_app;
GE_INPUT ge_input;
TRANSPARENT_BLEND tb;
MSG msg = {0};
// create window
if(! ge_app.Create_Window("Transparent blending test", instance, cmd_show))
return false;
HWND hwnd = ge_app.Get_Window_Handle();
SetWindowPos(hwnd, 0, 0,0,0,0, SWP_NOSIZE);
SetCursorPos(0, 0);
// create direct input
ge_input.Create_Input(instance, hwnd);
// Create direct3D interface and direct3D device.
if(! tb.Create_D3D_Device(hwnd, false))
return false;
// initialize vertex buffer for tiger
if(! tb.Init_Tiger_Vertex_Buffer())
return false;
// initialize vertex buffer for gun
if(! tb.Init_Gun_Vertex_Buffer())
return false;
// Create all texture interfaces from file.
tb.Create_All_Texture();
// draw tiger and gun
tb.Render();
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0,0 , PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// get keyboard input
if(ge_input.Read_Keyboard())
{
if(ge_input.Is_Key_Pressed(DIK_ESCAPE))
PostQuitMessage(0);
bool key_right_pressed = ge_input.Is_Key_Pressed(DIK_RIGHT);
bool key_left_pressed = ge_input.Is_Key_Pressed(DIK_LEFT);
bool key_up_pressed = ge_input.Is_Key_Pressed(DIK_UP);
bool key_down_pressed = ge_input.Is_Key_Pressed(DIK_DOWN);
if(key_right_pressed || key_left_pressed || key_up_pressed || key_down_pressed)
{
if(key_right_pressed) // press key "→"
tb.m_gun_pos_x += 5.5f;
if(key_left_pressed) // press key "←"
tb.m_gun_pos_x -= 5.5f;
if(key_up_pressed) // press key "↑"
tb.m_gun_pos_y -= 5.5f;
if(key_down_pressed) // press key "↓"
tb.m_gun_pos_y += 5.5f;
// reset vertex buffer for gun
tb.Init_Gun_Vertex_Buffer();
// render tiger and gun
tb.Render();
}
}
}
}
UnregisterClass(WINDOW_CLASS_NAME, instance);
return true;
}
运行效果: