187 lines
7.8 KiB
C
187 lines
7.8 KiB
C
/*
|
|
=======================================================================================
|
|
Name : TexCompress.c
|
|
Author : Gliglou Corporation
|
|
Description : compression of textures
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
#include "PvObj_st.h"
|
|
#include "texture.h"
|
|
#include "TEX.h"
|
|
#include "DLLInter.h"
|
|
#include "DLLCaps.h"
|
|
#include "TexArray.h"
|
|
#include "prf.h"
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compress texture width
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lCompressTexturesSizeInX(struct GLI_tdstTexture_ *p_stTexture)
|
|
{
|
|
long lTextureSizeBefore;
|
|
|
|
lTextureSizeBefore = GLI_DRV_lGetTextureSize(p_stTexture);
|
|
p_stTexture -> lWidth >>= 1;
|
|
return ( lTextureSizeBefore - GLI_DRV_lGetTextureSize(p_stTexture));
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compress texture height
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lCompressTexturesSizeInY(struct GLI_tdstTexture_ *p_stTexture)
|
|
{
|
|
long lTextureSizeBefore;
|
|
lTextureSizeBefore = GLI_DRV_lGetTextureSize(p_stTexture);
|
|
p_stTexture -> lHeight >>= 1;
|
|
return ( lTextureSizeBefore - GLI_DRV_lGetTextureSize(p_stTexture));
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compress texture size
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lCompressTextureSize(GLI_tdstTexture *p_stTexture)
|
|
{
|
|
long lTextureSizeBefore;
|
|
|
|
if ( (p_stTexture -> lHeight <= 4) || (p_stTexture -> lWidth <= 4) )
|
|
return 0;
|
|
|
|
lTextureSizeBefore = GLI_DRV_lGetTextureSize(p_stTexture);
|
|
|
|
p_stTexture -> lCompressionCounter ++;
|
|
p_stTexture -> lHeight >>= 1;
|
|
p_stTexture -> lWidth >>= 1;
|
|
|
|
return ( lTextureSizeBefore - GLI_DRV_lGetTextureSize(p_stTexture));
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compute texture compression
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long TEX_lComputeCompression()
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lSizeOfLevel,lSizeAvailable, lTextureCounter;
|
|
long lCounterAntiInfinite, lNbTexLowQuality;
|
|
unsigned long lMaxTextureSize,lIsAcceptNonSquaredTextures;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
lSizeOfLevel = GLI_lComputeTexturesSize();
|
|
/*
|
|
lSizeAvailable = GLI_DRV_lGetHardwareTotalTextureMemorySize( GLI_lGetTextureMode() );
|
|
lMaxTextureSize = GLI_DRV_lGetHardwareMaxTextureSize() ;
|
|
lIsAcceptNonSquaredTextures = GLI_DRV_lIsHardwareAcceptNonSquaredTextures();
|
|
*/
|
|
lSizeAvailable = GLI_g_stCaps.ulTotalTextureMemory;
|
|
lMaxTextureSize = GLI_g_stCaps.ulTextureMaxSize;;
|
|
lIsAcceptNonSquaredTextures = GLI_g_stCaps.ulTextureCaps & GLICAPS_TEX_C_ulSupportNonSquare;
|
|
|
|
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpTextureSize, lSizeOfLevel );
|
|
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpTextureMemorySize, lSizeAvailable );
|
|
/*
|
|
* if hardware doesn't accept non-squared textures squared them
|
|
* and compress texture if hardware size is smaller than texture
|
|
*/
|
|
if (lIsAcceptNonSquaredTextures == 0)
|
|
{
|
|
for (lTextureCounter = 0 ; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter ++)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated)
|
|
continue;
|
|
|
|
/* Make them squared */
|
|
while (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lWidth > gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lHeight)
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInX(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
|
|
while (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lWidth < gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lHeight)
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInY(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
|
|
/* then compress too large textures */
|
|
while ( gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lWidth > lMaxTextureSize )
|
|
{
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInX(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInY(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Compress Height */
|
|
for (lTextureCounter = 0 ; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter ++)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated)
|
|
continue;
|
|
|
|
while (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lWidth > lMaxTextureSize)
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInX(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
|
|
}
|
|
/* Compress Width */
|
|
for (lTextureCounter = 0 ; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter ++)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated)
|
|
continue;
|
|
|
|
while (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]->lHeight > lMaxTextureSize)
|
|
lSizeOfLevel -= GLI_lCompressTexturesSizeInY(gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);
|
|
}
|
|
}
|
|
|
|
if (lSizeAvailable == -1) /* Case of the reality engine */
|
|
return 0;
|
|
|
|
lCounterAntiInfinite = 10;
|
|
lNbTexLowQuality = 1;
|
|
while ((lSizeOfLevel > lSizeAvailable) && (lCounterAntiInfinite-- > 0))
|
|
{
|
|
if( lNbTexLowQuality )
|
|
{
|
|
lNbTexLowQuality--;
|
|
/* First compress the low textures */
|
|
for (lTextureCounter =GLI_C_lNBMaxOfTextures - 1 ; (lTextureCounter >= 0) && (lSizeOfLevel > lSizeAvailable); lTextureCounter --)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated)
|
|
continue;
|
|
|
|
if (TEX_ucGetTextureQualityLevel(gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]) != TEX_C_QNORMAL)
|
|
{
|
|
if (TEX_ucGetTextureQualityLevel(gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]) != TEX_C_QHIGH) /* = LOW quality*/
|
|
/*if (GLI_M_bNotAnLODLevel(gs_aDEFTableOfTextureMemoryChannels[lTextureCounter]))*/
|
|
{
|
|
lNbTexLowQuality++;
|
|
lSizeOfLevel -= GLI_lCompressTextureSize(gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ]);
|
|
if (lSizeOfLevel < lSizeAvailable)
|
|
continue;
|
|
lSizeOfLevel -= GLI_lCompressTextureSize(gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* then compress Normal textures;*/
|
|
for (lTextureCounter =0 ; (lTextureCounter < GLI_C_lNBMaxOfTextures) && (lSizeOfLevel > lSizeAvailable); lTextureCounter ++)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated)
|
|
continue;
|
|
|
|
if (TEX_ucGetTextureQualityLevel(gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]) == TEX_C_QNORMAL)
|
|
lSizeOfLevel -= GLI_lCompressTextureSize(gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ]);
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|