Reorganize RageDisplay
Add Direct3D renderer (separate project configuration) Add Xbox project config (doesn't yet compile)
This commit is contained in:
+132
-337
@@ -16,7 +16,7 @@
|
||||
#include "RageLog.h"
|
||||
#include "RageException.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageDisplayInternal.h"
|
||||
#include "RageTypes.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
@@ -27,84 +27,6 @@
|
||||
|
||||
#include "RageTimer.h"
|
||||
|
||||
enum pixfmts {
|
||||
FMT_RGBA8,
|
||||
FMT_RGBA4,
|
||||
FMT_RGB5A1,
|
||||
FMT_PAL,
|
||||
NUM_PIX_FORMATS
|
||||
};
|
||||
|
||||
/* Return true for pixfmts that need to be converted to FMT_RGBA8 for GLDirect
|
||||
* (those with packed pixel data types). */
|
||||
static bool IsPackedPixelFormat(GLenum pixfmt)
|
||||
{
|
||||
return pixfmt == FMT_RGBA4 || pixfmt == FMT_RGB5A1;
|
||||
}
|
||||
|
||||
/* Definitions for various texture formats. We'll probably want RGBA
|
||||
* in OpenGL, not ARGB ... All of these are in local (little) endian;
|
||||
* this may or may not need adjustment for OpenGL. */
|
||||
struct PixFmt_t {
|
||||
int bpp;
|
||||
GLenum internalfmt; /* target format */
|
||||
GLenum format; /* target format */
|
||||
GLenum type; /* data format */
|
||||
unsigned int masks[4];
|
||||
} PixFmtMasks[NUM_PIX_FORMATS] = {
|
||||
/* XXX: GL_UNSIGNED_SHORT_4_4_4_4 is affected by endianness; GL_UNSIGNED_BYTE
|
||||
* is not, but all SDL masks are affected by endianness, so GL_UNSIGNED_BYTE
|
||||
* is reversed. This isn't endian-safe. */
|
||||
{
|
||||
/* B8G8R8A8 */
|
||||
32,
|
||||
GL_RGBA8,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
{ 0x000000FF,
|
||||
0x0000FF00,
|
||||
0x00FF0000,
|
||||
0xFF000000 }
|
||||
}, {
|
||||
/* B4G4R4A4 */
|
||||
16,
|
||||
GL_RGBA4,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_4_4_4_4,
|
||||
{ 0xF000,
|
||||
0x0F00,
|
||||
0x00F0,
|
||||
0x000F },
|
||||
}, {
|
||||
/* B5G5R5A1 */
|
||||
16,
|
||||
GL_RGB5_A1,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_5_5_5_1,
|
||||
{ 0xF800,
|
||||
0x07C0,
|
||||
0x003E,
|
||||
0x0001 },
|
||||
}, {
|
||||
/* Paletted */
|
||||
8,
|
||||
GL_COLOR_INDEX8_EXT,
|
||||
GL_COLOR_INDEX,
|
||||
GL_UNSIGNED_BYTE,
|
||||
{ 0,0,0,0 } /* N/A */
|
||||
}
|
||||
};
|
||||
|
||||
int PixFmtMaskNo(GLenum fmt)
|
||||
{
|
||||
switch(fmt) {
|
||||
case GL_RGBA8: return FMT_RGBA8;
|
||||
case GL_RGBA4: return FMT_RGBA4;
|
||||
case GL_RGB5_A1: return FMT_RGB5A1;
|
||||
default: ASSERT(0); return FMT_RGBA8;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetResolutionFromFileName( CString sPath, int &Width, int &Height )
|
||||
{
|
||||
/* Match:
|
||||
@@ -130,42 +52,33 @@ RageBitmapTexture::RageBitmapTexture( RageTextureID name ) :
|
||||
RageTexture( name )
|
||||
{
|
||||
// LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
|
||||
|
||||
m_uGLTextureID = 0;
|
||||
|
||||
Create(); // sFilePath and prefs are saved by RageTexture()
|
||||
Create();
|
||||
}
|
||||
|
||||
RageBitmapTexture::~RageBitmapTexture()
|
||||
{
|
||||
if(m_uGLTextureID)
|
||||
glDeleteTextures(1,reinterpret_cast<GLuint*>(&m_uGLTextureID));
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void RageBitmapTexture::Reload()
|
||||
{
|
||||
RageTexture::Reload();
|
||||
DISPLAY->SetTexture(0);
|
||||
|
||||
if(m_uGLTextureID)
|
||||
{
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_uGLTextureID));
|
||||
m_uGLTextureID = 0;
|
||||
}
|
||||
|
||||
Destroy();
|
||||
Create();
|
||||
}
|
||||
|
||||
/* 1. Create (and return) a surface ready to be loaded to OpenGL,
|
||||
* 2. Set up m_ActualID, and
|
||||
* 3. Set these texture parameters:
|
||||
* m_iSourceWidth, m_iSourceHeight
|
||||
* m_iTextureWidth, m_iTextureHeight
|
||||
* m_iImageWidth, m_iImageHeight
|
||||
* m_iFramesWide, m_iFramesHigh
|
||||
/*
|
||||
* Each dwMaxSize, dwTextureColorDepth and iAlphaBits are maximums; we may
|
||||
* use less. iAlphaBits must be 0, 1 or 4.
|
||||
*
|
||||
* XXX: change iAlphaBits == 4 to iAlphaBits == 8 to indicate "as much alpha
|
||||
* as needed", since that's what it really is; still only use 4 in 16-bit textures.
|
||||
*
|
||||
* Dither forces dithering when loading 16-bit textures.
|
||||
* Stretch forces the loaded image to fill the texture completely.
|
||||
*/
|
||||
SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
||||
void RageBitmapTexture::Create()
|
||||
{
|
||||
/* Create (and return) a surface ready to be loaded to OpenGL */
|
||||
/* Load the image into an SDL surface. */
|
||||
SDL_Surface *img = IMG_Load(GetFilePath());
|
||||
|
||||
@@ -174,7 +87,7 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
||||
if(img == NULL)
|
||||
RageException::Throw( "RageBitmapTexture: Couldn't load %s: %s", GetFilePath().c_str(), SDL_GetError() );
|
||||
|
||||
if(m_ActualID.bHotPinkColorKey)
|
||||
if(m_ID.bHotPinkColorKey)
|
||||
{
|
||||
/* Annoying: SDL will do a nearest-match on paletted images if
|
||||
* they don't have the color we ask for, so images without HOT PINK
|
||||
@@ -199,79 +112,46 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
||||
* TRAIT_NO_TRANSPARENCY if the color key is never used. */
|
||||
int traits = FindSurfaceTraits(img);
|
||||
if(traits & TRAIT_NO_TRANSPARENCY)
|
||||
m_ActualID.iAlphaBits = 0;
|
||||
m_ID.iAlphaBits = 0;
|
||||
else if(traits & TRAIT_BOOL_TRANSPARENCY)
|
||||
m_ActualID.iAlphaBits = 1;
|
||||
m_ID.iAlphaBits = 1;
|
||||
if(traits & TRAIT_WHITE_ONLY)
|
||||
m_ActualID.iTransparencyOnly = 8;
|
||||
m_ID.iTransparencyOnly = 8;
|
||||
}
|
||||
|
||||
// look in the file name for a format hints
|
||||
CString HintString = GetFilePath();
|
||||
HintString.MakeLower();
|
||||
|
||||
if( HintString.Find("4alphaonly") != -1 ) m_ActualID.iTransparencyOnly = 4;
|
||||
else if( HintString.Find("8alphaonly") != -1 ) m_ActualID.iTransparencyOnly = 8;
|
||||
if( HintString.Find("dither") != -1 ) m_ActualID.bDither = true;
|
||||
if( HintString.Find("4alphaonly") != -1 ) m_ID.iTransparencyOnly = 4;
|
||||
else if( HintString.Find("8alphaonly") != -1 ) m_ID.iTransparencyOnly = 8;
|
||||
if( HintString.Find("dither") != -1 ) m_ID.bDither = true;
|
||||
|
||||
if( m_ActualID.iTransparencyOnly )
|
||||
{
|
||||
/* Treat the image as 32-bit, so we don't lose any alpha precision. */
|
||||
m_ActualID.iColorDepth = 32;
|
||||
}
|
||||
|
||||
GLenum fmtTexture;
|
||||
/* Figure out which texture format to use. */
|
||||
if( m_ActualID.iColorDepth == 16 )
|
||||
{
|
||||
/* Bits of alpha in the source: */
|
||||
int src_alpha_bits = 8 - img->format->Aloss;
|
||||
|
||||
/* No real alpha in paletted input. */
|
||||
if( img->format->BytesPerPixel == 1 )
|
||||
src_alpha_bits = 0;
|
||||
|
||||
/* Colorkeyed input effectively has at least one bit of alpha: */
|
||||
if( img->flags & SDL_SRCCOLORKEY )
|
||||
src_alpha_bits = max( 1, src_alpha_bits );
|
||||
|
||||
/* Don't use more than we were hinted to. */
|
||||
src_alpha_bits = min( m_ActualID.iAlphaBits, src_alpha_bits );
|
||||
|
||||
switch( src_alpha_bits ) {
|
||||
case 0:
|
||||
case 1:
|
||||
fmtTexture = GL_RGB5_A1;
|
||||
break;
|
||||
default:
|
||||
fmtTexture = GL_RGBA4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( m_ActualID.iColorDepth == 32)
|
||||
fmtTexture = GL_RGBA8;
|
||||
else
|
||||
RageException::Throw( "Invalid color depth: %d bits", m_ActualID.iColorDepth );
|
||||
if( m_ID.iTransparencyOnly )
|
||||
m_ID.iColorDepth = 32; /* Treat the image as 32-bit, so we don't lose any alpha precision. */
|
||||
|
||||
/* Cap the max texture size to the hardware max. */
|
||||
m_ActualID.iMaxSize = min( m_ActualID.iMaxSize, DISPLAY->GetMaxTextureSize() );
|
||||
m_ID.iMaxSize = min( m_ID.iMaxSize, DISPLAY->GetMaxTextureSize() );
|
||||
|
||||
/* Save information about the source. */
|
||||
m_iSourceWidth = img->w;
|
||||
m_iSourceHeight = img->h;
|
||||
|
||||
/* See if the apparent "size" is being overridden. */
|
||||
GetResolutionFromFileName(m_ID.filename, m_iSourceWidth, m_iSourceHeight);
|
||||
|
||||
/* image size cannot exceed max size */
|
||||
m_iImageWidth = min( m_iSourceWidth, m_ActualID.iMaxSize );
|
||||
m_iImageHeight = min( m_iSourceHeight, m_ActualID.iMaxSize );
|
||||
m_iImageWidth = min( m_iSourceWidth, m_ID.iMaxSize );
|
||||
m_iImageHeight = min( m_iSourceHeight, m_ID.iMaxSize );
|
||||
|
||||
/* Texture dimensions need to be a power of two; jump to the next. */
|
||||
m_iTextureWidth = power_of_two(m_iImageWidth);
|
||||
m_iTextureHeight = power_of_two(m_iImageHeight);
|
||||
|
||||
ASSERT( m_iTextureWidth <= m_ActualID.iMaxSize );
|
||||
ASSERT( m_iTextureHeight <= m_ActualID.iMaxSize );
|
||||
ASSERT( m_iTextureWidth <= m_ID.iMaxSize );
|
||||
ASSERT( m_iTextureHeight <= m_ID.iMaxSize );
|
||||
|
||||
if(m_ActualID.bStretch)
|
||||
if(m_ID.bStretch)
|
||||
{
|
||||
/* The hints asked for the image to be stretched to the texture size,
|
||||
* probably for tiling. */
|
||||
@@ -279,225 +159,140 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
||||
m_iImageHeight = m_iTextureHeight;
|
||||
}
|
||||
|
||||
/* If the source is larger than the texture, we have to scale it to fit. */
|
||||
if(m_iSourceWidth > m_iImageWidth || m_iSourceHeight > m_iImageHeight)
|
||||
m_ActualID.bStretch = true;
|
||||
|
||||
pixfmt = PixFmtMaskNo(fmtTexture);
|
||||
|
||||
if( m_ActualID.bStretch )
|
||||
if( img->w != m_iImageWidth || img->h != m_iImageHeight )
|
||||
{
|
||||
/* resize currently only does RGBA8888 */
|
||||
int mask = 0;
|
||||
ConvertSDLSurface(img, img->w, img->h, PixFmtMasks[mask].bpp,
|
||||
PixFmtMasks[mask].masks[0], PixFmtMasks[mask].masks[1],
|
||||
PixFmtMasks[mask].masks[2], PixFmtMasks[mask].masks[3]);
|
||||
ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
|
||||
zoomSurface(img, m_iImageWidth, m_iImageHeight );
|
||||
}
|
||||
|
||||
/* See if the apparent "size" is being overridden. */
|
||||
GetResolutionFromFileName(m_ActualID.filename, m_iSourceWidth, m_iSourceHeight);
|
||||
return img;
|
||||
}
|
||||
// Format of the image that we will pass to OpenGL and that we want OpenGL to use
|
||||
PixelFormat pixfmt;
|
||||
|
||||
/*
|
||||
* Each dwMaxSize, dwTextureColorDepth and iAlphaBits are maximums; we may
|
||||
* use less. iAlphaBits must be 0, 1 or 4.
|
||||
*
|
||||
* XXX: change iAlphaBits == 4 to iAlphaBits == 8 to indicate "as much alpha
|
||||
* as needed", since that's what it really is; still only use 4 in 16-bit textures.
|
||||
*
|
||||
* Dither forces dithering when loading 16-bit textures.
|
||||
* Stretch forces the loaded image to fill the texture completely.
|
||||
*/
|
||||
void RageBitmapTexture::Create()
|
||||
{
|
||||
/* This will be set to the pixfmt we should use if we use an RGBA texture. */
|
||||
int desired_rgba_pixfmt;
|
||||
SDL_SaveBMP( img, "testing.bmp" );
|
||||
|
||||
SDL_Surface *img = CreateImg(desired_rgba_pixfmt);
|
||||
if(!m_uGLTextureID)
|
||||
glGenTextures(1, reinterpret_cast<GLuint*>(&m_uGLTextureID));
|
||||
ASSERT(m_uGLTextureID);
|
||||
|
||||
DISPLAY->SetTexture(this);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
/* This is an experiment: some people are seeing skips when the danger
|
||||
* background comes in. One hypothesis: we're loading the danger background,
|
||||
* keeping it in memory without displaying it for several games, it gets
|
||||
* swapped out of texture memory, and then we skip swapping it in.
|
||||
*
|
||||
* It's rather small, so I'm not entirely convinced this is what's happening.
|
||||
* Let's try boosting the texture priority for the danger background and
|
||||
* see if it goes away. If it does, I'll make texture pris a texture hint
|
||||
* (or find another way to do this; perhaps we should do a dummy render of
|
||||
* a texture when it's reused from our texture cache if it hasn't been used
|
||||
* in a long time). */
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5f);
|
||||
if(GetFilePath().Find("danger") != -1)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0f);
|
||||
|
||||
int pixfmt = desired_rgba_pixfmt;
|
||||
|
||||
retry:
|
||||
if(img->format->BitsPerPixel == 8 && DISPLAY->GetSpecs().EXT_paletted_texture)
|
||||
pixfmt = FMT_PAL;
|
||||
|
||||
if(pixfmt != FMT_PAL)
|
||||
/* 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(FMT_PAL))
|
||||
{
|
||||
pixfmt = FMT_PAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not paletted
|
||||
switch( m_ID.iColorDepth )
|
||||
{
|
||||
case 16:
|
||||
{
|
||||
/* Bits of alpha in the source: */
|
||||
int src_alpha_bits = 8 - img->format->Aloss;
|
||||
|
||||
/* No real alpha in paletted input. */
|
||||
if( img->format->BytesPerPixel == 1 )
|
||||
src_alpha_bits = 0;
|
||||
|
||||
/* Colorkeyed input effectively has at least one bit of alpha: */
|
||||
if( img->flags & SDL_SRCCOLORKEY )
|
||||
src_alpha_bits = max( 1, src_alpha_bits );
|
||||
|
||||
/* Don't use more than we were hinted to. */
|
||||
src_alpha_bits = min( m_ID.iAlphaBits, src_alpha_bits );
|
||||
|
||||
switch( src_alpha_bits ) {
|
||||
case 0:
|
||||
case 1:
|
||||
pixfmt = FMT_RGB5A1;
|
||||
break;
|
||||
default:
|
||||
pixfmt = FMT_RGBA4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
pixfmt = FMT_RGBA8;
|
||||
break;
|
||||
default:
|
||||
RageException::Throw( "Invalid color depth: %d bits", m_ID.iColorDepth );
|
||||
}
|
||||
|
||||
/* Override the internalformat with an alpha format if it was requested.
|
||||
* Don't use iTransparencyOnly with paletted images; there's no point--paletted
|
||||
* images are as small or smaller (and the load will fail). */
|
||||
/* SDL surfaces don't allow for 8 bpp surfaces that aren't paletted. Arg!
|
||||
* fix this later. -Chris */
|
||||
// if(m_ID.iTransparencyOnly > 0)
|
||||
// {
|
||||
// imagePixfmt = FMT_ALPHA8;
|
||||
// texturePixfmt = FMT_ALPHA8;
|
||||
// }
|
||||
|
||||
/* It's either not a paletted image, or we can't handle paletted textures.
|
||||
* Convert to the desired RGBA format, dithering if appropriate. */
|
||||
|
||||
/* Never dither when the target is 32bpp; there's no point. */
|
||||
if( PixFmtMasks[pixfmt].bpp == 32)
|
||||
m_ActualID.bDither = false;
|
||||
|
||||
if( m_ActualID.bDither )
|
||||
if( m_ID.bDither &&
|
||||
(pixfmt==FMT_RGBA4 || pixfmt==FMT_RGB5A1) ) /* Don't dither if format is 32bpp; there's no point. */
|
||||
{
|
||||
/* Dither down to the destination format. */
|
||||
SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, PixFmtMasks[pixfmt].bpp,
|
||||
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
|
||||
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
|
||||
SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, PIXEL_FORMAT_DESC[pixfmt].bpp,
|
||||
PIXEL_FORMAT_DESC[pixfmt].masks[0], PIXEL_FORMAT_DESC[pixfmt].masks[1],
|
||||
PIXEL_FORMAT_DESC[pixfmt].masks[2], PIXEL_FORMAT_DESC[pixfmt].masks[3]);
|
||||
|
||||
//SM_SDL_OrderedDither(img, dst);
|
||||
SM_SDL_ErrorDiffusionDither(img, dst);
|
||||
SDL_FreeSurface(img);
|
||||
img = dst;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the data to the destination format if it's not in it already. */
|
||||
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PixFmtMasks[pixfmt].bpp,
|
||||
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
|
||||
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
|
||||
SDL_SaveBMP( img, "testing.bmp" );
|
||||
|
||||
/* 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. */
|
||||
FixHiddenAlpha(img);
|
||||
|
||||
if(pixfmt == FMT_PAL)
|
||||
{
|
||||
/* The image is currently paletted. Let's try to set up a paletted texture. */
|
||||
GLubyte palette[256*4];
|
||||
memset(palette, 0, sizeof(palette));
|
||||
int p = 0;
|
||||
/* Copy the palette to the simple, unpacked data OGL expects. If
|
||||
* we're color keyed, change it over as we go. */
|
||||
for(int i = 0; i < img->format->palette->ncolors; ++i)
|
||||
{
|
||||
palette[p++] = img->format->palette->colors[i].r;
|
||||
palette[p++] = img->format->palette->colors[i].g;
|
||||
palette[p++] = img->format->palette->colors[i].b;
|
||||
SDL_SaveBMP( img, "testing.bmp" );
|
||||
|
||||
if(img->flags & SDL_SRCCOLORKEY && i == int(img->format->colorkey))
|
||||
palette[p++] = 0;
|
||||
else
|
||||
palette[p++] = 0xFF; /* opaque */
|
||||
}
|
||||
/* Convert the data to the destination format and dimensions
|
||||
* required by OpenGL if it's not in it already. */
|
||||
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PIXEL_FORMAT_DESC[pixfmt].bpp,
|
||||
PIXEL_FORMAT_DESC[pixfmt].masks[0], PIXEL_FORMAT_DESC[pixfmt].masks[1],
|
||||
PIXEL_FORMAT_DESC[pixfmt].masks[2], PIXEL_FORMAT_DESC[pixfmt].masks[3]);
|
||||
|
||||
SDL_SaveBMP( img, "testing.bmp" );
|
||||
|
||||
/* Set the palette. */
|
||||
GLExt::glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette);
|
||||
m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img );
|
||||
|
||||
GLint RealFormat = 0;
|
||||
GLExt::glGetColorTableParameterivEXT(GL_TEXTURE_2D, GL_COLOR_TABLE_FORMAT, &RealFormat);
|
||||
if(RealFormat != GL_RGBA8)
|
||||
{
|
||||
/* This is a case I don't expect to happen; if it does, log,
|
||||
* turn off PT's permanently and continue as an RGBA texture. */
|
||||
LOG->Info("Expected an RGBA8 palette, got %i instead; disabling paletted textures", RealFormat);
|
||||
DISPLAY->DisablePalettedTexture();
|
||||
pixfmt = desired_rgba_pixfmt;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
|
||||
|
||||
GLenum internalfmt = PixFmtMasks[pixfmt].internalfmt;
|
||||
|
||||
if(DISPLAY->GetSpecs().bPackedPixelsCauseProblems &&
|
||||
IsPackedPixelFormat(pixfmt))
|
||||
{
|
||||
/* GLDirect crashes if we give it packed pixel format. We need
|
||||
* to convert to a non-packed format (FMT_RGBA8). However, we
|
||||
* can still get 16-bit textures by passing it the appropriate
|
||||
* internalformat; it'll simply truncate the extra bits. This
|
||||
* means that it'll still use the dithering we gave it; we just
|
||||
* have to do a bit of redundant conversion work. */
|
||||
ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, PixFmtMasks[FMT_RGBA8].bpp,
|
||||
PixFmtMasks[FMT_RGBA8].masks[0], PixFmtMasks[FMT_RGBA8].masks[1],
|
||||
PixFmtMasks[FMT_RGBA8].masks[2], PixFmtMasks[FMT_RGBA8].masks[3]);
|
||||
|
||||
pixfmt = FMT_RGBA8;
|
||||
/* (don't change internalfmt) */
|
||||
}
|
||||
|
||||
if(internalfmt != GL_COLOR_INDEX8_EXT)
|
||||
{
|
||||
/* Override the internalformat with an alpha format if it was requested.
|
||||
* Don't use iTransparencyOnly with paletted images; there's no point--paletted
|
||||
* images are as small or smaller (and the load will fail). */
|
||||
if(m_ActualID.iTransparencyOnly == 4)
|
||||
internalfmt = GL_ALPHA4;
|
||||
else if(m_ActualID.iTransparencyOnly == 8)
|
||||
internalfmt = GL_ALPHA8;
|
||||
else ASSERT(m_ActualID.iTransparencyOnly == 0);
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalfmt,
|
||||
m_iTextureWidth, m_iTextureHeight, 0,
|
||||
PixFmtMasks[pixfmt].format, PixFmtMasks[pixfmt].type, img->pixels);
|
||||
|
||||
/* If we're paletted, and didn't get the 8-bit palette we asked for ...*/
|
||||
if(img->format->BitsPerPixel == 8)
|
||||
{
|
||||
GLint size = 0;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GLenum(GL_TEXTURE_INDEX_SIZE_EXT), &size);
|
||||
if(size != 8)
|
||||
{
|
||||
/* I don't know any reason this should actually fail (paletted textures
|
||||
* but no support for 8-bit palettes?), so let's just disable paletted
|
||||
* textures the first time this happens. */
|
||||
LOG->Info("Expected an 8-bit palette, got a %i-bit one instead; disabling paletted textures", size);
|
||||
DISPLAY->DisablePalettedTexture();
|
||||
pixfmt = desired_rgba_pixfmt;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glFlush();
|
||||
|
||||
SDL_FreeSurface(img);
|
||||
SDL_FreeSurface( img );
|
||||
|
||||
CreateFrameRects();
|
||||
CString props = " ";
|
||||
switch( internalfmt )
|
||||
{
|
||||
case GL_RGBA4: props += "GL_RGBA4 "; break;
|
||||
case GL_RGBA8: props += "GL_RGBA8 "; break;
|
||||
case GL_RGB5_A1: props += "GL_RGB5_A1 "; break;
|
||||
case GL_ALPHA8: props += "GL_ALPHA8 "; break;
|
||||
case GL_COLOR_INDEX8_EXT: props += "GL_COLOR_INDEX8_EXT "; break;
|
||||
default: props += ssprintf("unknown-format-%d ",internalfmt); break;
|
||||
}
|
||||
|
||||
if(m_ActualID.iAlphaBits == 0) props += "opaque ";
|
||||
if(m_ActualID.iAlphaBits == 1) props += "matte ";
|
||||
if(m_ActualID.iTransparencyOnly) props += "mask ";
|
||||
if(m_ActualID.bStretch) props += "stretch ";
|
||||
if(m_ActualID.bDither) props += "dither ";
|
||||
/*
|
||||
CString props = " ";
|
||||
switch( pixfmt )
|
||||
{
|
||||
case FMT_RGBA4: props += "FMT_RGBA4 "; break;
|
||||
case FMT_RGBA8: props += "FMT_RGBA8 "; break;
|
||||
case FMT_RGB5A1: props += "FMT_RGB5A1 "; break;
|
||||
case FMT_ALPHA8: props += "FMT_ALPHA8 "; break;
|
||||
case FMT_PAL: props += "FMT_PAL "; break;
|
||||
default: ASSERT(0); break;
|
||||
}
|
||||
if(m_ID.iAlphaBits == 0) props += "opaque ";
|
||||
if(m_ID.iAlphaBits == 1) props += "matte ";
|
||||
if(m_ID.iTransparencyOnly) props += "mask ";
|
||||
if(m_ID.bStretch) props += "stretch ";
|
||||
if(m_ID.bDither) props += "dither ";
|
||||
if(IsPackedPixelFormat(pixfmt)) props += "paletted ";
|
||||
props.erase(props.size()-1);
|
||||
LOG->Trace( "RageBitmapTexture: Loaded '%s' (%ux%u); %s, source %d,%d; image %d,%d.",
|
||||
m_ActualID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
|
||||
m_ID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
|
||||
props.c_str(), m_iSourceWidth, m_iSourceHeight,
|
||||
m_iImageWidth, m_iImageHeight);
|
||||
*/
|
||||
}
|
||||
|
||||
void RageBitmapTexture::Destroy()
|
||||
{
|
||||
DISPLAY->DeleteTexture( m_uTexHandle );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user