#include "Stdafx.h" #include "GenTexture.h" #include "UIToolTemplate.h" #ifdef _DEBUG #define new DEBUG_NEW #endif struct STemplateTexture { EtTextureHandle hTexture; int nIndex1; int nIndex2; SUICoord UVCoord; }; bool TemplateTextureSortFunc( STemplateTexture Obj1, STemplateTexture Obj2 ) { int nWidth1 = 0, nWidth2 = 0, nHeight1 = 0, nHeight2 = 0; if( Obj1.hTexture ) { nWidth1 = Obj1.hTexture->Width(); nHeight1 = Obj1.hTexture->Height(); } if( Obj2.hTexture ) { nWidth2 = Obj2.hTexture->Width(); nHeight2 = Obj2.hTexture->Height(); } if( nWidth1 > nWidth2 ) { return true; } else if( nWidth1 == nWidth2 ) { if( nHeight1 > nHeight2 ) { return true; } } return false; } bool EmptySpaceSortFunc( SEmptySpaceTexGen Obj1, SEmptySpaceTexGen Obj2 ) { if( Obj1.GetSpace() < Obj2.GetSpace() ) { return true; } return false; } bool ArrangeTexture( std::vector< STemplateTexture > &vecTemplateTexture, std::vector< SEmptySpaceTexGen > &vecTexLayout, int &nWidth, int &nHeight ) { int i, j; std::vector< SEmptySpaceTexGen > vecEmptySpace; SEmptySpaceTexGen CurEmptySpace; CurEmptySpace.Set( 0, 0, nWidth, nHeight ); vecEmptySpace.push_back( CurEmptySpace ); vecTexLayout.resize( vecTemplateTexture.size() ); for( i = 0; i < ( int )vecTemplateTexture.size(); i++ ) { int nSameTexIndex; int nTexWidth, nTexHeight; if( ( !vecTemplateTexture[ i ].hTexture ) || ( vecTemplateTexture[ i ].hTexture->GetTexturePtr() == NULL ) ) { SEmptySpaceTexGen TempEmptySpace; TempEmptySpace.Set( 0, 0, 0, 0 ); vecTexLayout[ i ] = TempEmptySpace; continue; } nSameTexIndex = -1; for( j = 0; j < i; j++ ) { if( vecTemplateTexture[ i ].hTexture == vecTemplateTexture[ j ].hTexture ) { nSameTexIndex = j; } } if( nSameTexIndex == -1 ) { float fBestSpaceRatio = 0.0f; int nBestFitIndex = -1; nTexWidth = vecTemplateTexture[ i ].hTexture->Width() + 2; nTexHeight = vecTemplateTexture[ i ].hTexture->Height() + 2; for( j = 0; j < ( int )vecEmptySpace.size(); j++ ) { if( ( nTexWidth <= vecEmptySpace[ j ].nWidth ) && ( nTexHeight <= vecEmptySpace[ j ].nHeight ) ) { float fRatio; fRatio = nTexWidth * nTexHeight / ( float )vecEmptySpace[ j ].nWidth * vecEmptySpace[ j ].nHeight; if( fRatio > fBestSpaceRatio ) { fRatio = fBestSpaceRatio; nBestFitIndex = j; } } } if( nBestFitIndex != -1 ) { SEmptySpaceTexGen Temp1, Temp2; int nModWidth, nModHeight; nModWidth = vecEmptySpace[ nBestFitIndex ].nWidth - nTexWidth; nModHeight = vecEmptySpace[ nBestFitIndex ].nHeight - nTexHeight; if( nModWidth >= nModHeight ) { Temp1.nX = vecEmptySpace[ nBestFitIndex ].nX + nTexWidth; Temp1.nWidth = vecEmptySpace[ nBestFitIndex ].nWidth - nTexWidth; Temp1.nY = vecEmptySpace[ nBestFitIndex ].nY; Temp1.nHeight = vecEmptySpace[ nBestFitIndex ].nHeight; Temp2.nX = vecEmptySpace[ nBestFitIndex ].nX; Temp2.nWidth = nTexWidth; Temp2.nY = vecEmptySpace[ nBestFitIndex ].nY + nTexHeight; Temp2.nHeight = vecEmptySpace[ nBestFitIndex ].nHeight - nTexHeight; } else { Temp1.nX = vecEmptySpace[ nBestFitIndex ].nX + nTexWidth; Temp1.nWidth = vecEmptySpace[ nBestFitIndex ].nWidth - nTexWidth; Temp1.nY = vecEmptySpace[ nBestFitIndex ].nY; Temp1.nHeight = nTexHeight; Temp2.nX = vecEmptySpace[ nBestFitIndex ].nX; Temp2.nWidth = vecEmptySpace[ nBestFitIndex ].nWidth; Temp2.nY = vecEmptySpace[ nBestFitIndex ].nY + nTexHeight; Temp2.nHeight = vecEmptySpace[ nBestFitIndex ].nHeight - nTexHeight; } CurEmptySpace = vecEmptySpace[ nBestFitIndex ]; vecEmptySpace.erase( vecEmptySpace.begin() + nBestFitIndex ); if( ( Temp1.nWidth > 2 ) && ( Temp1.nHeight > 2 ) ) { vecEmptySpace.push_back( Temp1 ); } if( ( Temp2.nWidth > 2 ) && ( Temp2.nHeight > 2 ) ) { vecEmptySpace.push_back( Temp2 ); } std::sort( vecEmptySpace.begin(), vecEmptySpace.end(), EmptySpaceSortFunc ); } else // ºó°ø°£ ¾ø´Ù.. ¸®ÅÏÇÏÀÚ.. { return false; } } if( nSameTexIndex == -1 ) { vecTexLayout[ i ] = CurEmptySpace; } else { vecTexLayout[ i ] = vecTexLayout[ nSameTexIndex ]; } } int nMaxY = 0; // ÀÌ ¾Æ·¡ üũ¿¡ ¹ö±× ÀÖÀ½. // Height¸¦ °í·ÁÇÏÁö ¾Ê¾Æ¼­ 50x29Â¥¸® 2°³¸¦ 64x64¿¡ ³Ö¾î¾ßÇϴµ¥, 64x32ÅØ½ºÃ³·Î Àß¶ó¹ö¸². //for( i = 0; i < ( int )vecEmptySpace.size(); i++ ) //{ // if( vecEmptySpace[ i ].nY > nMaxY ) // { // nMaxY = vecEmptySpace[ i ].nY; // } //} // °ËÁõÀÌ Á¦´ë·Î ¾ÈµÇ¼­ ¹Ù·Î Ä¿¹ÔÇϱâ Á» ±×·¸´Ù. -> ¾Æ¹«·¡µµ ÇÊ¿äÇѰа°¾Æ¼­ Ä¿¹Ô. for( i = 0; i < ( int )vecTemplateTexture.size(); i++ ) { if( vecTemplateTexture[ i ].hTexture ) { int nTexHeight = vecTemplateTexture[ i ].hTexture->Height() + 2; if( vecTexLayout[ i ].nY + nTexHeight > nMaxY ) { nMaxY = vecTexLayout[ i ].nY + nTexHeight; } } } if( nMaxY != 0 ) { while( nHeight / 2 >= nMaxY ) { nHeight /= 2; if( nHeight == 0 ) { return true; } } } return true; } int g_anOffsetX[] = { -1, 1, -1, 1, -1, 1, 0, 0, 0 }; int g_anOffsetY[] = { -1, -1, 1, 1, 0, 0, -1, 1, 0 }; void MakeTexture( EtTextureHandle hArrangeTexture, std::vector< CUIToolTemplate * > &vecToolTemplate, std::vector< STemplateTexture > &vecTemplateTexture, std::vector< SEmptySpaceTexGen > &vecTexLayout, int nWidth, int nHeight, bool bUseTemplateUVCoord ) { int i, j; for( i = 0; i < ( int )vecTemplateTexture.size(); i++ ) { if( vecTexLayout[ i ].nWidth == 0 ) { SUICoord TempCoord; memset( &TempCoord, 0, sizeof( SUICoord ) ); if( bUseTemplateUVCoord ) vecToolTemplate[ vecTemplateTexture[ i ].nIndex1 ]->m_Template.m_vecElement[ vecTemplateTexture[ i ].nIndex2 ].TemplateUVCoord = TempCoord; else vecToolTemplate[ vecTemplateTexture[ i ].nIndex1 ]->m_Template.m_vecElement[ vecTemplateTexture[ i ].nIndex2 ].UVCoord = TempCoord; continue; } LPDIRECT3DSURFACE9 pTargetSurface, pSourceSurface; RECT DestRect, TempRect; int nTexWidth = vecTemplateTexture[ i ].hTexture->Width() + 2; int nTexHeight = vecTemplateTexture[ i ].hTexture->Height() + 2; DestRect.left = vecTexLayout[ i ].nX + 1; DestRect.right = DestRect.left + ( nTexWidth - 2 ); DestRect.top = vecTexLayout[ i ].nY + 1; DestRect.bottom = DestRect.top + ( nTexHeight - 2 ); int nIndex1, nIndex2; SUICoord UVCoord; UVCoord.fX = ( vecTexLayout[ i ].nX + 1 ) / ( float )nWidth; UVCoord.fY = ( vecTexLayout[ i ].nY + 1 ) / ( float )nHeight; UVCoord.fWidth = ( nTexWidth - 2 ) / ( float )nWidth; UVCoord.fHeight = ( nTexHeight - 2 ) / ( float )nHeight; nIndex1 = vecTemplateTexture[ i ].nIndex1; nIndex2 = vecTemplateTexture[ i ].nIndex2; if( bUseTemplateUVCoord ) vecToolTemplate[ nIndex1 ]->m_Template.m_vecElement[ nIndex2 ].TemplateUVCoord = UVCoord; else vecToolTemplate[ nIndex1 ]->m_Template.m_vecElement[ nIndex2 ].UVCoord = UVCoord; vecTemplateTexture[ i ].UVCoord = UVCoord; pTargetSurface = hArrangeTexture->GetSurfaceLevel(); pSourceSurface = vecTemplateTexture[ i ].hTexture->GetSurfaceLevel(); for( j = 0; j < 9; j++ ) { TempRect = DestRect; OffsetRect( &TempRect, g_anOffsetX[ j ], g_anOffsetY[ j ] ); D3DXLoadSurfaceFromSurface( pTargetSurface, NULL, &TempRect, pSourceSurface, NULL, NULL, D3DX_FILTER_NONE, 0 ); } } } EtTextureHandle GenerateTexture( std::vector< CUIToolTemplate * > &vecToolTemplate, bool bUseTemplateUVCoord ) { int i, j, nTotalSpace, nReqWidth, nReqHeight; EtTextureHandle hTexture, hGenerateTexture; std::vector< STemplateTexture > vecTemplateTexture; // ÀÌ·¸°Ô Çϸé LayoutView¿¡¼­ »ç¿ëÇÏ´Â ÀÏ¹Ý ´ÙÀ̾ó·Î±×¿¡¼­µµ, // TemplateView¿¡¼­ »ç¿ëÇÏ´Â ÅÛÇø´ º¸¿©ÁÖ±â¿ë ´ÙÀ̾ó·Î±×¿¡¼­µµ, ÅØ½ºÃ³¸¦ ¾È¸¸µé°Ô µÈ´Ù. // ´ÙÀ̾ó·Î±×¸¶´Ù »ý¼ºµÈ ÅØ½ºÃ³°¡ ¾øÀ¸¸é ÀúÀå ÀÚü¸¦ ¾ÈÇϱ⶧¹®¿¡, À̰ŠÇÑÁÙÀÌ¸é ³¡. // (¿ì¼±Àº ÇØ¿Ü¶§¹®¿¡ Ä¿¹Ô ºÒ°¡) //if( bUseTemplateUVCoord == false ) // Áø¼Ö // return hGenerateTexture; nTotalSpace = 0; for( i = 0; i < ( int )vecToolTemplate.size(); i++ ) { for( j = 0; j < ( int )vecToolTemplate[ i ]->m_vecTextureName.size(); j++ ) { STemplateTexture TemplateTexture; TemplateTexture.hTexture = LoadResource( vecToolTemplate[ i ]->m_vecTextureName[ j ].c_str(), RT_TEXTURE ); if( TemplateTexture.hTexture ) { nTotalSpace += ( TemplateTexture.hTexture->Width() + 2 ) * ( TemplateTexture.hTexture->Height() + 2 ); } TemplateTexture.nIndex1 = i; TemplateTexture.nIndex2 = j; vecTemplateTexture.push_back( TemplateTexture ); } } nReqWidth = 2; nReqHeight = 2; while( nReqWidth * nReqHeight < nTotalSpace ) { if( nReqWidth == nReqHeight ) { nReqWidth *= 2; } else { nReqHeight *= 2; } } std::sort( vecTemplateTexture.begin(), vecTemplateTexture.end(), TemplateTextureSortFunc ); std::vector< SEmptySpaceTexGen > vecTexLayout; while( 1 ) { if( ArrangeTexture( vecTemplateTexture, vecTexLayout, nReqWidth, nReqHeight ) ) { break; } if( nReqWidth == nReqHeight ) { nReqWidth *= 2; } else { nReqHeight *= 2; } } D3DLOCKED_RECT LockedRect; if( bUseTemplateUVCoord && nReqWidth == 2 && nReqHeight == 2 ) { // ÅÛÇø´ ÅØ½ºÃ³¸¦ »ý¼ºÇÒ¶§ ÅØ½ºÃ³ »ý¼ºÇÒÇÊ¿ä ¾øÀ¸¸é ÀÛÀº ÅØ½ºÃ³µµ »ý¼ºÇÏÁö ¾Ê°í ±×³É ÆÐ½ºÇÑ´Ù. } else if( nReqWidth * nReqHeight == 0 ) { hGenerateTexture = CEtTexture::CreateNormalTexture( 16, 16, FMT_A8R8G8B8, USAGE_DYNAMIC, POOL_DEFAULT ); } else { hGenerateTexture = CEtTexture::CreateNormalTexture( nReqWidth, nReqHeight, FMT_A8R8G8B8, USAGE_DYNAMIC, POOL_DEFAULT ); ( ( EtTexture * )hGenerateTexture->GetTexturePtr() )->LockRect( 0, &LockedRect, NULL, D3DLOCK_DISCARD ); memset( LockedRect.pBits, 0, hGenerateTexture->Height() * LockedRect.Pitch ); ( ( EtTexture * )hGenerateTexture->GetTexturePtr() )->UnlockRect( 0 ); MakeTexture( hGenerateTexture, vecToolTemplate, vecTemplateTexture, vecTexLayout, nReqWidth, nReqHeight, bUseTemplateUVCoord ); } for( i = 0; i < ( int )vecTemplateTexture.size(); i++ ) { SAFE_RELEASE_SPTR( vecTemplateTexture[ i ].hTexture ); } CEtResource::FlushWaitDelete(); return hGenerateTexture; }