XML Exporter: Texture Rendering (1Â÷ ¿Ï¼º)

¸Æ½º Ç÷¯±×ÀÎ : ÅؽºÃÄ Export

ÅؽºÃÄ ÁÂÇ¥¸¦ ÀͽºÆ÷Æ® Çؼ­ ÅؽºÃĸ¦ ·»´õ¸µ ÇÑ´Ù.

¸Æ½º¿¡¼­ ÅؽºÃÄ ÁÂÇ¥¿Í Á¤Á¡ ÁÂÇ¥´Â 1:1ÀÌ ¾Æ´Ï´Ù. Á¤Á¡ À妽º ¸®½ºÆ®¿Í º°µµ·Î ÅؽºÃÄ ÁÂÇ¥µµ À妽º ¸®½ºÆ®·Î °ü¸®ÇÏ¿© °øÀ¯ÇÏ°í ÀÖ´Ù.

±×·¡¼­ ¸Æ½º¿¡¼­´Â ÅؽºÃÄ ÁÂÇ¥ À妽º ¸®½ºÆ®°¡ º°µµ·Î Á¸ÀçÇÑ´Ù. ÀϹÝÀûÀ¸·Î ÅؽºÃÄ Á¤Á¡ÀÌ ¸Þ½¬ÀÇ Á¤Á¡°¹¼öº¸´Ù ¸¹´Ù.  Á¤Á¡Àº ÇÑ °³Àε¥ Á¤Á¡À» °øÀ¯ÇÏ´Â »ï°¢Çü µÎ °³°¡ ÅؽºÃÄ°¡ ´Ù¸£¸é ÅؽºÃÄ ÁÂÇ¥´Â ¸Þ½¬ÀÇ Á¤Á¡º¸´Ù ¸¹¾Æ Áú°ÍÀÌ´Ù.  ¾Æ·¡ ±×¸²À» º¸°í ÀÌÇØÇÏ´Â°Ô ´õ ½¬¿ï °ÍÀÌ´Ù.

< Á¤Á¡ Face À妽º¿Í ÅؽºÃÄ Face À妽ºÀÇ °ü°è >

  a b c a b c
Á¤Á¡ face
À妽º
V0 V1 V3 V1 V2 V3

ÅؽºÃÄ
face
À妽º

T0 T1 T2 T3 T4 T7

À§ÀÇ ±×¸²¿¡¼­ V0, V1, V2, V3Àº Á¤Á¡ ÁÂÇ¥ÀÇ face À妽ºÀÌ°í, T1, T2, T3, T4, T5, T7Àº ÅؽºÃÄ ÁÂÇ¥ À妽ºÀÌ´Ù. À§ÀÇ ±×¸²Ã³·³ ÅؽºÃÄ ÁÂÇ¥ face À妽º¿¡ ¸ÂÃç Á¤Á¡, ³ë¸Ö, ¾Ö´Ï¸ÞÀÌ¼Ç ºí·£µù °ªÀ» Á¶Á¤ ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù.

XmlExp::WriteTextureCoordinate()¸Þ¼Òµå¿¡¼­ ÅؽºÃÄ°¡ Æ÷ÇÔµÈ Á¤Á¡À» ÀͽºÆ÷Æ® ÇÏ´Â °ÍÀº ´ÙÀ½ÀÇ ¼ø¼­·Î ÁøÇàµÈ´Ù.

1. ÅؽºÃÄ Face À妽º ¸®½ºÆ®¿Í ÅؽºÃÄ ÁÂÇ¥¸¦ ¹è¿­ pTvFace, pUV·Î °¡Á® ¿Â´Ù..
2. ÅؽºÃÄ Face À妽º ¸®½ºÆ®¸¦ ¿À¸§Â÷¼øÀ¸·Î Á¤·ÄÇϸ鼭 Áߺ¹µÈ µ¥ÀÌÅ͸¦ Á¦°ÅÇÑ´Ù.
3. ÅؽºÃÄ Face À妽º, Á¤Á¡ Face À妽º, UV ÁÂÇ¥¸¦ ÇϳªÀÇ ±×·ìÀ¸·Î ÇÏ¿© ¹è¿­ uvFaceArrÀ» ¸¸µç´Ù.
4. uvFaceArrÀÇ  ÅؽºÃÄ À妽º °ªÀ¸·Î pTvFaceÀÇ À妽º °ªÀ» ¼öÁ¤ÇÑ´Ù.
5. uvFaceArrÀ» ±âÁØÀ¸·Î Á¤Á¡ ¸®½ºÆ®¸¦ ´Ù½Ã ¸¸µç´Ù.
6. pTvFace¸¦ »õ·Î¿î Á¤Á¡ Face À妽º·Î Á¤ÇÑ´Ù.
7. uvFaceArrÀÇ Á¤Á¡ À妽º·Î ºí·©µù ¸®½ºÆ®¸¦ »õ·Ó°Ô ±¸¼ºÇÑ´Ù.

