DragonNest/Client/EtUITool/GenTexture.cpp
2024-12-19 09:48:26 +08:00

355 lines
9.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
{
return false;
}
}
if( nSameTexIndex == -1 )
{
vecTexLayout[ i ] = CurEmptySpace;
}
else
{
vecTexLayout[ i ] = vecTexLayout[ nSameTexIndex ];
}
}
int nMaxY = 0;
// <20><> <20>Ʒ<EFBFBD> üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// Height<68><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾƼ<CABE> 50x29¥<39><C2A5> 2<><32><EFBFBD><EFBFBD> 64x64<36><34> <20>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ϴµ<CFB4>, 64x32<33>ؽ<EFBFBD>ó<EFBFBD><C3B3> <20>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD>.
//for( i = 0; i < ( int )vecEmptySpace.size(); i++ )
//{
// if( vecEmptySpace[ i ].nY > nMaxY )
// {
// nMaxY = vecEmptySpace[ i ].nY;
// }
//}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵǼ<C8B5> <20>ٷ<EFBFBD> Ŀ<><C4BF><EFBFBD>ϱ<EFBFBD> <20><> <20>׷<EFBFBD><D7B7><EFBFBD>. -> <20>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF>Ѱ<EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> Ŀ<><C4BF>.
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;
// <20>̷<EFBFBD><CCB7><EFBFBD> <20>ϸ<EFBFBD> LayoutView<65><77><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>Ϲ<EFBFBD> <20><><EFBFBD>̾<EFBFBD><CCBE>α׿<CEB1><D7BF><EFBFBD><EFBFBD><EFBFBD>,
// TemplateView<65><77><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD>ø<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD> <20><><EFBFBD>̾<EFBFBD><CCBE>α׿<CEB1><D7BF><EFBFBD><EFBFBD><EFBFBD>, <20>ؽ<EFBFBD>ó<EFBFBD><C3B3> <20>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
// <20><><EFBFBD>̾<EFBFBD><CCBE>α׸<CEB1><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>ó<EFBFBD><C3B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD>ϱ<CFB1><E2B6A7><EFBFBD><EFBFBD>, <20>̰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> <20><>.
// (<28><EFBFBD><ECBCB1> <20>ؿܶ<D8BF><DCB6><EFBFBD><EFBFBD><EFBFBD> Ŀ<><C4BF> <20>Ұ<EFBFBD>)
//if( bUseTemplateUVCoord == false ) // <20><><EFBFBD><EFBFBD>
// 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 )
{
// <20><><EFBFBD>ø<EFBFBD> <20>ؽ<EFBFBD>ó<EFBFBD><C3B3> <20><><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD> <20>ؽ<EFBFBD>ó <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>ó<EFBFBD><C3B3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20>׳<EFBFBD> <20>н<EFBFBD><D0BD>Ѵ<EFBFBD>.
}
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;
}