7.4使用DirectX紋理工具創建Alpha通道
絕大多數普通圖象文件格式沒有存儲alpha信息,在這一部分我們給你演示怎樣使用DirectX紋理工具來創建一個帶alpha通道的DDS文件。DDS文件是一個為DirectX應用程序和紋理設置的圖象格式。DDS文件能夠利用D3DXCreateTextureFromFile函數讀進紋理中,就象bmp和jpg文件一樣。DirectX紋理工具被放在你的DXSDK目錄下的\Bin\DXUtils文件夾下,文件名是DxTex.exe。
打開DirectX紋理工具,并且把crate.jpg文件用工具打開。木箱被自動的按照24位RGB紋理被讀取。它包含8位紅色,8位綠色,以及8位藍色。我們需要將該紋理增加為32位ARGB紋理,增加的是額外的8位alpha通道。從菜單中選擇Format,選擇Change
Surface Format。一個象圖7.5的對話框將被彈出。選擇A8R8G8B8格式點擊OK。

圖7.5
改變紋理的格式
它創建了一個32位顏色深度的圖象,它的每個象素都有8位alpha通道,8位紅色,8位綠色,8位藍色。我們下一步是向alpha通道中寫入數據。我們將圖7.3中的8位灰色圖片信息寫進alpha通道中。選擇菜單中的File,選擇Open
Onto Alpha Channel Of This Texture。一個對話框將彈出讓你選擇包含你想要寫入alpha通道中數據信息的圖片。選擇alphachannel.bmp文件。圖7.6顯示的是程序已經插入了alpha通道數據。

圖7.6 在Alpha通道作用下的紋理圖
現在用你選擇的文件名存儲紋理;我們使用cratewalpha.dds文件名。
示例程序:
/**************************************************************************************
Renders a semi transparent cube using alpha blending.
In this sample, the alpha is taken from the textures alpha channel.
**************************************************************************************/
#include "d3dUtility.h"
#include "vertex.h"
#include "cube.h"
#pragma warning(disable : 4100)
const int WIDTH = 640;
const int HEIGHT = 480;
IDirect3DDevice9* g_d3d_device;
IDirect3DTexture9* g_crate_texture;
cCube* g_cube;
D3DXMATRIX g_cube_world_matrix;
IDirect3DVertexBuffer9* g_back_vb;
IDirect3DTexture9* g_back_texture;
////////////////////////////////////////////////////////////////////////////////////////////////////
bool setup()
{
// create the background quad
g_d3d_device->CreateVertexBuffer(6 * sizeof(cTextureVertex), D3DUSAGE_WRITEONLY, TEXTURE_VERTEX_FVF,
D3DPOOL_MANAGED, &g_back_vb, NULL);
cTextureVertex* vertices;
g_back_vb->Lock(0, 0, (void**)&vertices, 0);
// quad built from two triangles, note texture coordinate.
vertices[0] = cTextureVertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
vertices[1] = cTextureVertex(-10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
vertices[2] = cTextureVertex( 10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
vertices[3] = cTextureVertex(-10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
vertices[4] = cTextureVertex( 10.0f, 10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
vertices[5] = cTextureVertex( 10.0f, -10.0f, 5.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
g_back_vb->Unlock();
// create the cube
g_cube = new cCube(g_d3d_device);
// create the texture and set filters
D3DXCreateTextureFromFile(g_d3d_device, "cratewAlpha.dds", &g_crate_texture);
D3DXCreateTextureFromFile(g_d3d_device, "lobbyxpos.jpg", &g_back_texture);
g_d3d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_d3d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_d3d_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
// set alpha blending states
// use alhpa in material's diffuse component for alpha
g_d3d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_d3d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// set blending factors so that alpha component determines transparency
g_d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// disable lighting
g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
// set camera
D3DXVECTOR3 pos(0.0f, 0.0f, -2.5f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX view_matrix;
D3DXMatrixLookAtLH(&view_matrix, &pos, &target, &up);
g_d3d_device->SetTransform(D3DTS_VIEW, &view_matrix);
// set the projection matrix
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);
g_d3d_device->SetTransform(D3DTS_PROJECTION, &proj);
return true;
}
void cleanup()
{
safe_release<IDirect3DTexture9*>(g_crate_texture);
safe_release<IDirect3DVertexBuffer9*>(g_back_vb);
safe_release<IDirect3DTexture9*>(g_back_texture);
safe_delete<cCube*>(g_cube);
}
bool display(float time_delta)
{
// update: rotate the cube.
D3DXMATRIX x_rot;
D3DXMatrixRotationX(&x_rot, D3DX_PI * 0.2f);
static float y = 0.0f;
D3DXMATRIX y_rot;
D3DXMatrixRotationY(&y_rot, y);
y += time_delta;
if(y >= 6.28f)
y = 0.0f;
g_cube_world_matrix = x_rot * y_rot;
// render now
g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
g_d3d_device->BeginScene();
// draw the background
D3DXMATRIX world_matrix;
D3DXMatrixIdentity(&world_matrix);
g_d3d_device->SetTransform(D3DTS_WORLD, &world_matrix);
g_d3d_device->SetFVF(TEXTURE_VERTEX_FVF);
g_d3d_device->SetStreamSource(0, g_back_vb, 0, sizeof(cTextureVertex));
g_d3d_device->SetTexture(0, g_back_texture);
g_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
// draw the cube
g_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_cube->draw(&g_cube_world_matrix, NULL, g_crate_texture);
g_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_d3d_device->EndScene();
g_d3d_device->Present(NULL, NULL, NULL, NULL);
return true;
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(word_param == VK_ESCAPE)
DestroyWindow(hwnd);
break;
}
return DefWindowProc(hwnd, msg, word_param, long_param);
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
{
if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
{
MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
return 0;
}
if(! setup())
{
MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
return 0;
}
enter_msg_loop(display);
cleanup();
g_d3d_device->Release();
return 0;
}
截圖:

下載源程序