1. ÅؽºÃÄ Face À妽º ¸®½ºÆ®¿Í ÅؽºÃÄ ÁÂÇ¥¸¦ ¹è¿­ pTvFace, pUV·Î °¡Á® ¿Â´Ù..
pTvFace¿¡ »ï°¢Çü À妽º ¸®½ºÆ®¸¦ ÀúÀåÇÑ´Ù.
PUV¿¡  ÅؽºÃÄ ÁÂÇ¥¸¦ ÀúÀåÇÑ´Ù.

    base::Index3* pTvFace = new base::Index3[ numFace ];   

    base::Vector2* pUV = new base::Vector2[ numTVerts ];

 

    //1. ÅؽºÃÄ ÁÂÇ¥ Face À妽º ¸®½ºÆ®¿Í ÅؽºÃÄ ÁÂÇ¥¸¦ ¹è¿­ pTvFace, pUV·Î °¡Á® ¿Â´Ù..

    for( int i = 0; i < numFace; ++i )

    {

        base::Index3& index = pTvFace[i];

        index.a = pMesh->tvFace[i].t[0];

        index.b = pMesh->tvFace[i].t[1];

        index.c = pMesh->tvFace[i].t[2];

 

        if( GetLeftHand() )

        {

            index.b = pMesh->tvFace[i].t[2];

            index.c = pMesh->tvFace[i].t[1];

        }

    }

 

    for(int n=0; n < numTVerts; ++n)

    {

        UVVert t = pMesh->tVerts[n];

        pUV[n].x = t.x;

        pUV[n].y = 1.f - t.y;    // DXÀÇ UV¿¡ ¸Â°Ô ¼öÁ¤

    }


2. ÅؽºÃÄ Face À妽º ¸®½ºÆ®¸¦ ¿À¸§Â÷¼øÀ¸·Î Á¤·ÄÇϸ鼭 Áߺ¹µÈ µ¥ÀÌÅ͸¦ Á¦°ÅÇÑ´Ù.
ÅؽºÃÄ ÁÂÇ¥ »ï°¢Çü ¸®½ºÆ®¿¡¼­ Áߺ¹µÈ Á¤Á¡, ºó À妽º¸¦ Á¦°ÅÇϱâ Çϱâ À§ÇØ  ¸Ê tvFaceMap¿¡ ÀúÀåÇÑ´Ù.

    mapTvFace tvFaceMap;

    for(int n = 0; n < numFace; ++n)

    {

        tvFaceMap.insert( mapTvFace::value_type( pTvFace[n].a,  m_mesh.pFace[n].a) );

        tvFaceMap.insert( mapTvFace::value_type( pTvFace[n].b,  m_mesh.pFace[n].b) );

        tvFaceMap.insert( mapTvFace::value_type( pTvFace[n].c,  m_mesh.pFace[n].c) );

    }

3. ÅؽºÃÄ Face À妽º, Á¤Á¡ Face À妽º, UV ÁÂÇ¥¸¦ ÇϳªÀÇ ±×·ìÀ¸·Î ÇÏ¿© ¹è¿­ uvFaceArrÀ» ¸¸µç´Ù.
Á¤·ÄµÈ tvFaceMapÀ» º¤ÅÍ uvFaceArr¿¡ ¿Å±ä´Ù.  À̶§, ÅؽºÃÄ ÁÂÇ¥µµ °°ÀÌ ÀúÀåÇÑ´Ù.
³ªÁß¿¡ uvFaceArrÀ» ÀÌ¿ëÇÏ¿© Á¤Á¡ ¸®½ºÆ®, ³ë¸Ö°ª ¸®½ºÆ®¸¦ ±¸ÇÒ °ÍÀÌ´Ù.

    mapTvFaceIter    iter        = tvFaceMap.begin();

    mapTvFaceIter    endIter        = tvFaceMap.end();

 

    std::vector<UVIndex> uvFaceArr;

    for(; iter != endIter; ++iter )

    {

        int nTIndex = iter->first;

        int nVIndex = iter->second;

 

        float u = pUV[nTIndex].x;

        float v = pUV[nTIndex].y;

 

        uvFaceArr.push_back( UVIndex(nTIndex, nVIndex, u, v));

    }

