XML Exporter: Viewer

  Xml Exporter가 완성 되지 않았지만 익스포트 작업이 제대로 진행 되는지 파악 할려면 뷰어 프로그램이 필요하다. 와이어프레임으로 맥스에서 익스포트한 정점 정보를 출력해  보자.

아직 엔진이라고 하기에는 그렇고 라이브러리 단계이다. 클래스 이름 앞에는 Easy 약자인 E를 붙인다.

XmlMesh : 맥스에서 익스포트한 XML 데이터를 읽는 노드.

ENode : XmlMesh 데이터를 ENode 클래스로 변환 후, 실제로 그리는 부분이다.

EMesh : 버텍스와 인덱스 배열을 가지고 있는 노드로 메쉬를 가지고 노드들의 기본 클래스이다.

EStaticMesh : 스태틱 메쉬로 그리는 클래스.

VertexInfo : XmlMesh에서 Xml 데이터를 메쉬 정보로 변환 할 때 사용 되는 구조체

StaticVertex : 다이렉트X의 버텍스 버퍼에 사용되는 구조체이다.

처리 순서는 다음과 같다.

 

1. ReadXml() 함수로 맥스에서 익스포트 한 XML 로딩

        XmlMesh* xmlMesh = ReadXml<XmlMesh>( "data/test.XML" );

XmlNode 대신 XmlMesh 클래스로 Xml을 로딩하기 위해 ReadXml<XmlMesh>로 데이터를 읽는다.

2. XmlMesh::Traverse() 버텍스 엘리먼트와 인덱스 엘리먼트를 VertexInfo 타입의 m_vertex와 base::Index3 타입의 m_index에 저장한다.

        if( xmlMesh )

            xmlMesh->Traverse(); //OnUpdate()호출

Traverse() 메쏘드는 재귀 호출로 각 노드를 순회한다. 순회하면서 OnUpdate()가 호출 된다.

void XmlMesh::OnUpdate()

{

    if( *GetName() == "mesh" )

    {

        ConvertMeshInfo();   

        DetachChild(); //ConvertMeshInfo() 이후로는 Vertex나 Index의 노드는 제거한다.

    }

}

"mesh" 엘리먼트 이하의 버텍스와 인덱스의 XML 정보를 ConvertMeshInfo()에 의해 배열 정보로 변환한다.
배열 정보로 변환 후 자식 엘리먼트는 필요 없기 때문에 제거한다.

3. XmlMesh::CreateMesh()로 엔진단의 노드인 ENode를 생성한다.

    ENode* g_pMesh = NULL;

    g_xmlMesh->CreateMesh( g_pMesh );

4.  다이렉트X의 BeginScene()와 EndScene() 사이에 ENode::Draw()로 메쉬를 그려준다.

    g_d3d_Device->BeginScene ();

    ....

    g_pMesh->Draw();

    ....

    g_d3d_Device->EndScene ();

5. 다 사용했으면 제거한다.

    if( g_pMesh )

        delete g_pMesh;

    if( g_xmlMesh )

        delete g_xmlMesh;

 

< 문제점 >

노드별로 이동, 회전, 크기 정보가 맥스처럼 적용되어 있지 않기 때문에 박스, 원기둥, 피라미드,, 주선자가 한 군데 모여있다.
옆에서 보는 시점인데 위에서 보는것처럼 보인다. 이 문제는 맥스의 좌표계와 다이렉트X 좌표계의 차이다.
이 두가지 문제는 다음에 해결 한다.

3DSMAX 화면

실행 화면

 

프로젝트:  viewer.zip

참고 :
http://www.3dapi.com/
3D 게임 프로그래밍
DirectX9를 이용한 3D GAME 프로그래밍 입문r