ID3DXEffect 프레임웍에 추가

셰이더를 사용하기 위해 ID3DXEffect를 프레임웍에 추가해 보자.
x파일과 분리 할려고 했으나 약간의 어려움이 있어 x파일과의 의존성을 완전히 분리하지
못했다.

CDXEffect 클래스는 ID3DXEffect 객체를 가지고 있다.

//dxeffect.h

#ifndef __CDXEFFEXT_H

#define __CDXEFFEXT_H

 

class CDXEffect

{

public:

    CDXEffect();

    virtual ~CDXEffect();

 

public:

    bool Load(IDirect3DDevice9* pDevice, char* szFileName);

    void Release();

    ID3DXEffect* GetEffect();

 

public:

    //렌더링시 불려지는 메쏘드

    bool SetTechnique(const char* szTechnique);

    UINT Begin();

    bool End();

 

    bool BeginPass(UINT uPass);

    bool EndPass();

    bool CommitChanges();

 

protected:

    IDirect3DDevice9*    m_pDevice;

    ID3DXEffect*        m_pEffect;   

};

이펙트는 3단계에 의해서 사용 된다.

1. 생성 및 로딩

2. 렌더링

3. 해제

1. 생성 및 로딩:

CDXEffect* pkDXEffect = new CDXEffect;
pkDXEffect->Load(pkDevice, "test.fx");

 

2. 렌더링

void CXFile::Draw()

{

    HRESULT hr;

    ID3DXEffect* pEffect = m_pDXEffect->GetEffect();//---> (1)

 

    D3DXMATRIX   matWorld, matView, matProj;

    m_pDevice->GetTransform(D3DTS_WORLD,&matWorld);

    m_pDevice->GetTransform(D3DTS_VIEW, &matView);

    m_pDevice->GetTransform(D3DTS_PROJECTION, &matProj);

 

    D3DXMATRIX matWorldView = matWorld * matView;

    D3DXMATRIX matWorldViewProj = matWorld * matView * matProj;

 

    _V(pEffect->SetMatrix("g_matWorldView", &matWorldView));//---> (2)

    _V(pEffect->SetMatrix("g_matWorldViewProj", &matWorldViewProj));

 

    DWORD cPasses;

    for(int i = 0; i < (int)m_materialContainer.size(); ++i)

    { 

        bool bResult;

        if(m_textureContainer[i])

            bResult = m_pDXEffect->SetTechnique("BasicTest"); //---> (3)

        else

            bResult = m_pDXEffect->SetTechnique("NoTextureTest");

 

        cPasses = m_pDXEffect->Begin(); //---> (4)

        for(UINT uPassCount = 0; uPassCount < cPasses; ++uPassCount)

        {

            bResult = m_pDXEffect->BeginPass(uPassCount); //---> (5) 

            //아래 (6)
            
SetAttribute(m_pDXEffect, m_textureContainer[i], &m_materialContainer[i]);

            bResult = m_pDXEffect->CommitChanges(); //--->(7)

            m_pMesh->DrawSubset(i);

            m_pDXEffect->EndPass(); //---> (8)

        }

 

        m_pDXEffect->End(); //---> (9)

    }   

}

 

<ID3DXEffect를 사용하는 간단한 방법>

SetTechnique()
   Begin()
      BeginPass()
      //메트리얼 설정도 여기서 한다.
      SetTexture()
      CommitChanges()
      //여기서 메시를 그린다.
      EndPass()
   End()

1) CDXEffect에서 얻을수 없는 ID3DXEffect의 메소드는 GetEffect()를 통해서
ID3DXEffect를 직접 실행한다.

2) SetMatrix()를 월드뷰값과 월드뷰프로젝션 값을 Effect에 넘긴다.

3) 텍스쳐가 있으면 "BasicTest" 테크닉을 실행한다.
   텍스쳐가 없으면 "NoTextureTest" 테크닉을 실행한다.

4) Begin()을 통해 패스 수를 얻어와 활성화된 테크닉을 시작한다.

5) 활성화된 테크닉의 패스를 시작한다.

6) 메트리얼 값과 텍스쳐 값을 이펙트에 넘겨준다.

7) 메트리얼 값과 텍스쳐 값이 사용 되었기 때문에 CommitChanges()을 실행한다.

8) 패스를 끝낸다.

9) 테크닉을 끝낸다.

 

3. 해제

ID3DXEFFECT * pEffect;

pEffect->Release()

 

ID3DXEffect에 관한 설명은 여기(/hlsl/tutorial04.html)