4. uvFaceArrÀÇ  ÅؽºÃÄ À妽º °ªÀ¸·Î pTvFaceÀÇ À妽º °ªÀ» ¼öÁ¤ÇÑ´Ù.
Áß°£¿¡ »ç¿ëµÇÁö ¾Ê´Â À妽º°¡ Á¦°ÅµÈ´Ù.

    for(int n=0; n < uvFaceArr.size(); ++n)

    {

        int tIndex = uvFaceArr[n].ti;

 

        for(int j = 0; j < numFace; ++j)

        {

            if(tIndex == pTvFace[j].a)   

                pTvFace[j].a = n;

            if(tIndex == pTvFace[j].b)   

                pTvFace[j].b = n;

            if(tIndex == pTvFace[j].c)   

                pTvFace[j].c = n;

        }

    }

5. uvFaceArrÀ» ±âÁØÀ¸·Î Á¤Á¡ ¸®½ºÆ®¸¦ ´Ù½Ã ¸¸µç´Ù.
±âÁ¸ÀÇ Á¤Á¡, ³ë¸Ö°ªÀ» »èÁ¦ ÈÄ,  uvFaceArrÀÇ °ªÀ¸·Î Á¤Á¡, ³ë¸Ö°ªÀ» »ý¼ºÇÑ´Ù. À̶§, UV °ªµµ ÀúÀåÇÑ´Ù.

    int    nNewVtxSize =  (int)uvFaceArr.size();

    base::Vector3* pNewPos = new base::Vector3[nNewVtxSize];

    base::Vector3* pNewNor = new base::Vector3[nNewVtxSize];

    base::Vector2* pNewUV = new base::Vector2[nNewVtxSize];

 

    for(int n = 0; n < nNewVtxSize; ++n)

    {

        int faceIndex = uvFaceArr[n].vi;       

        base::Vector2 uv = uvFaceArr[n].uv;

 

        pNewPos[n] = m_mesh.pPos[ faceIndex ];

        pNewNor[n] = m_mesh.pNormal[ faceIndex ];

        pNewUV[n] = uv;

    }

 

    SAFE_DELETE_ARRAY( m_mesh.pPos );

    SAFE_DELETE_ARRAY( m_mesh.pNormal );

    SAFE_DELETE_ARRAY( m_mesh.pFace );

6. pTvFace¸¦ »õ·Î¿î Á¤Á¡ Face À妽º·Î Á¤ÇÑ´Ù.

    m_mesh.pFace = pTvFace; 

    m_mesh.pPos = pNewPos;

    m_mesh.pNormal = pNewNor;

    m_mesh.pUV = pNewUV;

    m_mesh.numVertex = nNewVtxSize;

7. uvFaceArrÀÇ Á¤Á¡ À妽º·Î ºí·©µù ¸®½ºÆ®¸¦ »õ·Ó°Ô ±¸¼ºÇÑ´Ù.

    BlendVector* pNewBone = new BlendVector[nNewVtxSize];

    BlendVector* pOldBone = m_mesh.pBoneWeight;

 

    for(int n=0; n < nNewVtxSize; ++n)

    {

        int oldIndex = uvFaceArr[n].vi;   

 

        if( oldIndex >= m_mesh.numBoneVertex )

            continue;

 

        BlendVector* pCurrBone = &pOldBone[ oldIndex ];   

 

        BlendVector::iterator iter = pCurrBone->begin();

        BlendVector::iterator endIter = pCurrBone->end();

 

        for(; iter != endIter; ++iter )

        {

            BlendData data = { (*iter).index, (*iter).weight };

            pNewBone[n].push_back( data );

        }

    }

 

    uvFaceArr.clear();

    SAFE_DELETE_ARRAY( pOldBone );

 

    m_mesh.pBoneWeight = pNewBone;

    m_mesh.numBoneVertex = nNewVtxSize;

 

< ÅؽºÃÄ ÁÂÇ¥¸¦ ÀͽºÆ÷Æ® Çϱâ±îÁö Å« È帧 >

1. DoExport¿¡¼­ BuildTextureCoordinate()¸¦ È£ÃâÇÑ´Ù.

int Export::DoExport(...)

{

    ......

    m_pXmlRoot->BuildTextureCoordinate();

    ......

}

2. BuildTextureCoordinate()¸¦ Àç±Í È£Ãâ·Î ½ÇÇàÇϸ鼭 WriteTextureCoordinate()°¡ trueÀ̸é XMLÀ»  ÀÌÀü "mesh" ³ëµå´Â »èÁ¦ÈÄ XMLÀ» »õ·Ó°Ô ¸¸µç´Ù.
ÅؽºÃÄ ÁÂÇ¥¸¦ ÀͽºÆ÷Æ® ÇÒ ¶§, Á¤Á¡À» ´Ù½Ã »ý¼ºÇϱâ À§ÇØ XmlExp Ŭ·¡½ºÀÇ MeshData m_mesh¿¡ Á¤Á¡ ±¸Á¶Ã¼ °ü·Ã °ªÀÌ ÀúÀå µÇ¾î ÀÖ´Ù.

void XmlExp::BuildTextureCoordinate()

{

    if( this->GetName() && *GetName() == "mesh" )

    {

        if( WriteTextureCoordinate() )

        {

            DetachMeshChild();

            XmlExp* pXmlExp = (XmlExp*)GetParent();

            WriteMesh( pXmlExp->GetINode() );

            return;

        }

    }

 

    XmlNode::ChildList* pChildList = &m_child;

    XmlNode::ChildList::iterator iter = pChildList->begin();

    XmlNode::ChildList::iterator endIter = pChildList->end();

    for( ; iter != endIter; ++iter )

    {

        XmlExp* pChildXml = (XmlExp*)*iter;

        pChildXml->BuildTextureCoordinate();

    }

}

 

ºä¾î : ÅؽºÃÄ

< ÅؽºÃÄ ÁÂÇ¥¿Í ÀçÁú Á¤º¸ ·Îµù >

XmlMesh Ŭ·¡½º¿¡´Â ÅؽºÃÄ UV¿Í ÅؽºÃÄ ÆÄÀÏ À̸§À» ¾ò¾î¿À´Â FetchTexureCoordinate(), FetchMaterial() ¸Þ¼Òµå°¡ Ãß°¡ µÇ¾ú´Ù.

void XmlMesh::ConvertMeshInfo()

{

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

    //ÅؽºÃÄ UV °ª Àбâ

    XmlNode* pUVXmlNode = FindFirstChild( "TextureUV" );

    if( pUVXmlNode  == NULL )

        return;

    pXmlMesh = (XmlMesh*)pUVXmlNode;

    pXmlMesh->FetchTexureCoordinate( GetParent()->m_vertexArr );

 

    //¸ÞÆ®¸®¾ó °ª Àбâ

    XmlNode* pMaterialXmlNode = FindFirstChild( "material" );

    if( pMaterialXmlNode  == NULL )

        return;

    pXmlMesh = (XmlMesh*)pMaterialXmlNode;

    pXmlMesh->FetchMaterial( &GetParent()->m_material );

}

< Á¤Á¡ ±¸Á¶Ã¼¿Í ÀçÁú Á¤º¸ >

Á¤Á¡ ±¸Á¶Ã¼¿¡ ÅؽºÃÄ uv¸¦ Àоî¿À±â À§ÇØ uv¸¦ Ãß°¡ÇÏ°í, FVF¿¡ D3DFVF_TEX1µµ Ãß°¡ÇÑ´Ù.

EShaderBoneMesh Ŭ·¡½º¿¡´Â ÅؽºÃÄ Á¤º¸¸¦ Ãß°¡ÇÑ´Ù.
std::string     m_diffuseMap;
LPDIRECT3DTEXTURE9  m_pTexture;

struct ShaderBlendVertex

{

    D3DXVECTOR3    p;            //¸Þ½ÃÀÇ Á¤Á¡

 

    FLOAT        weight[3];        // BLEND WEIGHT

    BYTE        boneIndex[4];    // MATRIX Index

 

    D3DXVECTOR3        n;            //¸Þ½ÃÀÇ ³ë¸Ö°ª

    D3DXVECTOR2        uv;            //ÅؽºÃÄ UV°ª

 

    ShaderBlendVertex() : p(0,0,0), n(0, 0, 0), uv(0, 0)

