D3D中的Alpha融合技术(2)

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。

D3D中的Alpha融合技术(2)_第1张图片

图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通道数据。

D3D中的Alpha融合技术(2)_第2张图片

图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 ;
}

 


截图:

D3D中的Alpha融合技术(2)_第3张图片

下载源程序


你可能感兴趣的:(D3D中的Alpha融合技术(2))