📄 chgrstrm.cpp
字号:
}
if ( GetNextStreamMgr() )
{
GetNextStreamMgr()->DestroyStream( requestData, pStream, iReason );
}
}
/////////////////////////////////////////////////////////////////////////////////////
/////////// Implementation of ChGrTextureHandler
void ChGraphicStreamManager::LockDecode()
{
if ( m_iSysType == CH_SYS_WINNT || m_iSysType == CH_SYS_WIN95 )
{
::EnterCriticalSection( &m_syncDecode );
}
}
void ChGraphicStreamManager::UnlockDecode()
{
if ( m_iSysType == CH_SYS_WINNT || m_iSysType == CH_SYS_WIN95 )
{
::LeaveCriticalSection( &m_syncDecode );
}
}
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
/*----------------------------------------------------------------------------
ChVisitFindRLImage class
----------------------------------------------------------------------------*/
class ChVisitFindRLImage : public ChVisitor2<string, ChRLImage*>
{
public:
ChVisitFindRLImage( ChRLImage* pImage ) : m_pRLImage( pImage )
{}
bool Visit( const string& strKey, const pChRLImage& pRLImage );
public :
string m_strKey;
ChRLImage* m_pRLImage;
};
bool ChVisitFindRLImage::Visit( const string& strKey, const pChRLImage& pRLImage )
{
if ( pRLImage == m_pRLImage )
{
m_strKey = strKey;
return false;
}
return true;
}
CH_GLOBAL_CALLBACK( void )
ChRLImageDestroyCallback( void* pData, ChRLImage* pImage )
{
ChGraphicStreamManager* pGrMgr = (ChGraphicStreamManager*)pData;
ChVisitFindRLImage findImage( pImage );
pGrMgr->LockDecode();
// Find if this image is in our cache
pGrMgr->GetImageCache().Infix( findImage );
if ( !findImage.m_strKey.IsEmpty() )
{
pGrMgr->GetImageCache().Delete( findImage.m_strKey );
//TRACE1( "ChRLImageDestroyCallback : Deleting image %s\n", LPCSTR( findImage.m_strKey ) );
}
else
{
TRACE( "ChRLImageDestroyCallback : Image not in cache !!!\n" );
}
pGrMgr->UnlockDecode();
}
ChRLImage* ChGraphicStreamManager::GetCachedImage( const string& strURL )
{
LockDecode();
ChRLImage** ppCache = m_imagCache.Find( strURL );
ChRLImage* pRLImage = 0;
if ( ppCache && *ppCache )
{
pRLImage = *ppCache;
pRLImage->Use();
}
UnlockDecode();
return pRLImage;
}
#endif // (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void ChGraphicStreamManager::LoadTexture( int iMimeType, pChHTTPStream pStream,
ChMazeTextureHTTPReq *pReq )
{
chuint uOption = pReq->GetOption() ? pReq->GetOption() : ChMazeTextureHTTPReq::textureAutoSize;
chuint32 luChromaClr = 0;
#if defined(CH_USE_3DR)
ChDib* pDib = 0;
ChTextureHandle pData = 0;
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
ChRLImage *pData = 0;
#endif
if( pReq->GetPage() != pReq->GetView()->GetCurrentPage() )
{ // We have already moved to a different page, discard the request
delete pReq;
return;
}
if ( pReq->GetTextureNode()->GetUsage() <= 1 )
{ // The node is no longer used, discard the request
delete pReq;
return;
}
// Enter critical section : This is done for 2 reasons
// 1) Serialze decode so that threads don't take up all the CPU
// 2) ChDib::SetSize needs to serialzed
LockDecode();
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
ChRLImage** ppCache = 0;
// cache only autosized images
if ( !(uOption & ChMazeTextureHTTPReq::textureKeepSize) )
{
ppCache = m_imagCache.Find( pStream->GetURL() );
}
if ( ppCache && *ppCache )
{
TRACE( "Using cached image\n" );
pData = *ppCache;
pData->Use();
}
else
#endif
{
TRACE2( "Start decoding texture : %s\nFile : %s\n", LPCSTR(pStream->GetURL() ),
LPCSTR(pStream->GetCacheFilename() ) );
// Update progress
//pReq->GetView()->WriteStatus( PROGRESS_MSG_3 );
switch( iMimeType )
{
case ChHTTPConn::typeGIF:
{
// create the gif object
#if defined(CH_USE_3DR)
pDib = new ChDib;
ChGIFDecoder gifDecoder( pDib );
// Load the GIF file
if ( gifDecoder.Load( pStream->GetCacheFilename(), ChDib::load8Bit ) )
{
if ( pGIF->IsTransparent() )
{
uOption |= ChMazeTextureHTTPReq::textureChromaKey;
luChromaClr = pDib->GetTransparentColor();
}
}
else
{
delete pDib;
pDib = 0;
}
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
pData = new ChRLImage( false, uOption );
ASSERT( pData );
ChGifDecoder gifDecoder( pData );
// Load the GIF file
if ( !gifDecoder.Load( pStream->GetCacheFilename(), ChImageDecoder::load8Bit ) )
{
pData->Release();
pData = 0;
}
#endif
break;
}
case ChHTTPConn::typeJPEG:
{
#if defined(CH_USE_3DR)
pDib = new ChDib;
ChJPEG jpegDecoder( pDib );
// Load the GIF file
if ( !jpegDecoder.Load( pStream->GetCacheFilename(), ChImageDecoder::load24Bit ) )
{
delete pDib;
pDib = 0;
}
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
pData = new ChRLImage( false, uOption );
ASSERT( pData );
ChJPEG jpegDecoder( pData );
// Load the GIF file
if ( !jpegDecoder.Load( pStream->GetCacheFilename(), ChImageDecoder::load24Bit ) )
{
pData->Release();
pData = 0;
}
#endif
break;
}
case ChHTTPConn::typeBMP :
{
#if defined(CH_USE_3DR)
pData = G3dLoadTexture(pReq->GetView()->GetGC(), LPCTSTR(pStream->GetCacheFilename()) );
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
ChDib* pDib = 0;
pDib = new ChDib;
ChDibDecoder dibDecoder( pDib );
// Load the GIF file
if ( !dibDecoder.Load( pStream->GetCacheFilename() ) )
{
delete pDib;
pDib = 0;
}
else
{
pData = new ChRLImage( pDib, false, uOption );
delete pDib;
pDib = 0;
}
#endif
break;
}
default :
{ // this unknown type
break;
}
}
#if defined(CH_USE_3DR)
// Decoding is expensive, check if the page is still valid
if ( pDib )
{
if( pReq->GetPage() == pReq->GetView()->GetCurrentPage() )
{
if ( pData == 0 && pDib )
{
pData = pReq->GetView()->GetRenderContext()->LoadDIBTexture( pDib, luChromaClr, uOption );
}
}
delete pDib;
}
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
if ( pData )
{
if( pReq->GetPage() == pReq->GetView()->GetCurrentPage() )
{
pData->SetDestroyCallback( ChRLImageDestroyCallback, this );
// Add it to our cache list
ChRLImage** ppCache = m_imagCache.Find( pStream->GetURL() );
if ( ppCache && *ppCache )
{
ASSERT( 0 );
}
m_imagCache.Insert( pStream->GetURL(), pData );
}
else
{ // We no longer need this
pData->Release();
}
}
#endif
TRACE( "End decoding texture\n" );
}
// Leave the critical section
UnlockDecode();
if ( pData )
{
// load the texture
pReq->SetTextureHandle( pData );
if( !pReq->GetView()->PostMessage( WM_VRML_LOAD_TEXTURE, 0, (LPARAM)pReq ) )
{
delete pReq;
}
//pReq->Load(pStream->GetCacheFilename(), (void*)pData );
}
else
{
delete pReq;
}
// Update progress
//pReq->GetView()->WriteStatus( PROGRESS_MSG_0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -