DirectX Graphics 프로그래밍 가이드 프로그래밍 가능한 파이프라인 프로그래밍 가능한인 스트림 모델   [목차열람] [주소복사] [슬롯비우기]
프로그래밍 가능한 스트림 모델
 
Microsoft DirectX 9.0

프로그래밍 가능한 스트림 모델


여기에서는, 프로그래밍 가능한 스트림 모델로 사용할 수 있는 셰이더에 대해 설명한다.

스트림의 사용법

Microsoft® DirectX® 8.0 에서는, 셰이더로 사용하기 위해서(때문에) 데이터를 입력 레지스터에 바인드 하는 스트림의 개념을 도입했다. 스트림은 데이터 요소의 한결같은 배열이며, 각 요소는, 위치·법선·색등의 단일 엔티티를 나타내는 1 개 혹은 복수의 요소로 구성되어 있다. 스트림에 의해, 그래픽 클립으로 복수의 정점 버퍼로부터 다이렉트 메모리 액세스 (DMA)를 병렬 실행할 수 있게 되어, 애플리케이션 데이터로부터의 자연스러운 맵핑도 실현되고 있다. 또, 간이적인 멀티 텍스처와 멀티 패스를 가능하게 한다. 이것은, 다음과 같이 생각할 수가 있다.

IDirect3DDevice9::SetStreamSource 메서드는, 정점 버퍼를 장치 데이터 스트림에 바인드 해, 기본도형 처리 함수에 데이터를 공급하는 데이터 스트림 포트의 1 개와 정점 데이터와 관련짓는다. 스트림 데이터에의 실제의 참조는,IDirect3DDevice9::DrawPrimitive 등의 드로잉(Drawing) 메서드가 불려 갈 때까지는 발생하지 않는다.

입력 정점 요소로부터 프로그래밍 가능한 정점 셰이더의 정점 입력 레지스터에의 맵핑은, 셰이더 선언 중(안)에서 정의되지만, 입력 정점 요소는, 그 사용법에 관한 특정의 의미들을 가지지 않는다. 입력 정점 요소의 해석은, 셰이더의 명령을 사용해 프로그래밍 된다. 정점 셰이더의 함수는, 각 정점에 적용하는 일련의 명령에 의해 정의된다. 정점 출력 레지스터는, 셰이더 함수내의 명령에 의해 명시된다.

다만, 여기에서는, 요소와 레지스터와의 의미적인 맵핑보다, 「왜 스트림을 사용하는 것인가」 및 「스트림은 어떠한 문제를 해결하는 것인가」라고 하는 점을 중심으로 설명한다. 스트림의 주된 이점은, 이전의 멀티 텍스처링에 부착의 것에서 만난 정점 데이터에 의한 코스트를 제거할 수 있다고 하는 점이다. 스트림의 도입 이전에는, 사용자는 미사용의 데이터 요소가 없게 싱글 및 멀티 텍스처를 처리하기 위해서 정점 데이터 세트를 복제하는지, 멀티 텍스처 이외에서는 사용되지 않는 데이터 요소를 전송 할 필요가 있었다.

싱글 텍스처용과 멀티 텍스처용으로 1 개씩, 정점 데이터세트를 2 개 사용하는 예를 다음에 나타낸다.

 
struct CUSTOMVERTEX_TEX1
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_1, tv_1;   // Texture coordinates for a single texture
};
 
struct CUSTOMVERTEX_TEX2
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_2, tv_2;   // Texture coordinates for multitexturing
};

이 대신에, 양쪽 모두의 텍스처 좌표세트를 저장 하는 단일의 정점 요소를 사용할 수도 있다.

 
struct CUSTOMVERTEX_TEX2
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_1, tv_1;   // Texture coordinates for a single texture
    float tu_2, tv_2;   // Texture coordinates for multitexturing
};

이 정점 데이터를 사용하는 경우, 위치 데이터 및 색데이터의 복사가 1 개만 메모리에 건네져 싱글 텍스처의 렌더링의 경우에서도, 양쪽 모두의 텍스처 좌표세트를 전송 할 필요가 있다.

이 경우의 트레이드 오프는 명확하다. 스트림을 사용하면 이 딜레마를 잘 해결할 수 있다. 3 개의 스트림을 지원 하는 일련의 정점 정의를 다음에 나타낸다. 1개는 위치와 색용, 1개는 텍스처 좌표의 최초세트용, 이제 1개는 텍스처 좌표의 제 2 세트용이다.

 
// multistream vertex
// stream 0, pos, diffuse, specular
struct POSCOLORVERTEX
{
    FLOAT x, y, z;
    DWORD diffColor, specColor;
};
#define D3DFVF_POSCOLORVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR)


// stream 1, tex coord 0
struct TEXC0VERTEX
{
    FLOAT tu1, tv1;
};
#define D3DFVF_TEXC0VERTEX (D3DFVF_TEX1)

// stream 2, tex coord 1
struct TEXC1VERTEX
{
    FLOAT tu2, tv2;
};
#define D3DFVF_TEXC1VERTEX (D3DFVF_TEX0)

정점 선언은 다음과 같이 된다.

 
// multitexture - multistream

D3DVERTEXELEMENT9 dwDecl3[] = 
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  0 },
	{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  1 },
	{ 1, 36, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_TEXCOORD, 0 },
	{ 2, 44, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_TEXCOORD, 0 },
	D3DDECL_END()
};

여기서, 정점 선언 개체를 생성 해, 다음과 같이 설정한다.

 
LPDIRECT3DVERTEXDECLARATION9 m_pVertexDeclaration;
g_d3dDevice->CreateVertexDeclaration( dwDecl3, &m_pVertexDeclaration );

m_pd3dDevice->SetVertexDeclaration( m_pVertexDeclaration );

편성의 예

디퓨즈색을 가지는 1 스트림

디퓨즈색을 렌더링 하는 정점 선언과 스트림 설정은, 다음과 같이 된다.

 
D3DVERTEXELEMENT9 dwDecl3[] = 
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  0 },
	{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  1 },
	D3DDECL_END()
};


   m_pd3dDevice->SetStreamSource( 0, m_pVBVertexShader0, 0,
                                      sizeof(CUSTOMVERTEX) );
   m_pd3dDevice->SetStreamSource( 1, NULL, 0, 0);
   m_pd3dDevice->SetStreamSource( 2, NULL, 0, 0);

색과 텍스처를 가지는 2 스트림

단일의 텍스처를 렌더링 하는 정점 선언과 스트림 설정은, 다음과 같이 된다.

 
D3DVERTEXELEMENT9 dwDecl3[] = 
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  0 },
	{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  1 },

	{ 1, 36, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_TEXCOORD, 0 },

	D3DDECL_END()
};


   m_pd3dDevice->SetStreamSource( 0, m_pVBPosColor, 0,
                                           sizeof(POSCOLORVERTEX) );
   m_pd3dDevice->SetStreamSource( 1, m_pVBTexC0, 0,
                                           sizeof(TEXC0VERTEX) );
   m_pd3dDevice->SetStreamSource( 2, NULL, 0, 0);

색과 2 개의 텍스처를 가지는 2 스트림

2 텍스처로 멀티 텍스처 렌더링을 실시하는 정점 선언과 스트림 설정은, 다음과 같이 된다.

 
D3DVERTEXELEMENT9 dwDecl3[] = 
{
	{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  0 },
	{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_COLOR,  1 },

	{ 1, 36, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_TEXCOORD, 0 },

	{ 2, 44, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
	                                  D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()
};
 
m_pd3dDevice->SetStreamSource( 0, m_pVBPosColor, 0, 
                                          sizeof(POSCOLORVERTEX) );
m_pd3dDevice->SetStreamSource( 1, m_pVBTexC0, 0, 
                                          sizeof(TEXC0VERTEX) );
m_pd3dDevice->SetStreamSource( 2, m_pVBTexC1, 0, 
                                          sizeof(TEXC1VERTEX) );

어느 경우도, 다음의 IDirect3DDevice9::DrawPrimitive 의 호출로 충분하다.

 
       m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, NUM_TRIS );

이것은, 스트림에 의해, 데이터의 복제나 버스상에서의 장황한 데이터의 전송 (즉 대역폭의 낭비)의 문제를 유연하게 해결할 수 있는 것을 나타내고 있다.



© 2002 Microsoft Corporation. All rights reserved.
↑TOP