D3D中的Alpha融合技术(2)
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 ;
}
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 ;
}
截图:
下载源程序