픽셀 셰이더 9.0C 기초

DirextX 8.0 - tutorial02를 9.0C 버전으로 바꾸어 보자.

고정 파이프라인의 다이렉트 X 9.0C 버전의 컨버팅은 tutorial01에서 자세하게 설명했기 때문에 여기서는 바뀐 부분에 대한 언급만 하고 셰이더의 다른점만 자세하게 애기하겠다.

 1. 헤더파일과 라이브러리 교체

#include <d3d8.h>
#include <d3dx8.h>
#pragma comment (lib, "dxguid.lib")
#pragma comment (lib, "d3d8.lib")
#pragma comment (lib, "d3dx8.lib")

#include <d3d9.h>
#include <d3dx9.h>
#pragma comment (lib, "dxguid.lib")
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")




2. 인터페이스 교체
 

LPDIRECT3D8             g_d3d        = NULL; // our main d3d8 interface
LPDIRECT3DDEVICE8       g_pd3dDevice = NULL; // our d3d8 device
LPDIRECT3DVERTEXBUFFER8 g_pVertexBuffer = NULL; // our VertexBuffer
LPDIRECT3DTEXTURE8      g_pTexture   = NULL;

D3DPRESENT_PARAMETERS   g_d3dpp;
DWORD                   g_hPShader = 0;  //픽셀 셰이더의 핸들

LPDIRECT3D9             g_d3d        = NULL; // our main d3d8 interface
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // our d3d8 device
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL; // our VertexBuffer
LPDIRECT3DTEXTURE9      g_pTexture   = NULL;

D3DPRESENT_PARAMETERS   g_d3dpp;
LPDIRECT3DPIXELSHADER9  g_hPShader = 0;  //픽셀 셰이더의 핸들



3. 다이렉트 X 인터페이스 생성

if( NULL == ( g_d3d = Direct3DCreate8( D3D_SDK_VERSION ) ) )

if( NULL == ( g_d3d = Direct3DCreate9( D3D_SDK_VERSION ) ) )



4. D3DPRESENT 구조체 교체

g_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;

g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;




5. CreateVertexBuffer 변화

g_pd3dDevice->CreateVertexBuffer(4*sizeof(MYVERTEX),
                                   0, D3DFVF_MYVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer)

g_pd3dDevice->CreateVertexBuffer(4*sizeof(MYVERTEX),
                                   0, D3DFVF_MYVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL)




6. SetStreamSource, SetVertexShader 변화
 

        g_pd3dDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(MYVERTEX));
        g_pd3dDevice->SetVertexShader(D3DFVF_MYVERTEX);

        g_pd3dDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(MYVERTEX));
        g_pd3dDevice->SetFVF(D3DFVF_MYVERTEX);

 

힘들고만 ~~~~~~~~~~

이제 셰이더 설명으로 넘어 갈련다. 지겨워서 넘어갈련다..휘리릭 ~~~

1) 셰이더 변수 선언

LPDIRECT3DPIXELSHADER9  g_hPShader = 0;  //픽셀 셰이더의 핸들                
DWORD에서 LPDIRECT3DPIXELSHADER9로 픽셀셰이더의 핸들을 선언한다.

2) 셰이더 생성

HRESULT CreateShader()
{
	const char szPixelShader[] =
	"ps.1.1							        \n"
	//"def c2, 0.3333f, 0.59f, 0.11f, 0.0f  \n"
	"tex t0									\n"
	"dp3 r0, t0, c2							\n";
 
	ID3DXBuffer* pShaderBuffer;
	ID3DXBuffer* pShaderErrors;
	if (FAILED(D3DXAssembleShader(szPixelShader, sizeof(szPixelShader) - 1, 0, NULL,
						D3DXSHADER_DEBUG, &pShaderBuffer, &pShaderErrors)))
		return E_FAIL;

	if (FAILED(g_pd3dDevice->CreatePixelShader((DWORD *)pShaderBuffer->GetBufferPointer(), &g_hPShader)))
		return E_FAIL;
	_RELEASE_(pShaderBuffer);
	return S_OK;
}	
	    
D3DXAssembleShader()에서는 DXSHADER_DEBUG가 추가 되었다.

3) 렌드링

HRESULT Render3D ()
{
	HRESULT hr;

	D3DXMATRIX	matTranslation;

	// Clear the scene
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
		                                D3DCOLOR_XRGB(150,150,255), 1.0f, 0 );
	g_pd3dDevice->BeginScene();

	D3DXMatrixIdentity( &matTranslation );
	g_pd3dDevice->SetTransform(D3DTS_WORLD, &matTranslation);
	
	//Set texture
	g_pd3dDevice->SetTexture( 0, g_pTexture );

	g_pd3dDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(MYVERTEX));
	g_pd3dDevice->SetFVF(D3DFVF_MYVERTEX);

	float fColorConstant[][4] = 
	{
        { 0.3333f, 0.59f, 0.11f, 0.0f}
    };
    g_pd3dDevice->SetPixelShaderConstantF( 2, (float*)fColorConstant ,1); 
	g_pd3dDevice->SetPixelShader(g_hPShader);

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

    //Clear texture
	g_pd3dDevice->SetTexture( 0, NULL );
	
	g_pd3dDevice->EndScene();
	hr = g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

	return hr;
}

8.0과 비교해서 특별하게 바뀐점이 없다. SetPixelShader()는 8.0에서 두 번째 파라메터로 VOID형 캐스트 연산자에서 float 형 연산자를 사용하면 된다.

4) 소멸

    _RELEASE_(g_hPShader);
DeletePixelShader() 같은 셰이더 소멸자는 더 이상 사용하지 않는다.
[펌]
DirectX 실시간 렌더링 실전 테크닉 - 정보 문화사
http://www.t-pot.com