Direct 3 D Alphaブレンドによる半透明化

8007 ワード

デモのダウンロード先:http://download.csdn.net/detail/jiangcaiyang123/4091157
今回皆さんに捧げたのは、最近DirectXの基礎を勉強した内容:Alpha混合を行うことです.私は多くのゲームで美しい半透明効果を見ましたが、自分で半透明の効果を作ることができてとても嬉しいです.これは自分の目的の達成だけでなく、自分の独学能力の向上でもあるからです.
Alphaはピクセルカラーの値ですが、カラーを変更することはできません.透明度を変更します.1バイト、つまり0~255の範囲で値を取得します.0は全く見えないことを表し、255は完全に不透明であることを表す.そのため、transparentとopaqueの2つの英語の単語を覚えました.Alphaを使用して半透明の効果を作成するには、D 3 Dデバイスで関数を呼び出して有効にします.この関数がSetRenderStateです.次に、Alphaブレンドを有効にする一般的な方法を示します.
//   Alpha  
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

//           ,  Alpha       (Rasterization)    。           ,            。          。  《Real Time Rendering》     。          ,               ,           :

// RenderByFileDialog.cpp Alpha          
// 2012 2 26 13:35:02     

#include             // ATL       
#include                 // ATL          
#include             //   WTL        
#include "RenderByFileDialog.h"
#include "resource.h"            //      

#define SAFE_RELEASE( p )        if ( p ) { p->Release( ); p = 0; }

