ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 정점 버퍼 생성하기
    Programing/DirectX 2008. 5. 8. 14:37


    다이렉트 SDK기본 튜토리얼 2번째시간에 있는 정점 버퍼 생성에 관한 글이다.
    첫번째 시간의 디바이스 생성코드를 기준으로 작성을 하기로 한다.

    우선 정점 버퍼를 만들기 위하여 전역 변수에 다음과 같이 정점을 보관할 정점 버퍼를 생성한다.

    LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;

    다음으로 정점을 정의할 구조체를 만든다. 튜토에서 처럼 구조체 이름을 CUSTOMVERTEX로 하기로 한다. 이 구조체는 사용자 자신이 원하는 여러가지 형태로 만들수 있는데 D3D에 정해져 있는 포맷은 다음과 같다.

     정점 좌표 : 정점의 3차원 좌표를 나타낸다. (float)
     RWH : 동차 좌표계의 값, 이값이 있으면 변환이 완료된 정점이다.(float)
     결합 가중치 : 스키닝에 사용된다.(float)
     법선 벡터 : 정점의 법선 벡터를 나타낸다. 주로 광원 처리시 사용된다. (float)
     확산광 : 정점의 확산광 색깔을 나타낸다.(DWORD)
     반사광 : 정점의 반사광 색깔을 나타낸다.(DWORD)
     텍스처 좌표 : 텍스처 좌표값을 나타낸다. 총 8개까지의 텍스처를 동시에 겹쳐 사용 가능 (float)


    위와 같은 포맷을 전부 다 사용할수도 있지만, 꼭 필요한 것들이 무엇인지 생각하고 데이터 낭비를 줄일 필요가 있다.

    2번째 튜토인 정점 버퍼생성에서는 단지 정점 좌표와 RHW, 정점의 반사광만을 사용하여 아래처럼 만들었다.

    struct CUSTOMVERTEX
    {
     FLOAT x, y, z, rhw; /// 정점의 변환된 좌표(rhw값이 있으면 변환이 완료된 정점이다.
     DWORD color;        /// 정점의 색깔
    };


    이제 구조체가 만들어 졌다면 구조체와 함께 반드시 플래그 선언도 해줘야만 한다. 단 구조체 선언시 사용된 항목이 들어간 형태 및 순서 그대로 만들어줘야 한다. 위의 구조체에 대한 플래그 선언은 아래와 같다.

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

    이렇게 해서 정점을 생성하기 위한 기본 준비가 끝났다.
    이제 실제로 값을 할당해야 한다. 이렇게.....

    CUSTOMVERTEX vertices[] =
     {
      { 150.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
      { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
      {  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
     };

    위에 선언된 구조체에 해당되는 값으로 3개의 정점을 선언하였다.

    정점 버퍼는 보통의 다른 것들과는 달리 특수한 메모리에 저장되어 훨씬 효율적이다. 크게 비디오 메모리와 시스템메모리 두가지의 메모리를 사용한다.
    또한 번외적인 이야기 이지만 DrawPrimitiveUp()함수를 사용하여 정점 버퍼가 아닌 배열을 사용하여 직접 정점을 관리 할수도 있다.

    다시 본론으로 돌아와서 정점을 선언했으니 이제 그 정점을 생성시켜야 한다.
    정점을 생성시키기 위해 CreateVertexBuffer() 함수를 이용한다.

    g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
      0, D3DFVF_CUSTOMVERTEX,
      D3DPOOL_DEFAULT, &g_pVB, NULL )


    이제 정점버퍼를 비디오카드에 생성하여 g_pVB에 보관하게 된 것이다.

    이렇게 만들어진 정점 버퍼는 쓰레기 값으로 가득 차 있기 때문에 값을 넣어줘야 한다.
    이때 Lock()함수 를 사용하여 메모리 포인터를 얻어낸다.

    VOID* pVertices;
    g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 )
    memcpy( pVertices, vertices, sizeof(vertices) );
     g_pVB->Unlock();


    위는 정점버퍼의 메모리 포인터를 얻어온후 memcpy함수를 사용하여 값을 복사한후 닫아주는 과정이다.
    이렇게 되면 이제 정점 버퍼의 생성이 최종 완료 된 것이다.
    이제는 그리는 과정(렌더링)만이 남아있는 것이다.

    렌더링 과정을 위해서는 BeginScene()과 EndScene()사이에 들어갈 다음의 3가지 함수의 도움이 필요하다.

    렌더링 과정 보러가기


Designed by Tistory.