    {

        boneIndex[0] = boneIndex[1] = boneIndex[2] = boneIndex[3] = 0;

        weight[0] = weight[1] = weight[2] = 0;

    }

 

    enum {    FVF = (D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_TEX1 ),    };

};

< Á¤Á¡ ¹öÆÛ »ý¼º >

Á¤Á¡ ±¸Á¶Ã¼ÀÇ UV°ªÀ» ¼ÂÆÃÇÏ°í Á¤Á¡ÀÇ ÅؽºÃÄ À̸§À» ¼³Á¤ÇÑ´Ù.

int EShaderBoneMesh::CreateVertexBuffer( XmlNode* pXmlNode )

{

    ..........

    int n = m_nVertex = (int)xmlVx.size();

    ..........

    for( int i = 0; i < n; ++i )

    {

        //ÅؽºÃÄ ÁÂÇ¥

        m_pMeshVerts[i].uv.x = xmlVx[i].t.x;

        m_pMeshVerts[i].uv.y = xmlVx[i].t.y;

 

    }

    ..........

    //ÅؽºÃÄ À̸§

    if( pXmlMesh->m_material.diffuseMap.empty() == false )

    {

        this->m_diffuseMap =  pXmlMesh->m_material.diffuseMap;

    }

   ..........

}

< ·»´õ¸µ >

ÅؽºÃĸ¦ ·»´õ¸µ Çϱâ À§ÇØ D3DRS_FILLMODE ·»´õ »óŸ¦ D3DFILL_WIREFRAME¿¡¼­ D3DFILL_SOLID·Î ¹Ù²Û´Ù.·»´õ¸µ½Ã ÅؽºÃÄ°¡ ·Îµù ¾ÈµÇ¾úÀ¸¸é ÅؽºÃÄ ·Îµù ÈÄ ¼³Á¤ÇÑ´Ù.

int EShaderBoneMesh::OnRender()

{

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

    m_pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);

    ............. // ¼ÎÀÌ´õ ¼³Á¤

    if( this->m_diffuseMap.empty() == false )

    {

        hr = S_OK;

        if( m_pTexture == NULL )

        {

            char szTexture[MAX_PATH];

            sprintf_s( szTexture, MAX_PATH, "data\\%s", this->m_diffuseMap.c_str() );

            hr = D3DXCreateTextureFromFile( m_pDevice, szTexture, &m_pTexture );

        }

        if( m_pTexture )

            m_pDevice->SetTexture(0, m_pTexture );

    }

    .........  // ¸Þ½Ã ·»´õ¸µ

}

<¾ÕÀ¸·Î °úÁ¦>

±âº»ÀûÀΠij¸¯ÅÍ Ãâ·ÂÀº µÇ¾ú´Ù. ¸Æ½º Ç÷¯±×Àΰú ºä¾îÀÇ ³²Àº °úÁ¦¸¦ Á¤¸®ÇØ º»´Ù.

¸Æ½º ¹öÀü 2011·Î ¾÷±×·¹ÀÌµå ¹×, UI ¼öÁ¤
XML ÃÖÀûÈ­ °¡´É¼º Á¶»çÈÄ ÃÖÀûÈ­
ij¸¯ÅÍ ÀͽºÆ÷Æ®½Ã ¿ùµå °ª ´ë½Å ·ÎÄà °ª »ç¿ëÇϵµ·Ï º¯°æ °¡´ÉÇÑÁö Á¡°Ë
¼ÎÀÌ´õ¿¡ ¶óÀÌÆà Á¤º¸ Ãß°¡
±âŸ µîµî~~~~~~

½ÇÇà È­¸éÀÌ´Ù. ¿¹Á¦´Â ÇýÁö¿øÀÇ ±èÁ¾¹Î´ÔÀÇ 3dsMax Game DesignÀÇ ¿¹Á¦¸¦ ÀÌ¿ëÇÏ¿´´Ù.  À̹ÌÁö´Â °È°í ÀÖ´Â ¸ð½ÀÀÌ´Ù. ¾ÆÁ÷ ¼ÎÀÌ´õ¿¡ ¶óÀÌÆà Á¤º¸´Â µé¾î°¡ ÀÖÁö ¾Ê´Ù.

¸Æ½º Ç÷¯±×ÀÎ : maxProject_texture.zip
¸Æ½º ºä¾î: viewer_texture.zip