2001-11-03 10:52:42 +00:00
|
|
|
#include "stdafx.h"
|
2001-11-04 19:34:28 +00:00
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
2002-08-13 23:26:46 +00:00
|
|
|
Class: RageBitmapTexture
|
2001-11-04 19:34:28 +00:00
|
|
|
|
|
|
|
|
Desc: Holder for a static texture with metadata. Can load just about any image format.
|
|
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
2002-10-24 04:16:15 +00:00
|
|
|
Glenn Maynard
|
2002-11-14 01:26:19 +00:00
|
|
|
Chris Danford
|
2001-11-04 19:34:28 +00:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
2001-11-03 10:52:42 +00:00
|
|
|
|
|
|
|
|
#include "RageBitmapTexture.h"
|
|
|
|
|
#include "RageUtil.h"
|
2002-05-01 19:14:55 +00:00
|
|
|
#include "RageLog.h"
|
2002-07-27 19:29:51 +00:00
|
|
|
#include "RageException.h"
|
2002-11-14 01:26:19 +00:00
|
|
|
#include "RageDisplay.h"
|
2003-01-23 04:45:45 +00:00
|
|
|
#include "RageDisplayInternal.h"
|
2002-06-14 22:25:22 +00:00
|
|
|
|
2002-10-24 04:16:15 +00:00
|
|
|
#include "SDL.h"
|
|
|
|
|
#include "SDL_image.h"
|
|
|
|
|
#include "SDL_endian.h"
|
|
|
|
|
#include "SDL_rotozoom.h"
|
|
|
|
|
#include "SDL_utils.h"
|
|
|
|
|
#include "SDL_dither.h"
|
|
|
|
|
|
2002-11-14 01:26:19 +00:00
|
|
|
#include "RageTimer.h"
|
|
|
|
|
|
2003-01-23 04:45:45 +00:00
|
|
|
enum pixfmts {
|
|
|
|
|
FMT_RGBA8,
|
|
|
|
|
FMT_RGBA4,
|
|
|
|
|
FMT_RGB5A1,
|
|
|
|
|
FMT_PAL,
|
|
|
|
|
NUM_PIX_FORMATS
|
|
|
|
|
};
|
|
|
|
|
|
2002-11-14 01:26:19 +00:00
|
|
|
/* 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. */
|
2002-12-30 04:46:56 +00:00
|
|
|
struct PixFmt_t {
|
|
|
|
|
int bpp;
|
2003-01-01 09:07:34 +00:00
|
|
|
GLenum internalfmt; /* target format */
|
2003-01-23 04:45:45 +00:00
|
|
|
GLenum format; /* target format */
|
|
|
|
|
GLenum type; /* data format */
|
2002-12-30 04:46:56 +00:00
|
|
|
unsigned int masks[4];
|
2003-01-23 04:45:45 +00:00
|
|
|
} PixFmtMasks[NUM_PIX_FORMATS] = {
|
2002-12-30 04:46:56 +00:00
|
|
|
/* 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,
|
2003-01-01 09:07:34 +00:00
|
|
|
GL_RGBA8,
|
2003-01-23 04:45:45 +00:00
|
|
|
GL_RGBA,
|
|
|
|
|
GL_UNSIGNED_BYTE,
|
2002-12-30 04:46:56 +00:00
|
|
|
{ 0x000000FF,
|
|
|
|
|
0x0000FF00,
|
|
|
|
|
0x00FF0000,
|
|
|
|
|
0xFF000000 }
|
|
|
|
|
}, {
|
|
|
|
|
/* B4G4R4A4 */
|
|
|
|
|
16,
|
2003-01-01 09:07:34 +00:00
|
|
|
GL_RGBA4,
|
2003-01-23 04:45:45 +00:00
|
|
|
GL_RGBA,
|
|
|
|
|
GL_UNSIGNED_SHORT_4_4_4_4,
|
2002-12-30 04:46:56 +00:00
|
|
|
{ 0xF000,
|
|
|
|
|
0x0F00,
|
|
|
|
|
0x00F0,
|
|
|
|
|
0x000F },
|
|
|
|
|
}, {
|
|
|
|
|
/* B5G5R5A1 */
|
|
|
|
|
16,
|
2003-01-01 09:07:34 +00:00
|
|
|
GL_RGB5_A1,
|
2003-01-23 04:45:45 +00:00
|
|
|
GL_RGBA,
|
|
|
|
|
GL_UNSIGNED_SHORT_5_5_5_1,
|
2002-12-30 04:46:56 +00:00
|
|
|
{ 0xF800,
|
|
|
|
|
0x07C0,
|
|
|
|
|
0x003E,
|
|
|
|
|
0x0001 },
|
2003-01-23 04:45:45 +00:00
|
|
|
}, {
|
|
|
|
|
/* Paletted */
|
|
|
|
|
8,
|
|
|
|
|
GL_COLOR_INDEX8_EXT,
|
|
|
|
|
GL_COLOR_INDEX,
|
|
|
|
|
GL_UNSIGNED_BYTE,
|
|
|
|
|
{ 0,0,0,0 } /* N/A */
|
2002-12-30 04:46:56 +00:00
|
|
|
}
|
2002-11-14 01:26:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int PixFmtMaskNo(GLenum fmt)
|
|
|
|
|
{
|
|
|
|
|
switch(fmt) {
|
2003-01-23 04:45:45 +00:00
|
|
|
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;
|
2002-11-14 01:26:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
2002-10-24 04:16:15 +00:00
|
|
|
|
2001-11-03 10:52:42 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// RageBitmapTexture constructor
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2002-12-30 02:43:52 +00:00
|
|
|
RageBitmapTexture::RageBitmapTexture( RageTextureID name ) :
|
|
|
|
|
RageTexture( name )
|
2001-11-03 10:52:42 +00:00
|
|
|
{
|
2002-07-31 19:40:40 +00:00
|
|
|
// LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2002-11-12 09:23:15 +00:00
|
|
|
m_uGLTextureID = 0;
|
2002-11-14 01:26:19 +00:00
|
|
|
|
|
|
|
|
Create(); // sFilePath and prefs are saved by RageTexture()
|
2001-11-03 10:52:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RageBitmapTexture::~RageBitmapTexture()
|
|
|
|
|
{
|
2002-11-12 09:23:15 +00:00
|
|
|
if(m_uGLTextureID)
|
|
|
|
|
glDeleteTextures(1, &m_uGLTextureID);
|
2002-04-28 20:42:32 +00:00
|
|
|
}
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2003-01-26 00:56:13 +00:00
|
|
|
void RageBitmapTexture::Reload()
|
2002-11-14 01:26:19 +00:00
|
|
|
{
|
2003-01-26 00:56:13 +00:00
|
|
|
RageTexture::Reload();
|
2002-11-14 01:26:19 +00:00
|
|
|
DISPLAY->SetTexture(0);
|
|
|
|
|
|
|
|
|
|
if(m_uGLTextureID)
|
|
|
|
|
{
|
|
|
|
|
glDeleteTextures(1, &m_uGLTextureID);
|
|
|
|
|
m_uGLTextureID = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Create();
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-30 04:03:49 +00:00
|
|
|
/* 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
|
2002-11-14 01:26:19 +00:00
|
|
|
*/
|
2003-01-01 09:07:34 +00:00
|
|
|
SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
2002-11-14 01:26:19 +00:00
|
|
|
{
|
|
|
|
|
// look in the file name for a format hints
|
2002-12-30 02:43:52 +00:00
|
|
|
CString HintString = GetFilePath();
|
|
|
|
|
HintString.MakeLower();
|
2002-10-24 04:16:15 +00:00
|
|
|
|
2002-12-30 02:43:52 +00:00
|
|
|
if( HintString.Find("no alpha") != -1 ) m_ActualID.iAlphaBits = 0;
|
|
|
|
|
else if( HintString.Find("1 alpha") != -1 ) m_ActualID.iAlphaBits = 1;
|
|
|
|
|
else if( HintString.Find("1alpha") != -1 ) m_ActualID.iAlphaBits = 1;
|
|
|
|
|
else if( HintString.Find("0alpha") != -1 ) m_ActualID.iAlphaBits = 0;
|
2002-12-30 03:35:58 +00:00
|
|
|
if( HintString.Find("dither") != -1 ) m_ActualID.bDither = true;
|
2002-10-24 04:16:15 +00:00
|
|
|
|
|
|
|
|
/* Load the image into an SDL surface. */
|
2002-12-30 02:43:52 +00:00
|
|
|
SDL_Surface *img = IMG_Load(GetFilePath());
|
2003-01-23 04:45:45 +00:00
|
|
|
|
2002-11-21 00:54:28 +00:00
|
|
|
/* XXX: Wait, we don't want to throw for all images; in particular, we
|
|
|
|
|
* want to tolerate corrupt/unknown background images. */
|
|
|
|
|
if(img == NULL)
|
2003-01-01 21:21:44 +00:00
|
|
|
RageException::Throw( "Couldn't load %s: %s", GetFilePath().GetString(), SDL_GetError() );
|
2002-11-14 01:26:19 +00:00
|
|
|
|
2003-01-22 04:18:02 +00:00
|
|
|
if(m_ActualID.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
|
|
|
|
|
* will get some other random color transparent. We have to make
|
|
|
|
|
* sure the value returned for paletted images is exactly #FF00FF. */
|
|
|
|
|
int color = SDL_MapRGB(img->format, 0xFF, 0, 0xFF);
|
|
|
|
|
if( img->format->BitsPerPixel == 8 ) {
|
|
|
|
|
if(img->format->palette->colors[color].r != 0xFF ||
|
|
|
|
|
img->format->palette->colors[color].g != 0x00 ||
|
|
|
|
|
img->format->palette->colors[color].b != 0xFF )
|
|
|
|
|
color = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( color != -1 )
|
|
|
|
|
SDL_SetColorKey( img, SDL_SRCCOLORKEY, color);
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-01 09:07:34 +00:00
|
|
|
GLenum fmtTexture;
|
2002-11-14 01:26:19 +00:00
|
|
|
/* Figure out which texture format to use. */
|
2003-01-01 09:07:34 +00:00
|
|
|
if( m_ActualID.iColorDepth == 16 )
|
2002-11-14 01:26:19 +00:00
|
|
|
{
|
|
|
|
|
/* 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. */
|
2002-12-30 02:43:52 +00:00
|
|
|
src_alpha_bits = min( m_ActualID.iAlphaBits, src_alpha_bits );
|
2002-11-14 01:26:19 +00:00
|
|
|
|
|
|
|
|
/* XXX Scan the image, and see if it actually uses its alpha channel/color key
|
|
|
|
|
* (if any). Reduce to 1 or 0 bits of alpha if possible. */
|
|
|
|
|
|
|
|
|
|
switch( src_alpha_bits ) {
|
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
fmtTexture = GL_RGB5_A1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fmtTexture = GL_RGBA4;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-01-01 09:07:34 +00:00
|
|
|
else if( m_ActualID.iColorDepth == 32)
|
2002-11-14 01:26:19 +00:00
|
|
|
fmtTexture = GL_RGBA8;
|
|
|
|
|
else
|
2002-12-30 03:35:58 +00:00
|
|
|
RageException::Throw( "Invalid color depth: %d bits", m_ActualID.iColorDepth );
|
2002-11-14 01:26:19 +00:00
|
|
|
|
|
|
|
|
/* Cap the max texture size to the hardware max. */
|
2002-12-30 02:43:52 +00:00
|
|
|
m_ActualID.iMaxSize = min( m_ActualID.iMaxSize, DISPLAY->GetMaxTextureSize() );
|
2002-11-14 01:26:19 +00:00
|
|
|
|
|
|
|
|
/* Save information about the source. */
|
|
|
|
|
m_iSourceWidth = img->w;
|
|
|
|
|
m_iSourceHeight = img->h;
|
|
|
|
|
|
|
|
|
|
/* image size cannot exceed max size */
|
2002-12-30 02:43:52 +00:00
|
|
|
m_iImageWidth = min( m_iSourceWidth, m_ActualID.iMaxSize );
|
|
|
|
|
m_iImageHeight = min( m_iSourceHeight, m_ActualID.iMaxSize );
|
2002-10-24 04:16:15 +00:00
|
|
|
|
|
|
|
|
/* Texture dimensions need to be a power of two; jump to the next. */
|
2002-11-14 01:26:19 +00:00
|
|
|
m_iTextureWidth = power_of_two(m_iImageWidth);
|
|
|
|
|
m_iTextureHeight = power_of_two(m_iImageHeight);
|
|
|
|
|
|
2002-12-30 02:43:52 +00:00
|
|
|
ASSERT( m_iTextureWidth <= m_ActualID.iMaxSize );
|
|
|
|
|
ASSERT( m_iTextureHeight <= m_ActualID.iMaxSize );
|
2002-11-14 01:26:19 +00:00
|
|
|
|
2002-12-30 02:43:52 +00:00
|
|
|
if(m_ActualID.bStretch)
|
2002-11-21 22:34:37 +00:00
|
|
|
{
|
|
|
|
|
/* The hints asked for the image to be stretched to the texture size,
|
|
|
|
|
* probably for tiling. */
|
|
|
|
|
m_iImageWidth = m_iTextureWidth;
|
|
|
|
|
m_iImageHeight = m_iTextureHeight;
|
|
|
|
|
}
|
2002-11-14 01:26:19 +00:00
|
|
|
|
|
|
|
|
/* If the source is larger than the texture, we have to scale it down; that's
|
|
|
|
|
* "stretching", I guess. */
|
|
|
|
|
if(m_iSourceWidth != m_iImageWidth || m_iSourceHeight > m_iImageHeight)
|
2002-12-30 02:43:52 +00:00
|
|
|
m_ActualID.bStretch = true;
|
2002-11-14 01:26:19 +00:00
|
|
|
|
2002-12-30 04:46:56 +00:00
|
|
|
pixfmt = PixFmtMaskNo(fmtTexture);
|
2002-11-14 01:26:19 +00:00
|
|
|
|
2002-12-30 02:43:52 +00:00
|
|
|
if( m_ActualID.bStretch )
|
2002-11-14 01:26:19 +00:00
|
|
|
{
|
|
|
|
|
/* resize currently only does RGBA8888 */
|
|
|
|
|
int mask = 0;
|
2002-12-30 04:46:56 +00:00
|
|
|
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]);
|
2002-11-21 22:34:37 +00:00
|
|
|
zoomSurface(img, m_iImageWidth, m_iImageHeight );
|
2002-11-14 01:26:19 +00:00
|
|
|
}
|
|
|
|
|
|
2002-12-30 04:03:49 +00:00
|
|
|
return img;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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()
|
|
|
|
|
{
|
2003-01-23 04:45:45 +00:00
|
|
|
/* This will be set to the pixfmt we should use if we use an RGBA texture. */
|
|
|
|
|
int desired_rgba_pixfmt;
|
|
|
|
|
SDL_Surface *img = CreateImg(desired_rgba_pixfmt);
|
2003-01-01 09:07:34 +00:00
|
|
|
|
|
|
|
|
if(!m_uGLTextureID)
|
2002-11-12 09:23:15 +00:00
|
|
|
glGenTextures(1, &m_uGLTextureID);
|
2002-10-24 04:16:15 +00:00
|
|
|
|
2002-11-12 09:23:15 +00:00
|
|
|
DISPLAY->SetTexture(this);
|
2003-01-01 09:07:34 +00:00
|
|
|
|
2002-11-11 04:53:31 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
2003-01-23 04:45:45 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
|
|
|
|
|
|
int pixfmt = desired_rgba_pixfmt;
|
|
|
|
|
|
2003-01-26 02:35:55 +00:00
|
|
|
retry:
|
|
|
|
|
if(img->format->BitsPerPixel == 8 && DISPLAY->GetSpecs().EXT_paletted_texture)
|
|
|
|
|
pixfmt = FMT_PAL;
|
|
|
|
|
|
|
|
|
|
if(pixfmt != FMT_PAL)
|
|
|
|
|
{
|
|
|
|
|
/* 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 )
|
|
|
|
|
{
|
|
|
|
|
/* 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]);
|
|
|
|
|
|
|
|
|
|
SM_SDL_OrderedDither(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]);
|
|
|
|
|
|
|
|
|
|
/* 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. */
|
2003-01-23 05:35:21 +00:00
|
|
|
FixHiddenAlpha(img);
|
2003-01-23 04:45:45 +00:00
|
|
|
|
2003-01-26 02:35:55 +00:00
|
|
|
if(pixfmt == FMT_PAL)
|
2003-01-23 04:45:45 +00:00
|
|
|
{
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
|
|
if(img->flags & SDL_SRCCOLORKEY && i == int(img->format->colorkey))
|
|
|
|
|
palette[p++] = 0;
|
|
|
|
|
else
|
|
|
|
|
palette[p++] = 0xFF; /* opaque */
|
|
|
|
|
}
|
2003-01-22 04:18:02 +00:00
|
|
|
|
2003-01-23 04:45:45 +00:00
|
|
|
/* Set the palette. */
|
2003-02-14 23:29:30 +00:00
|
|
|
GLExt::glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette);
|
2003-01-23 04:45:45 +00:00
|
|
|
|
|
|
|
|
int RealFormat = 0;
|
2003-02-15 00:15:26 +00:00
|
|
|
GLExt::glGetColorTableParameterivEXT(GL_TEXTURE_2D, GL_COLOR_TABLE_FORMAT_EXT, &RealFormat);
|
2003-01-26 02:35:55 +00:00
|
|
|
if(RealFormat != GL_RGBA8)
|
2003-01-23 04:45:45 +00:00
|
|
|
{
|
2003-01-26 02:35:55 +00:00
|
|
|
/* This is a case I don't expect to happen; if it does, log,
|
2003-01-23 04:45:45 +00:00
|
|
|
* 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();
|
2003-01-26 02:35:55 +00:00
|
|
|
pixfmt = desired_rgba_pixfmt;
|
|
|
|
|
goto retry;
|
2003-01-23 04:45:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, PixFmtMasks[pixfmt].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)
|
|
|
|
|
{
|
|
|
|
|
int size;
|
2003-02-15 00:15:26 +00:00
|
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GLenum(GL_TEXTURE_INDEX_SIZE_EXT), &size);
|
2003-01-23 04:45:45 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-01-22 04:18:02 +00:00
|
|
|
|
2002-12-20 06:28:22 +00:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
2002-11-11 04:53:31 +00:00
|
|
|
glFlush();
|
|
|
|
|
|
2002-10-24 04:16:15 +00:00
|
|
|
SDL_FreeSurface(img);
|
|
|
|
|
|
2002-11-11 04:53:31 +00:00
|
|
|
CreateFrameRects();
|
2002-11-12 09:23:15 +00:00
|
|
|
|
2002-11-14 01:26:19 +00:00
|
|
|
// LOG->Trace( "RageBitmapTexture: Loaded '%s' (%ux%u) from disk. bStretch = %d, source %d,%d; image %d,%d.",
|
|
|
|
|
// m_sFilePath.GetString(), GetTextureWidth(), GetTextureHeight(),
|
|
|
|
|
// bStretch, m_iSourceWidth, m_iSourceHeight,
|
|
|
|
|
// m_iImageWidth, m_iImageHeight);
|
2001-11-03 10:52:42 +00:00
|
|
|
}
|
2002-11-14 01:26:19 +00:00
|
|
|
|