현재의 프레임웍에서 셰이더를 간단하게 사용하기 위해, ID3DXEffect를 추가 한다.
이펙트를 사용하는 순서는 다음과 같다.
1. 이펙트 생성
2. 이펙트 렌더링
3. 이펙트 해제 |
1. 이펙트 생성
이펙트를 시작하기 위해 ID3DXEffect 객체를 만든다.
HRESULT D3DXCreateEffectFromFile
LPDIRECT3DDEVICE9 pDevice,
LPCTSTR pSrcFile,
CONST D3DXMACRO * pDefines,
LPD3DXINCLUDE pInclude,
DWORD Flags,
LPD3DXEFFECTPOOL pPool,
LPD3DXEFFECT * ppEffect,
LPD3DXBUFFER * ppCompilationErrors
); |
[in] pDevice: 이펙트를 생성하는 IDirect3DDevice9 포인터
[in] pSrcFile: 이펙트 파일명
[in] pDefines: 프리프로세서 매크로 정의로 NULL로 끝나는 D3DXMACRO 배열
보통 NULL을 넣는다.
[in] pInclude: #include 의사 명령어로 보통 NULL을 넣는다.
[in] Flags: 셰이더를 컴파일, 어셈블링 하는 사용되는 D3DXSHADER와 D3DXFX 플래그.
이번에 사용된 셰이더 컴파일 플래그는 아래와 같다.
D3DXSHADER_DEBUG : (컴파일 옵션 /Zi)
컴파일 하는 동안 디버그 파일이름, 라인 번호, 타입, 심볼 정보를 추가한다.
D3DXSHADER_NO_PRESHADER : (컴파일 옵션 /Op)
preshader를 실행하지 않는다. 디폴트로 Presshader를 실행한다.
[in] pPool: 파라 메터 공유를 위한 ID3DXFffectPool 개체의 포인터.
NULL이면 공유하지 않는다.
[out] ppEffect: 컴파일된 ID3DXEFFECT 포인터를 돌려준다.
[out] ppCompilationErrors: 컴파일 에러를 ID3DXBuffer를 돌려준다.
에러값이 필요 없다면 NULL 입력
IDirect3DDevice9* pDevice;
ID3DXEffect* m_pEffect;
ID3DXBuffer* errorBuffer = 0;
DWORD dwShaderFlags = 0;
#if defined( _DEBUG )
dwShaderFlags |= D3DXSHADER_DEBUG;
dwShaderFlags |= D3DXSHADER_NO_PRESHADER;
#endif
HRESULT hr = D3DXCreateEffectFromFile(
pDevice,
szFileName,
0,
0,
dwShaderFlags,
0,
&m_pEffect,
&errorBuffer); |
2. 이펙트 렌더링
이펙트 렌더링시에 사용되는 명령어를 알아본다.
SetTechnique()
Begin()
BeginPass()
//메트리얼 설정도 여기서 한다.
SetTexture()
CommitChanges()
//여기서 메시를 그린다.
EndPass()
End() |
SetTechnique() : 활성화된 테트닉을 셋팅한다.
HRESULT SetTechnique( D3DXHANDLE hTechnique ) |
[in] hTechnique : D3DXHANDLE를 입력한다.
D3DXHANDLE 의미:
a). GetParameter[ByName|Element|BySemantic] 이나 GetAnnotation[ByName]의해
반환된 값들을 사용한다.
b). 문자열을 의미 할 수도 있다.
Begin() : 활성화된 테크닉을 시작한다.
HRESULT Begin( UINT* pPasses, DWORD Flags )
......
HRESULT End() |
[out] pPasses : 활성화된 테크닉의 패스 수를 리턴한다.
[in] Flags : 현재의 장치 상태와 세이더 상태를 시작시(::Begin())에
보관했다가 종료(::End())시에 상태를 복구할 것인지 나타낸다.
D3DXFX_DONOTSAVESTATE :
ID3DXEffect::Begin() 호출시에 장치 state를 보관하지 않고,
ID3DXEffect::End()시에 호출시에 장치 state를 복원하지 하지 않는다.
D3DXFX_DONOTSAVESHADERSTATE :
ID3DXEffect::Begin() 호출시에 셰이더 state를 보관하지 않고
ID3DXEffect::End()시에 호출시에 셰이더 state를 복원하지 하지 않는다.
Begin() : 활성화된 테크닉의 패스를 시작한다.
HRESULT BeginPass( UINT Pass)
......
HRESULT EndPass() |
[in] pPasses : 테크닉안에 있는 패스를 지정한다.
SetTexture() : 이펙트에서 사용될 텍스쳐를 지정한다.
부모 클래스 ID3DXBaseEffect의 메쏘드이다.
HRESULT SetTexture(
D3DXHANDLE hParameter,
LPDIRECT3DBASETEXTURE9 pTexture
) |
[in] hParameter : 이펙트(*.fx)에 있는 텍스쳐 핸들
[in] pTexture : IDirect3DBaseTexture의 핸들
CommitChanges() : BeginPass()와 EndPass() 사이 ID3DXEffect::Setx~~()에
의해 이펙트 상태가 바뀌면 이 메쏘드를 호출 하여 디바이스에게 변화를 알려준다.
아래는 ID3DXEffect를 어떻게 사용하는지 간단하게 설명하고 있는 GpgStudy의
zupet님의 글이다.
zupet님의 글 : ID3DXEffect 사용방법
http://www.gpgstudy.com/forum/viewtopic.php?topic=19093
device->SetStreamSource(...)
device->SetVertexDeclaration(...)
device->SetIndices(...)
UINT pass;
if(SUCCEEDED(effect->Begin(&pass)))
{
for(UINT i=0; i < pass; effect->BeginPass(i))
{
for(int j=0; j< numObject; ++j)
{
effect->SetTexture(objectList[i].m_texture);
effect->CommitChanges();
device->DrawIndexedPrimitive(...);
}
}
effect->End();
} |
이펙트 인스턴스가 같은 경우 SetTexture()를 호출후 CommitChanges()를 실행하여,
텍스쳐가 바뀐걸 적용 시킨다.
3. 이펙트 해제
ID3DXEFFECT * pEffect;
pEffect->Release() |