ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • X 파일 읽고 렌더링하기
    Programing/DirectX 2008. 5. 23. 12:53

    D3DXLoadMeshFromX 함수를 사용하여 x파일에 보관된 메쉬 데이터를 읽어들일 수 있다.
    이 메서드는 ID3DXMesh 객체를 만들고 여기에 X파일의 기하정보 데이터를 읽어들인다.

    HRESULT D3DXLoadMeshFromX(      
        LPCTSTR pFilename,
        DWORD Options,
        LPDIRECT3DDEVICE9 pDevice,
        LPD3DXBUFFER* ppAdjacency,
        LPD3DXBUFFER* ppMaterials,
        LPD3DXBUFFER* ppEffectInstances,
        DWORD* pNumMaterials,
        LPD3DXMESH* ppMesh
    );

    첫번째 인자는 읽어 들이고자 하는 X파일의 파일명이다.
    두번째 인자는  메쉬의 생성 옵션과 관계되는 D3DXMESH 열거형의 플래그이다.
    세번째는 메쉬와 연결될 장치이며
    네번째 인자는 인접성 데이터를 포함한 버퍼의 포인터이다. ID3DXBuffer를 리턴한다.
    다섯번째 인자는 메트리얼 데이터를 포한한 버퍼의 포인터이다.  ID3DXBuffer를 리턴한다.
    여섯번째는 이펙트 인스턴스의 배열을 포함한 포인터이다..보통 0 을 지정
    일곱번째 인자는 메쉬의 재질수를 리턴한다. 그니깐 다섯번째의 배열수라고 생각하면 된다.
    마지막인자는 X파일 기하정보로 채워진 ID3DXMesh 객체를 리턴해주는 인자이다.

    위의 인자중에 다섯번째와 일곱번째 인자는 재질에 관한 내용인데 다섯번째 인자는 재질 데이터를 포함하는 D3DMATERIAL 구조체배열을 리턴한다. D3DMATERIAL 구조체는 D3DMATERIAL9 정보와 파일이름의 두가지 인자를 가질수 있다.
    X파일은 텍스처 데이터를 직접 포함하지 않으며 실제 텍스처 데이터를 포함하는 이미지 파일로의 파일명을 포함한다. 즉 D3DXLoadMeshFromX로 부터 X파일을 읽어들인 다음 알아낸 텍스처 파일명으로 텍스처 데이터를 읽어들여야 하는 것이다.

    간단하게 X파일을 읽어들이는 과정을 살펴보면...

    일단 전역변수 선언
    ID3DXMesh*                              Mesh = 0;
    std::vector<D3DMATERIAL9>       Mtrls(0);
    std::vector<IDirect3DTexture9*>   Textures(0);

    1. 우선 X파일을 읽어들이는 작업이 이뤄져야 한다.
    HRESULT hr = 0;
    hr = D3DXLoadMeshFromX( 
      "X파일명",
      D3DXMESH_MANAGED,
      p_Device,    // 연결될 장치
      &adjBuffer,  // 인접성 데이터를 포함한 버퍼 (ID3DXBuffer*)
      &mtrlBuffer, // 재질(ID3DXBuffer*)
      0,
      &numMtrls, // 재질수(DWORD)
      &Mesh);    // X파일로 부터 읽은 메쉬 데이러틀 보관할 ID3DXMesh*  객체


    2. 이제 실제 X파일 데이터를 읽어들인다. 또한 텍스처를 읽어 들인다.

    if( mtrlBuffer != 0 && numMtrls != 0 ) // 만일 메터리얼 정보가 있다면
     {
     //데이터시작포인터 얻어오기
      D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

      for(int i = 0; i < numMtrls; i++) // 포함하고 있는 재질 수 만큼
      {
      // Ambient값을 준후에
       mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;
       // 재질을 저장한다.
       Mtrls.push_back( mtrls[i].MatD3D ); // 단 Mtrls은 현재 vector이다.

       // 이제 텍스처가 있는지를 검사해본다.
       if( mtrls[i].pTextureFilename != 0 ) // 지정 메털리얼 이름을 가진 녀석이 있다면
       {
        // 서브셋을 위한 텍스처를 읽어들인다.
        IDirect3DTexture9* tex = 0;
        D3DXCreateTextureFromFile(
         p_Device,
         mtrls[i].pTextureFilename,
         &tex);

        // 읽어들인 텍스처를 저장한다.
        Textures.push_back( tex ); // 단 Textures은 현재 vector이다.
       }
       else // 만일 메터리얼 이름이 없다면
       {
        Textures.push_back( 0 );
       }
      }
     }

    3. 이제 셋팅된 메쉬를 보여주면 된다.

    for(int i = 0; i < Mtrls.size(); i++){
       p_Device->SetMaterial( &Mtrls[i] );
       p_Device->SetTexture(0, Textures[i]);
       Mesh->DrawSubset(i);
    }

    BeginScene() 와 EndScene() 사이에 위의 코드를 삽입하면된다.

    물론 여러가지 셋팅값들이 필요하긴 하지만 X파일을 읽어와서 화면에 렌더링하기위해서는 위의 3단계 를 거쳐야 하는 것이다.




     

Designed by Tistory.