ID3DXEffect 사용법

앞장에서 ID3DXEffect 사용법을 설명 했지만 설명이 부족한 듯 해서 다시 설명한다.
이펙트를 사용하여 셰이더를 편하게 관리하고 사용할 수 있다.

사람도 그렇지만 ID3DXEffect도 생성, 동작, 소멸이라는 단계를 거친다.

생성 단계에서는 ID3DXEffect, IDirect3DVertexDeclaration9 두객체를 생성한다.
동작은 생성된 두 객체를 이용하여 정점 선언 정보, 셰이더 상수 설정, 테크닉 설정, 렌더링 패스를 실행한다.
소멸 단계에서 생선된 두 객체를 소멸 시킨다.

1. ID3DXEffect 생성
2. IDirect3DVertexDeclaration9 생성
3. 렌더링
4.  ID3DXEffect, IDirect3DVertexDeclaration9  해제

 

1. ID3DXEffect 생성
-  D3DXCreateEffectFromFile()로 LPD3DXEFFECT 생성
이펙터를 이용하기 위한 오브젝트 ID3DXEffect를 생성한다.

    LPD3DXEFFECT     m_pShaderEffect
    DWORD dwFlags = 0;

#if defined( _DEBUG )

    dwFlags |= D3DXSHADER_DEBUG;

#endif

    LPD3DXBUFFER ppCompilationErrors = NULL;

 

    HRESULT hr = D3DXCreateEffectFromFile( m_pDevice

        , "hlsl.fx"

        , NULL

        , NULL

        , dwFlags

        , NULL

        , &m_pShaderEffect

        , &ppCompilationErrors);

2. IDirect3DVertexDeclaration9 생성

IDirect3DDevice9::CreateVertexDeclaration()로 LPDIRECT3DVERTEXDECLARATION9 생성
간편하게 IDirect3DVertexDeclaration9를 생성하기 위해 CreateVertexDeclaration()을 사용한다.

    //정점 선언

    D3DVERTEXELEMENT9 vertexDecl[MAX_FVF_DECL_SIZE] = {0};

    D3DXDeclaratorFromFVF( ShaderMeshVertex::FVF, vertexDecl );

 

    LPDIRECT3DVERTEXDECLARATION9    pFVF = NULL;

 

    if( FAILED(m_pDevice->CreateVertexDeclaration(vertexDecl, &pFVF)) )

        return false;

3. 렌더링

렌더링 단계는 정점 선언, 테크닉 설정, 이펙트 상수 설정, 렌더링, FX설정값 NULL로 지정 순서로 진행한다.

1) LPDIRECT3DVERTEXDECLARATION9로 정점 선언

고정 함수를 사용할 때는 SetFVF()를 사용하고 이펙트를 사용할 때는 SetVertexDeclaration()로 정점 선언 정보를 디바이스에게 알려 준다.

#if   0  //고정 D3D 함수 사용시

        // Render the vertex buffer contents

        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );

#else

        hr = g_pd3dDevice->SetVertexDeclaration( Shader::Instance()->GetMeshDecl() );

        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( ShaderMeshVertex ) );

#endif

2) 테크닉 설정

실행할 셰이더의 테크닉을 설정한다.

hr = pShaderEffect->SetTechnique("MeshTech");

테크닉의 이름은 FX 파일에서 아래와 같이 있을것이다.

technique MeshTech

{

    pass P0

    {

        VertexShader = compile vs_3_0 VsMain();

        PixelShader = compile ps_3_0 PsMain();

    }

};

3) 이펙트 상수 설정

World, View, Projection  행렬 곱을 상수로 설정하고 있다.

        pShaderEffect->SetMatrix("matWVP", &matWVP);

hlsl.fx에 있는 상수 선언이다.

// world * view * projection

float4x4    matWVP;

4) 렌더링

FX 시작과 종료는 ID3DXEffect::Begin(), ID3DXEffect::End()로 렌더링 패스, 종료는 ID3DXEffect::BeginPass(), ID3DXEffect::EndPass()로 한다. BeginPass()와 EndPass() 사이에 폴리곤을 드로우 하면 된다.

    1 FX 시작

    2 {

    3        렌더링 패스 시작

    4        {

    5             렌더링  

    6        }

    7        렌더링 패스 종료 

    8 }

    9 FX 종료

텍스쳐가 바뀐다면 CommitChanges()를 호출하여 텍스쳐가 바뀐걸 적용시키도록 한다.

        UINT nPass;

        hr = pShaderEffect->Begin( &nPass, 0 );

        for( UINT i = 0; i < nPass; ++i )

        {

            hr = pShaderEffect->BeginPass( i );

            //SetTexture()를 호출한 경우 CommitChanges()를 호출하여 텍스쳐가 바뀐걸 적용시킨다.

            //pShaderEffect->SetTexture();

            //pShaderEffect->CommitChanges();

            g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );

            pShaderEffect->EndPass();

        }

        pShaderEffect->End();

5) FX 설정값을 NULL로 하여 고정함수 사용할수 있도록 설정

ID3DXEffect를 사용한 뒤에는 NULL로 설정하여 고정 파이프라인을 사용할 수 있도록 한다.

        g_pd3dDevice->SetVertexDeclaration(NULL);

        g_pd3dDevice->SetVertexShader(NULL);

        g_pd3dDevice->SetPixelShader(NULL);

4.  ID3DXEffect, IDirect3DVertexDeclaration9  해제
사용한 오브젝트는 해제한다.

프로젝트: Tut03_Matrices.zip