This commit is contained in:
Glenn Maynard
2005-06-24 02:19:04 +00:00
parent ad9d34b45c
commit 91e88be084
+64 -76
View File
@@ -13,7 +13,7 @@
#include "RageSurfaceUtils_Dither.h"
#include "RageSurface_Load.h"
static void GetResolutionFromFileName( CString sPath, int &Width, int &Height )
static void GetResolutionFromFileName( CString sPath, int &iWidth, int &iHeight )
{
/* Match:
* Foo (res 512x128).png
@@ -21,20 +21,19 @@ static void GetResolutionFromFileName( CString sPath, int &Width, int &Height )
* Foo (dither, res 512x128).png
*
* Be careful that this doesn't get mixed up with frame dimensions. */
static Regex re("\\([^\\)]*res ([0-9]+)x([0-9]+).*\\)");
static Regex re( "\\([^\\)]*res ([0-9]+)x([0-9]+).*\\)" );
vector<CString> matches;
if(!re.Compare(sPath, matches))
vector<CString> asMatches;
if( !re.Compare(sPath, asMatches) )
return;
Width = atoi(matches[0].c_str());
Height = atoi(matches[1].c_str());
iWidth = atoi( asMatches[0].c_str() );
iHeight = atoi( asMatches[1].c_str() );
}
RageBitmapTexture::RageBitmapTexture( RageTextureID name ) :
RageTexture( name )
{
// LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
Create();
}
@@ -65,27 +64,26 @@ void RageBitmapTexture::Create()
ASSERT( actualID.filename != "" );
/* Create (and return) a surface ready to be loaded to OpenGL */
/* Load the image into a RageSurface. */
CString error;
RageSurface *img = RageSurfaceUtils::LoadFile( actualID.filename, error );
RageSurface *pImg = RageSurfaceUtils::LoadFile( actualID.filename, error );
/* Tolerate corrupt/unknown images. */
if( img == NULL )
if( pImg == NULL )
{
CString sWarning = ssprintf( "RageBitmapTexture: Couldn't load %s: %s", actualID.filename.c_str(), error.c_str() );
Dialog::OK( sWarning );
img = RageSurfaceUtils::MakeDummySurface( 64, 64 );
ASSERT( img != NULL );
pImg = RageSurfaceUtils::MakeDummySurface( 64, 64 );
ASSERT( pImg != NULL );
}
if( actualID.bHotPinkColorKey )
RageSurfaceUtils::ApplyHotPinkColorKey( img );
RageSurfaceUtils::ApplyHotPinkColorKey( pImg );
{
/* Do this after setting the color key for paletted images; it'll also return
* TRAIT_NO_TRANSPARENCY if the color key is never used. */
int traits = RageSurfaceUtils::FindSurfaceTraits(img);
int traits = RageSurfaceUtils::FindSurfaceTraits( pImg );
if( traits & RageSurfaceUtils::TRAIT_NO_TRANSPARENCY )
actualID.iAlphaBits = 0;
else if( traits & RageSurfaceUtils::TRAIT_BOOL_TRANSPARENCY )
@@ -93,37 +91,37 @@ void RageBitmapTexture::Create()
}
// look in the file name for a format hints
CString HintString = GetID().filename + actualID.AdditionalTextureHints;
HintString.MakeLower();
CString sHintString = GetID().filename + actualID.AdditionalTextureHints;
sHintString.MakeLower();
if( HintString.Find("32bpp") != -1 ) actualID.iColorDepth = 32;
else if( HintString.Find("16bpp") != -1 ) actualID.iColorDepth = 16;
if( HintString.Find("dither") != -1 ) actualID.bDither = true;
if( HintString.Find("stretch") != -1 ) actualID.bStretch = true;
if( HintString.Find("mipmaps") != -1 ) actualID.bMipMaps = true;
if( HintString.Find("nomipmaps") != -1 ) actualID.bMipMaps = false; // check for "nomipmaps" after "mipmaps"
if( sHintString.Find("32bpp") != -1 ) actualID.iColorDepth = 32;
else if( sHintString.Find("16bpp") != -1 ) actualID.iColorDepth = 16;
if( sHintString.Find("dither") != -1 ) actualID.bDither = true;
if( sHintString.Find("stretch") != -1 ) actualID.bStretch = true;
if( sHintString.Find("mipmaps") != -1 ) actualID.bMipMaps = true;
if( sHintString.Find("nomipmaps") != -1 ) actualID.bMipMaps = false; // check for "nomipmaps" after "mipmaps"
/* If the image is marked grayscale, then use all bits not used for alpha
* for the intensity. This way, if an image has no alpha, you get an 8-bit
* grayscale; if it only has boolean transparency, you get a 7-bit grayscale. */
if( HintString.Find("grayscale") != -1 ) actualID.iGrayscaleBits = 8-actualID.iAlphaBits;
if( sHintString.Find("grayscale") != -1 ) actualID.iGrayscaleBits = 8-actualID.iAlphaBits;
/* This indicates that the only component in the texture is alpha; assume all
* color is white. */
if( HintString.Find("alphamap") != -1 ) actualID.iGrayscaleBits = 0;
if( sHintString.Find("alphamap") != -1 ) actualID.iGrayscaleBits = 0;
/* No iGrayscaleBits for images that are already paletted. We don't support
* that; and that hint is intended for use on images that are already grayscale,
* it's not intended to change a color image into a grayscale image. */
if( actualID.iGrayscaleBits != -1 && img->format->BitsPerPixel == 8 )
if( actualID.iGrayscaleBits != -1 && pImg->format->BitsPerPixel == 8 )
actualID.iGrayscaleBits = -1;
/* Cap the max texture size to the hardware max. */
actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() );
/* Save information about the source. */
m_iSourceWidth = img->w;
m_iSourceHeight = img->h;
m_iSourceWidth = pImg->w;
m_iSourceHeight = pImg->h;
/* image size cannot exceed max size */
m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize );
@@ -134,17 +132,17 @@ void RageBitmapTexture::Create()
m_iTextureHeight = power_of_two(m_iImageHeight);
/* If we're under 8x8, increase it, to avoid filtering problems on odd hardware. */
if(m_iTextureWidth < 8 || m_iTextureHeight < 8)
if( m_iTextureWidth < 8 || m_iTextureHeight < 8 )
{
actualID.bStretch = true;
m_iTextureWidth = max(8, m_iTextureWidth);
m_iTextureHeight = max(8, m_iTextureHeight);
m_iTextureWidth = max( 8, m_iTextureWidth );
m_iTextureHeight = max( 8, m_iTextureHeight );
}
ASSERT( m_iTextureWidth <= actualID.iMaxSize );
ASSERT( m_iTextureHeight <= actualID.iMaxSize );
if(actualID.bStretch)
if( actualID.bStretch )
{
/* The hints asked for the image to be stretched to the texture size,
* probably for tiling. */
@@ -152,23 +150,22 @@ void RageBitmapTexture::Create()
m_iImageHeight = m_iTextureHeight;
}
if( img->w != m_iImageWidth || img->h != m_iImageHeight )
RageSurfaceUtils::Zoom( img, m_iImageWidth, m_iImageHeight );
// Format of the image that we will pass to OpenGL and that we want OpenGL to use
RageDisplay::PixelFormat pixfmt;
if( pImg->w != m_iImageWidth || pImg->h != m_iImageHeight )
RageSurfaceUtils::Zoom( pImg, m_iImageWidth, m_iImageHeight );
if( actualID.iGrayscaleBits != -1 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL) )
{
RageSurface *dst = RageSurfaceUtils::PalettizeToGrayscale( img, actualID.iGrayscaleBits, actualID.iAlphaBits );
RageSurface *pGrayscale = RageSurfaceUtils::PalettizeToGrayscale( pImg, actualID.iGrayscaleBits, actualID.iAlphaBits );
delete img;
img = dst;
delete pImg;
pImg = pGrayscale;
}
/* Figure out which texture format to use. */
// if the source is palleted, load palleted no matter what the prefs
if(img->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL))
/* Figure out which texture format we want the renderer to use. */
RageDisplay::PixelFormat pixfmt;
/* If the source is palleted, always load as paletted if supported. */
if( pImg->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL) )
{
pixfmt = RageDisplay::FMT_PAL;
}
@@ -180,12 +177,13 @@ void RageBitmapTexture::Create()
case 16:
{
/* Bits of alpha in the source: */
int src_alpha_bits = 8 - img->format->Loss[3];
int iSourceAlphaBits = 8 - pImg->format->Loss[3];
/* Don't use more than we were hinted to. */
src_alpha_bits = min( actualID.iAlphaBits, src_alpha_bits );
iSourceAlphaBits = min( actualID.iAlphaBits, iSourceAlphaBits );
switch( src_alpha_bits ) {
switch( iSourceAlphaBits )
{
case 0:
case 1:
pixfmt = RageDisplay::FMT_RGB5A1;
@@ -221,34 +219,24 @@ void RageBitmapTexture::Create()
{
/* Dither down to the destination format. */
const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
RageSurface *dst = CreateSurface( img->w, img->h, pfd->bpp,
RageSurface *dst = CreateSurface( pImg->w, pImg->h, pfd->bpp,
pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );
RageSurfaceUtils::ErrorDiffusionDither( img, dst );
delete img;
img = dst;
RageSurfaceUtils::ErrorDiffusionDither( pImg, dst );
delete pImg;
pImg = dst;
}
/* This needs to be done *after* the final resize, since that resize
* may introduce new alpha bits that need to be set. It needs to be
* done *before* we set up the palette, since it might change it. */
RageSurfaceUtils::FixHiddenAlpha(img);
RageSurfaceUtils::FixHiddenAlpha( pImg );
/* Convert the data to the destination format and dimensions
* required by OpenGL if it's not in it already. */
/* We no longer need to do this; pixfmt and the format of img no longer have
* to match. This means that if we have a paletted image, but the hardware
* doesn't support it, we can leave the data in the smaller paletted format
* and let OpenGL dereference it, as long as nothing else (such as dithering)
* ends up depalettizing it first. We only have to scale it up to the texture
* size, which we won't have to do either if the image size is already a power
* of two. */
// const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
RageSurfaceUtils::ConvertSurface( img, m_iTextureWidth, m_iTextureHeight,
img->fmt.BitsPerPixel, img->fmt.Mask[0], img->fmt.Mask[1], img->fmt.Mask[2], img->fmt.Mask[3] );
// pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );
/* Scale up to the texture size, if needed. */
RageSurfaceUtils::ConvertSurface( pImg, m_iTextureWidth, m_iTextureHeight,
pImg->fmt.BitsPerPixel, pImg->fmt.Mask[0], pImg->fmt.Mask[1], pImg->fmt.Mask[2], pImg->fmt.Mask[3] );
m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img, actualID.bMipMaps );
m_uTexHandle = DISPLAY->CreateTexture( pixfmt, pImg, actualID.bMipMaps );
CreateFrameRects();
@@ -259,7 +247,7 @@ void RageBitmapTexture::Create()
//
bool bRunCheck = true;
// Don't check if the artist intentionally blanked the image by making it very tiny.
// Don't check if the artist intentionally blanked the image by making it very tiny.
if( this->GetSourceWidth()<=2 || this->GetSourceHeight()<=2 )
bRunCheck = false;
@@ -293,23 +281,23 @@ void RageBitmapTexture::Create()
delete img;
delete pImg;
/* See if the apparent "size" is being overridden. */
GetResolutionFromFileName(actualID.filename, m_iSourceWidth, m_iSourceHeight);
GetResolutionFromFileName( actualID.filename, m_iSourceWidth, m_iSourceHeight );
CString props;
props += RageDisplay::PixelFormatToString( pixfmt ) + " ";
if(actualID.iAlphaBits == 0) props += "opaque ";
if(actualID.iAlphaBits == 1) props += "matte ";
if(actualID.bStretch) props += "stretch ";
if(actualID.bDither) props += "dither ";
props.erase(props.size()-1);
CString sProperties;
sProperties += RageDisplay::PixelFormatToString( pixfmt ) + " ";
if( actualID.iAlphaBits == 0 ) sProperties += "opaque ";
if( actualID.iAlphaBits == 1 ) sProperties += "matte ";
if( actualID.bStretch ) sProperties += "stretch ";
if( actualID.bDither ) sProperties += "dither ";
sProperties.erase( sProperties.size()-1 );
LOG->Trace( "RageBitmapTexture: Loaded '%s' (%ux%u); %s, source %d,%d; image %d,%d.",
actualID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
props.c_str(), m_iSourceWidth, m_iSourceHeight,
m_iImageWidth, m_iImageHeight);
sProperties.c_str(), m_iSourceWidth, m_iSourceHeight,
m_iImageWidth, m_iImageHeight );
}
void RageBitmapTexture::Destroy()