Multi Stream

지금까지 예제들은 스트림을 하나만 사용하였다. 스트림을 여러개 사용하면 정점 정보를 다양하게 사용 할 수 있다. 앞으로 어떻게 사용할지 모르겠지만 멀티 스트림 예제를 다뤄 보겠다.

IDirect3DDevice::SetStreamSource(...) 첫 번째 인자에 스트림 인덱스가 들어간다. 하드웨어 적으로 지원하는 스트림의 갯수는 보통 16개이다. 스트림의 갯수를 알아 볼려면 다음과 같이 실행한다.

int GetMaxStream()

{

    D3DCAPS9 caps;

    g_dxDevice->GetDeviceCaps( &caps );

    int num = caps.MaxStreams;   

    return num;

}

기존 directx9.0/tutorial14 예제를 멀티 스트림을 사용하는 예제로 바꿔 본다.

<정점 선언과 오브젝트 생성>

셰이더를 사용 했던 D3DVERTEXELEMENT9와 IDirect3DDevice::CreateVertexDeclaration()을 이용한다.
위치, 정점의 칼라, 텍스쳐 UV 좌표 3개를 사용하는 정점을 선언하는 오브젝트를 생성한다.

위치는 스트림 0번, 정점 칼라는 스트림 1번, 텍스쳐 UV좌표는 스트림 2번을 사용하여 vertexElem[]를 선언한다.

    //정점 선언

    D3DVERTEXELEMENT9 vertexElem[] =

    {

       { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, //정점 좌표

       { 1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, //칼라

       { 2, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, //텍스쳐 UV 좌표

       D3DDECL_END ()

    };

 

    //정점 선언 오브젝트 생성

    LPDIRECT3DVERTEXDECLARATION9    g_vertexDec = NULL;

    g_dxDevice->CreateVertexDeclaration (vertexElem, &g_vertexDec);

<정점 버퍼 생성>

3개의 스트림을 사용하기로 계획하였으므로 3개의 정점 버퍼(위치, 정점의 칼라, 텍스쳐 UV좌표)를 생성한다.

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_COORD), 0, D3DFVF_XYZ, D3DPOOL_MANAGED, &g_vertexCoordBuf, NULL);

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_COLOR), 0, D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &g_vertexColorBuf, NULL);

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_TEXCOORD), 0, D3DFVF_TEX1, D3DPOOL_MANAGED, &g_vertexTexcoordBuf, NULL);

정점 버퍼 생성과 데이터를 복사하는 전체 소스는 다음과 같다.

    //정점 버퍼 생성

    VERTEX_COORD vertex[4];

    vertex[0].x = -fSizeX/2;    vertex[0].y = 0.0f;        vertex[0].z = -fSizeY/2;

    vertex[1].x = fSizeX/2;        vertex[1].y = 0.0f;        vertex[1].z = -fSizeY/2;

    vertex[2].x = -fSizeX/2;    vertex[2].y = 0.0f;        vertex[2].z = fSizeY/2;

    vertex[3].x = fSizeX/2;        vertex[3].y = 0.0f;        vertex[3].z = fSizeY/2;

 

    VERTEX_COLOR col[4];

    col[0].color = 0xffff0000;

    col[1].color = 0xffff0000;

    col[2].color = 0xffff0000;

    col[3].color = 0xffff0000;

 

    VERTEX_TEXCOORD tex[4];

    tex[0].u = 0.0f;            tex[0].v = 1.0f;

    tex[1].u = 1.0f;            tex[1].v = 1.0f;

    tex[2].u = 0.0f;            tex[2].v = 0.0f;

    tex[3].u = 1.0f;            tex[3].v = 0.0f;

 

    LPDIRECT3DVERTEXBUFFER9        g_vertexCoordBuf = NULL;

    LPDIRECT3DVERTEXBUFFER9        g_vertexColorBuf = NULL;

    LPDIRECT3DVERTEXBUFFER9        g_vertexTexcoordBuf = NULL;

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_COORD), 0, D3DFVF_XYZ, D3DPOOL_MANAGED, &g_vertexCoordBuf, NULL);

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_COLOR), 0, D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &g_vertexColorBuf, NULL);

    g_dxDevice->CreateVertexBuffer (4*sizeof(VERTEX_TEXCOORD), 0, D3DFVF_TEX1, D3DPOOL_MANAGED, &g_vertexTexcoordBuf, NULL);

 

    VOID* pVertices;

    g_vertexCoordBuf->Lock(0, sizeof(vertex), &pVertices, 0);

    memcpy (pVertices, vertex, sizeof(vertex));

    g_vertexCoordBuf->Unlock();

 

    g_vertexColorBuf->Lock(0, sizeof(col), &pVertices, 0);

    memcpy (pVertices, col, sizeof(col));

    g_vertexColorBuf->Unlock();

 

    g_vertexTexcoordBuf->Lock(0, sizeof(tex), &pVertices, 0);

    memcpy (pVertices, tex, sizeof(tex));

    g_vertexTexcoordBuf->Unlock();

<렌더링: 스트림 설정>

BeginScene(), EndScene() 사이에 SetFVF()대신 SetVertexDeclaration()을 사용하여 스트림을 설정한다.
위치는 스트림 0번, 정점 칼라는 스트림 1번, 텍스쳐 UV좌표는 스트림 2번을 지정해 준다.

    //g_dxDevice->SetFVF (D3DFVF_CUSTOMVERTEX);

    //g_dxDevice->SetStreamSource(0, g_VertexBuffer, 0, sizeof(CUSTOMVERTEX));

    g_dxDevice->SetVertexDeclaration( g_vertexDec );

    g_dxDevice->SetStreamSource( 0, g_vertexCoordBuf, 0, sizeof(VERTEX_COORD));

    g_dxDevice->SetStreamSource( 1, g_vertexColorBuf, 0, sizeof(VERTEX_COLOR));

    g_dxDevice->SetStreamSource( 2, g_vertexTexcoordBuf, 0, sizeof(VERTEX_TEXCOORD));

<렌더링: 스트림 NULL 설정>

텍스쳐 스트림을 출력 할 필요가 없으면 NULL로 지정한다.
텍스쳐가 출력 되지 않기 때문에 빨간색의 평면이 보일 것이다.

    g_dxDevice->SetStreamSource( 2, NULL, 0, 0);

소스: multi_stream.zip