CRenderByFileDialog::CRenderByFileDialog( HINSTANCE hInst, HWND hWnd,
                                          LPDIRECT3DDEVICE9 pDevice,
                                          int width, int height )//     
{
    //     
    m_pDevice            = pDevice;
    m_MoveFact            = 0.01f;
    m_CurImageFile        = TEXT( "" );

    //     
    ZeroMemory( &m_Viewport, sizeof( m_Viewport ) );//   
    m_Viewport.X                = 0;
    m_Viewport.Y                = 0;
    m_Viewport.Width            = width;
    m_Viewport.Height            = height;
    m_Viewport.MinZ                = 0.0f;
    m_Viewport.MaxZ                = 1.0f;
    m_pDevice->SetViewport( &m_Viewport );

    //       
    HRESULT hr;
    hr = m_pDevice->CreateVertexBuffer( 8 * sizeof( STVertex ), D3DUSAGE_WRITEONLY,
                                        TEXTURE_FVF, D3DPOOL_MANAGED, &m_pBuffer, NULL );
    ThrowIfFailed( hr, "   ,          。⊙﹏⊙b " );

    hr = m_pBuffer->Lock( 0, 8 * sizeof( STVertex ), (void**)&m_pVtxBackground, D3DLOCK_DISCARD );
    ThrowIfFailed( hr, "   ,          ??o(>﹏Unlock( );
    ThrowIfFailed( hr, "   ,            ??o(>﹏SetStreamSource( 0, m_pBuffer, 0, sizeof( STVertex ) );    //                
    m_pDevice->SetTexture( 0, m_pTexBackground );            //       
    m_pDevice->SetFVF( TEXTURE_FVF );

    //     
    hr = m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
    ThrowIfFailed( hr, "        ?" );

    //   Alpha  
    m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
    m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
    m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    //        
    m_ImmediateInput.Initialize( IMMEDIATE, hInst, hWnd );
    m_BufferInput.Initialize( BUFFERED, hInst, hWnd );
}

unsigned long CRenderByFileDialog::Release( void )            //     
{
    SAFE_RELEASE( m_pTexture );
    SAFE_RELEASE( m_pTexBackground );
    SAFE_RELEASE( m_pBuffer );

    return 0;
}

void CRenderByFileDialog::CenterImage( D3DXIMAGE_INFO& imageInfo, STVertex* vertices )    //     
{
    float                    x, y;
    x = -1.0f / float( m_Viewport.Width ) * float( imageInfo.Width );
    y = -1.0f / float( m_Viewport.Height ) * float( imageInfo.Height );
    vertices[0].Set( x, y, 1.0f, 0.0f, 1.0f );
    vertices[1].Set( x, -y, 1.0f, 0.0f, 0.0f );
    vertices[2].Set( -x, y, 1.0f, 1.0f, 1.0f );
    vertices[3].Set( -x, -y, 1.0f, 1.0f, 0.0f );

}

void CRenderByFileDialog::BrowseImageFile( void )            //              
{
    CFileDialog imageFileDlg( TRUE,
                              TEXT( ".jpg" ),
                              m_CurImageFile.c_str( ),
                              OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                              TEXT( "JPG/JPEG  \0*.jpg\0PNG  \0*.png\0    \0*.*" ),
                              NULL );

    if ( IDOK == imageFileDlg.DoModal( ) )
    {
        m_CurImageFile = imageFileDlg.m_szFileName;
    }
}

void CRenderByFileDialog::Draw( void )                        //   
{
    m_ImmediateInput.UpdateKeyState( );
    m_BufferInput.UpdateKeyState( );

    m_pDevice->SetTexture( 0, m_pTexBackground );            //       
    m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    m_pDevice->SetTexture( 0, m_pTexture );                    //       
    m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 );

    //       
    if ( m_BufferInput.KeyDown( DIK_RETURN ) )
    {
        D3DXIMAGE_INFO            imageInfo;
        HRESULT hr;

        SAFE_RELEASE( m_pTexture );//     
        BrowseImageFile( );//           
        hr = D3DXCreateTextureFromFileEx(            //        
                                                    m_pDevice,                                // DIRECT3DDEVICE9    
                                                    m_CurImageFile.c_str( ),                //         
                                                    D3DX_DEFAULT,                            //  
                                                    D3DX_DEFAULT,                            //  
                                                    D3DX_FROM_FILE,                            // mip  
                                                    0,                                        //   
                                                    D3DFMT_A8R8G8B8,                        //   
                                                    D3DPOOL_MANAGED,                        //      
                                                    D3DX_DEFAULT,                            //    
                                                    D3DX_DEFAULT,                            // mip   
                                                    0,                                        //    (    )
                                                    &imageInfo,                                //      
                                                    NULL,                                    //    
                                                    &m_pTexture );                            // IDirect3DTexture9  

        ThrowIfFailed( hr, "   ,         !          ?" );
        CenterImage( imageInfo, m_pVertices );    //        
    }
    if ( m_ImmediateInput.KeyDown( DIK_UP ) )
    {
        m_pVertices[0].y += m_MoveFact, m_pVertices[1].y += m_MoveFact;
        m_pVertices[2].y += m_MoveFact, m_pVertices[3].y += m_MoveFact;
    }
    if ( m_ImmediateInput.KeyDown( DIK_DOWN ) )
    {
        m_pVertices[0].y -= m_MoveFact, m_pVertices[1].y -= m_MoveFact;
        m_pVertices[2].y -= m_MoveFact, m_pVertices[3].y -= m_MoveFact;
    }
    if ( m_ImmediateInput.KeyDown( DIK_LEFT ) )
    {
        m_pVertices[0].x -= m_MoveFact, m_pVertices[1].x -= m_MoveFact;
        m_pVertices[2].x -= m_MoveFact, m_pVertices[3].x -= m_MoveFact;
    }
    if ( m_ImmediateInput.KeyDown( DIK_RIGHT ) )
    {
        m_pVertices[0].x += m_MoveFact, m_pVertices[1].x += m_MoveFact;
        m_pVertices[2].x += m_MoveFact, m_pVertices[3].x += m_MoveFact;
    }
}
これでは足りません.Alpha読み込みを有効にすることは実装されているだけなので、ファイルは作成時にAlpha値を持つ必要があります.次に、自分がよく使うPhotoshop Cs 4とEasyPaintToolsaiを使ってプレゼンテーションします.
Photoshopの新しいダイアログボックスで、背景を透明に選択します.次の図です.
次に、単純化のために、単一レイヤーのみを使用し、グラデーションの効果を使用して実証する.グラデーションの不透明度を50%に調整します.
次に、画像にグラデーションを任意に使用します.
描画が完了したらpng形式のファイルとして保存し、プログラムにロードできます.結果は下図のようになります.
EasyPaintToolSAIを使用するのも簡単です.コントロールパネルでレイヤーの不透明度を調整し、次の図に名前を付けて保存します.
pngフォーマットとして保存した後、ダイアログボックスを提示して、下にAlpha値があるものを選択します.そうしないと、あなたが描いたAlpha値のある画像は半透明の効果を表示しません.保存されていないからです.
最後に表示される効果は、次の図のようになります.