Texture Export

이번장에는 텍스쳐 이름, UV 값을 출력해 본다.
텍스쳐 맵의 인터페이스는 Texmap 클래스로 텍스쳐 관련 정보를 얻어 올수 있다.

1. UI  추가

Export Texture 체크 박스를 추가 하였다.  리소스 아이디는 IDC_CHECK_EXPORT_TEXTURE이다.

ExporterOption.h에 다음을 추가한다.

//ExporterOption.h

class ExporterOption

{

private:

    // Our options

    ............

    bool m_bExportTexture;

 

public:

    .............

    bool ExportTexture() { return m_bExportTexture; }

    .............

};

체크박스에 대응하는 변수는 ExporterOption 클래스에 m_bExportTexture를 추가하여 텍스쳐를 익스포트 할것인지 나타낸다. 속성 메쏘드도 같이 추가한다.

//ExporterOption.cpp

ExporterOption::ExporterOption()

{

    m_bExportObject = m_bExportAnimation = m_bExportMaterial = m_bExportTexture = true;

    m_bForceSample = false;

}

 

 

INT_PTR CALLBACK ExporterOption::DialogProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

    ...................

        case WM_INITDIALOG:

            SetCheckBox(hWnd, IDC_CHECK_EXPORT_TEXTURE, imp->ExportTexture());

            return TRUE;

 

        case WM_COMMAND:

            switch(wParam)

            {

            case IDC_OK:

                imp->m_bExportTexture = IsDlgButtonChecked(hWnd, IDC_CHECK_EXPORT_TEXTURE) == BST_CHECKED;

            }

    ...................

}

m_bExportTexture를 초기화 하고 WM_INITDIALOG 메시지에서 IDC_CHECK_EXPORT_TEXTURE 체크박스를 셋팅 한다.  익스포트시 OK 버튼을 누르면, ExportOption()클래스의 m_bExportTexture 변수를 설정 한다.

2. 텍스쳐 익스포트( maxPluginTest.cpp )

ExportTexture(), WriteTexture() 2개의 메쏘드가 추가 되었다.

//maxPluginTest.cpp

class maxPluginTest : public SceneExport

{

    ................

    void ExportTexture(Mtl* pMtl, int iTreeDepth);

    ................

    void WriteTexture(Texmap* pTex, const char* pSlotName, int iTreeDepth);

};

 

void maxPluginTest::ExportMaterial(INode* pNode, int iTreeDepth)

{

    .................

        // Export this materials textures

        if (m_option.ExportTexture())

            ExportTexture(pMtl, iTreeDepth);

    }

}

 

void maxPluginTest::ExportTexture(Mtl* pMtl, int iTreeDepth)

{

    // Iterate all the textures this mtl could possibly

    // have assigned.  If a texture is assigned, export it

    for (int i = 0; i < pMtl->NumSubTexmaps(); i++)

    {

        Texmap* pTex = pMtl->GetSubTexmap(i);

        if (pTex != NULL)

        {

            MSTR sSlotName = pMtl->GetSubTexmapSlotName(i);

            WriteTexture(pTex, sSlotName.data(), iTreeDepth + 1);

        }

    }

}

 

void maxPluginTest::WriteTexture(Texmap* pTex, const char* pSlotName, int iTreeDepth)

{

    // There are many different types of textures in Max

    // Which one have we got here?

    MSTR sTexClass;

    pTex->GetClassName(sTexClass);

    Write(iTreeDepth, "%s Tex: %s", pSlotName, sTexClass.data());

 

    // If our texture is an image file, write out its path

    if (pTex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))

    {

        BitmapTex* pBmpTex = (BitmapTex*) pTex;

        StdUVGen* pUVGen = pBmpTex->GetUVGen();

 

        // Note to reader: All these parameters could

        // be animated!  Here we only export at time

        // 0 for convenience, in production we must be careful

        // to take care of exporting values at the correct time

        float fUTile = pUVGen->GetUScl(0);

        float fVTile = pUVGen->GetVScl(0);

 

        Write(iTreeDepth, "   path: \"%s\"", pBmpTex->GetMapName());

        Write(iTreeDepth, "   U Tile = %.1f, V Tile = %.1f\n", fUTile, fVTile);

    }

}

Mtl::NumSubTexmaps()에 의해 텍스쳐 맵의 갯수를 얻는다.

Mtl::GetSubTexmap(int i)에 의해 Texmap의 포인터를 얻는다.

Mtl::GetSubTexmapSlotName()은 슬롯의 이름을 리턴한다.( 일반적인 텍스쳐인 경우 "Diffuse Color"이다)

텍스쳐 정보를 가져올때 비트맵 텍스쳐만 처리하고 있다. 다른 타입의 텍스쳐를 처리 할려면 별도로 처리 해야 한다. (비트맵인 경우 Class_ID는 BMTEX_CLASS_ID이다)

비트맵 텍스쳐를 다루는 클래스는 BitmapTex로 캐스팅한다. BitmapTex 클래스의 메쏘드로 UV값과 텍스쳐의 이름을 알수 있다.

파라메터가 MULTI_CLASS_ID면 여러개의 서브 메트리얼을 가지고 있다는 것을 뜻한다.

멀티 서브 오브젝트는 기회가 되면 다루도록 하겠다.

결과)   9texture.max         texture.TXT

소스)  maxPluginTest09_texture.zip