rudimentary paletted texture support and some other optimizations
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageException.h"
|
#include "RageException.h"
|
||||||
#include "RageDisplay.h"
|
#include "RageDisplay.h"
|
||||||
|
#include "RageDisplayInternal.h"
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
@@ -26,23 +27,33 @@
|
|||||||
|
|
||||||
#include "RageTimer.h"
|
#include "RageTimer.h"
|
||||||
|
|
||||||
|
enum pixfmts {
|
||||||
|
FMT_RGBA8,
|
||||||
|
FMT_RGBA4,
|
||||||
|
FMT_RGB5A1,
|
||||||
|
FMT_PAL,
|
||||||
|
NUM_PIX_FORMATS
|
||||||
|
};
|
||||||
|
|
||||||
/* Definitions for various texture formats. We'll probably want RGBA
|
/* Definitions for various texture formats. We'll probably want RGBA
|
||||||
* in OpenGL, not ARGB ... All of these are in local (little) endian;
|
* in OpenGL, not ARGB ... All of these are in local (little) endian;
|
||||||
* this may or may not need adjustment for OpenGL. */
|
* this may or may not need adjustment for OpenGL. */
|
||||||
struct PixFmt_t {
|
struct PixFmt_t {
|
||||||
int bpp;
|
int bpp;
|
||||||
GLenum type; /* data format */
|
|
||||||
GLenum internalfmt; /* target format */
|
GLenum internalfmt; /* target format */
|
||||||
|
GLenum format; /* target format */
|
||||||
|
GLenum type; /* data format */
|
||||||
unsigned int masks[4];
|
unsigned int masks[4];
|
||||||
} PixFmtMasks[] = {
|
} PixFmtMasks[NUM_PIX_FORMATS] = {
|
||||||
/* XXX: GL_UNSIGNED_SHORT_4_4_4_4 is affected by endianness; GL_UNSIGNED_BYTE
|
/* 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 not, but all SDL masks are affected by endianness, so GL_UNSIGNED_BYTE
|
||||||
* is reversed. This isn't endian-safe. */
|
* is reversed. This isn't endian-safe. */
|
||||||
{
|
{
|
||||||
/* B8G8R8A8 */
|
/* B8G8R8A8 */
|
||||||
32,
|
32,
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
GL_RGBA8,
|
GL_RGBA8,
|
||||||
|
GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
{ 0x000000FF,
|
{ 0x000000FF,
|
||||||
0x0000FF00,
|
0x0000FF00,
|
||||||
0x00FF0000,
|
0x00FF0000,
|
||||||
@@ -50,8 +61,9 @@ struct PixFmt_t {
|
|||||||
}, {
|
}, {
|
||||||
/* B4G4R4A4 */
|
/* B4G4R4A4 */
|
||||||
16,
|
16,
|
||||||
GL_UNSIGNED_SHORT_4_4_4_4,
|
|
||||||
GL_RGBA4,
|
GL_RGBA4,
|
||||||
|
GL_RGBA,
|
||||||
|
GL_UNSIGNED_SHORT_4_4_4_4,
|
||||||
{ 0xF000,
|
{ 0xF000,
|
||||||
0x0F00,
|
0x0F00,
|
||||||
0x00F0,
|
0x00F0,
|
||||||
@@ -59,22 +71,30 @@ struct PixFmt_t {
|
|||||||
}, {
|
}, {
|
||||||
/* B5G5R5A1 */
|
/* B5G5R5A1 */
|
||||||
16,
|
16,
|
||||||
GL_UNSIGNED_SHORT_5_5_5_1,
|
|
||||||
GL_RGB5_A1,
|
GL_RGB5_A1,
|
||||||
|
GL_RGBA,
|
||||||
|
GL_UNSIGNED_SHORT_5_5_5_1,
|
||||||
{ 0xF800,
|
{ 0xF800,
|
||||||
0x07C0,
|
0x07C0,
|
||||||
0x003E,
|
0x003E,
|
||||||
0x0001 },
|
0x0001 },
|
||||||
|
}, {
|
||||||
|
/* Paletted */
|
||||||
|
8,
|
||||||
|
GL_COLOR_INDEX8_EXT,
|
||||||
|
GL_COLOR_INDEX,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
{ 0,0,0,0 } /* N/A */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int PixFmtMaskNo(GLenum fmt)
|
int PixFmtMaskNo(GLenum fmt)
|
||||||
{
|
{
|
||||||
switch(fmt) {
|
switch(fmt) {
|
||||||
case GL_RGBA8: return 0;
|
case GL_RGBA8: return FMT_RGBA8;
|
||||||
case GL_RGBA4: return 1;
|
case GL_RGBA4: return FMT_RGBA4;
|
||||||
case GL_RGB5_A1: return 2;
|
case GL_RGB5_A1: return FMT_RGB5A1;
|
||||||
default: ASSERT(0); return 0;
|
default: ASSERT(0); return FMT_RGBA8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +153,7 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
|||||||
|
|
||||||
/* Load the image into an SDL surface. */
|
/* Load the image into an SDL surface. */
|
||||||
SDL_Surface *img = IMG_Load(GetFilePath());
|
SDL_Surface *img = IMG_Load(GetFilePath());
|
||||||
|
|
||||||
/* XXX: Wait, we don't want to throw for all images; in particular, we
|
/* XXX: Wait, we don't want to throw for all images; in particular, we
|
||||||
* want to tolerate corrupt/unknown background images. */
|
* want to tolerate corrupt/unknown background images. */
|
||||||
if(img == NULL)
|
if(img == NULL)
|
||||||
@@ -225,10 +246,6 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
|||||||
|
|
||||||
pixfmt = PixFmtMaskNo(fmtTexture);
|
pixfmt = PixFmtMaskNo(fmtTexture);
|
||||||
|
|
||||||
/* Dither only when the target is 16bpp, not when it's 32bpp. */
|
|
||||||
if( PixFmtMasks[pixfmt].bpp == 32)
|
|
||||||
m_ActualID.bDither = false;
|
|
||||||
|
|
||||||
if( m_ActualID.bStretch )
|
if( m_ActualID.bStretch )
|
||||||
{
|
{
|
||||||
/* resize currently only does RGBA8888 */
|
/* resize currently only does RGBA8888 */
|
||||||
@@ -239,32 +256,6 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
|||||||
zoomSurface(img, m_iImageWidth, m_iImageHeight );
|
zoomSurface(img, m_iImageWidth, m_iImageHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
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. Hmm. We could just
|
|
||||||
* convert the format, leaving the resolution alone (simplifying
|
|
||||||
* ConvertSDLSurface), and then load the texture a little more
|
|
||||||
* intelligently. If we do that with OpenGL, is the rest
|
|
||||||
* of the texture (that we didn't fill) guaranteed to be black?
|
|
||||||
* We don't want anything else to be linearly filtered in on the
|
|
||||||
* edge of the texture ...
|
|
||||||
*/
|
|
||||||
/* We could check to see if we happen to simply be in a reversed
|
|
||||||
* pixel order, and tell OpenGL to do the switch for us. */
|
|
||||||
ConvertSDLSurface(img, img->w, img->h, PixFmtMasks[pixfmt].bpp,
|
|
||||||
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
|
|
||||||
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
|
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,28 +269,114 @@ SDL_Surface *RageBitmapTexture::CreateImg(int &pixfmt)
|
|||||||
* Dither forces dithering when loading 16-bit textures.
|
* Dither forces dithering when loading 16-bit textures.
|
||||||
* Stretch forces the loaded image to fill the texture completely.
|
* Stretch forces the loaded image to fill the texture completely.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void RageBitmapTexture::Create()
|
void RageBitmapTexture::Create()
|
||||||
{
|
{
|
||||||
int pixfmt;
|
/* This will be set to the pixfmt we should use if we use an RGBA texture. */
|
||||||
|
int desired_rgba_pixfmt;
|
||||||
SDL_Surface *img = CreateImg(pixfmt);
|
SDL_Surface *img = CreateImg(desired_rgba_pixfmt);
|
||||||
|
|
||||||
if(!m_uGLTextureID)
|
if(!m_uGLTextureID)
|
||||||
glGenTextures(1, &m_uGLTextureID);
|
glGenTextures(1, &m_uGLTextureID);
|
||||||
|
|
||||||
DISPLAY->SetTexture(this);
|
DISPLAY->SetTexture(this);
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, img->pitch / img->format->BytesPerPixel);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
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_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
|
||||||
/* Here's a trick for loading a texture that doesn't necessarily have power-of-two
|
int pixfmt = desired_rgba_pixfmt;
|
||||||
* dimensions into a texture, without wasting time converting it: */
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, PixFmtMasks[pixfmt].internalfmt, power_of_two(img->w), power_of_two(img->h), 0,
|
/* XXX this needs to be a hint */
|
||||||
GL_RGBA, PixFmtMasks[pixfmt].type, NULL);
|
Uint8 AlphaR=0, AlphaG=0, AlphaB=0;
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
SetAlphaRGB(img, AlphaR, AlphaG, AlphaB);
|
||||||
img->w, img->h, GL_RGBA, PixFmtMasks[pixfmt].type, img->pixels);
|
|
||||||
|
if(img->format->BitsPerPixel == 8 && DISPLAY->GetSpecs().EXT_paletted_texture)
|
||||||
|
{
|
||||||
|
/* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the palette. */
|
||||||
|
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette);
|
||||||
|
|
||||||
|
int RealFormat = 0;
|
||||||
|
glGetColorTableParameterivEXT(GL_TEXTURE_2D, GL_COLOR_TABLE_FORMAT_EXT, &RealFormat);
|
||||||
|
if(RealFormat == GL_RGBA8)
|
||||||
|
{
|
||||||
|
/* Good, the color table is what we asked for. Use a paletted texture format. */
|
||||||
|
pixfmt = FMT_PAL;
|
||||||
|
} else {
|
||||||
|
/* This is another 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if(pixfmt != FMT_PAL)
|
||||||
|
{
|
||||||
|
/* It's either not a paletted image, or we can't handle paletted images.
|
||||||
|
* 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]);
|
||||||
|
|
||||||
|
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;
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 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);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ void mySDL_GetBitsPerChannel(const SDL_PixelFormat *fmt, Uint32 bits[4])
|
|||||||
bits[2] = 8 - fmt->Bloss;
|
bits[2] = 8 - fmt->Bloss;
|
||||||
bits[3] = 8 - fmt->Aloss;
|
bits[3] = 8 - fmt->Aloss;
|
||||||
}
|
}
|
||||||
#include "RageLog.h"
|
|
||||||
|
|
||||||
void ConvertSDLSurface(SDL_Surface *&image,
|
void ConvertSDLSurface(SDL_Surface *&image,
|
||||||
int width, int height, int bpp,
|
int width, int height, int bpp,
|
||||||
@@ -150,22 +149,48 @@ void ConvertSDLSurface(SDL_Surface *&image,
|
|||||||
SDL_SWSURFACE, width, height, bpp, R, G, B, A);
|
SDL_SWSURFACE, width, height, bpp, R, G, B, A);
|
||||||
ASSERT(ret_image != NULL);
|
ASSERT(ret_image != NULL);
|
||||||
|
|
||||||
/* If the formats are the same, no conversion is needed. One exception:
|
/* If the formats are the same, no conversion is needed. */
|
||||||
* if we have a color key and we're not paletted (8-bit). (If we have
|
if(width == image->w && height == image->h && bpp == image->format->BitsPerPixel &&
|
||||||
* a color key but we're paletted, we'll handle this on texture load.) xxx unimplemented */
|
image->format->Rmask == ret_image->format->Rmask &&
|
||||||
if(!(image->flags & SDL_SRCCOLORKEY) &&
|
image->format->Gmask == ret_image->format->Gmask &&
|
||||||
width == image->w && height == image->h &&
|
image->format->Bmask == ret_image->format->Bmask &&
|
||||||
!memcmp(image->format, ret_image->format, sizeof(SDL_PixelFormat)))
|
image->format->Amask == ret_image->format->Amask)
|
||||||
|
{
|
||||||
|
/* One exception: if we have a color key and we're not paletted (8-bit).
|
||||||
|
* In this case, we need to do the blit to get rid of the color key. */
|
||||||
|
if(!( image->flags & SDL_SRCCOLORKEY && image->format->BitsPerPixel != 8) )
|
||||||
{
|
{
|
||||||
LOG->Trace("noconv");
|
|
||||||
SDL_FreeSurface(ret_image);
|
SDL_FreeSurface(ret_image);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We don't want to actually blend the alpha channel over the destination converted
|
/* We don't want to actually blend the alpha channel over the destination converted
|
||||||
* surface; we want to simply blit it, so make sure SDL_SRCALPHA is not on. */
|
* surface; we want to simply blit it, so make sure SDL_SRCALPHA is not on. */
|
||||||
SDL_SetAlpha( image, 0, SDL_ALPHA_OPAQUE );
|
SDL_SetAlpha( image, 0, SDL_ALPHA_OPAQUE );
|
||||||
|
|
||||||
|
/* Copy the palette, if we have one. */
|
||||||
|
if(image->format->palette)
|
||||||
|
SDL_SetPalette(ret_image, SDL_LOGPAL, image->format->palette->colors,
|
||||||
|
0, image->format->palette->ncolors);
|
||||||
|
|
||||||
|
if(image->format->BitsPerPixel == 8 && ret_image->format->BitsPerPixel == 8 &&
|
||||||
|
image->flags & SDL_SRCCOLORKEY)
|
||||||
|
{
|
||||||
|
/* The source and dest are both paletted, and we have a color key.
|
||||||
|
* First, make sure that the image we're blitting to has a default
|
||||||
|
* color of the color key, so any places we don't blit to will
|
||||||
|
* be transparent. (The default color in the image is 0, so we're
|
||||||
|
* all set if the color key is 0.) */
|
||||||
|
if(image->format->colorkey != 0)
|
||||||
|
SDL_FillRect(ret_image, NULL, image->format->colorkey);
|
||||||
|
|
||||||
|
/* Copy over the color key mode, and then turn off color keying in the
|
||||||
|
* source so the color key index gets copied like any other color. */
|
||||||
|
SDL_SetColorKey( ret_image, SDL_SRCCOLORKEY, image->format->colorkey);
|
||||||
|
SDL_SetColorKey( image, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Rect area;
|
SDL_Rect area;
|
||||||
area.x = area.y = 0;
|
area.x = area.y = 0;
|
||||||
area.w = short(image->w);
|
area.w = short(image->w);
|
||||||
@@ -207,3 +232,43 @@ SDL_Surface *SDL_CreateRGBSurfaceSane
|
|||||||
return SDL_CreateRGBSurface(flags, width, height, depth,
|
return SDL_CreateRGBSurface(flags, width, height, depth,
|
||||||
Rmask, Gmask, Bmask, Amask);
|
Rmask, Gmask, Bmask, Amask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the underlying RGB values of all pixels in 'img' that are
|
||||||
|
* completely transparent. */
|
||||||
|
void SetAlphaRGB(SDL_Surface *img, Uint8 r, Uint8 g, Uint8 b)
|
||||||
|
{
|
||||||
|
/* If it's a paletted surface, all we have to do is change the
|
||||||
|
* colorkey, if any. */
|
||||||
|
if(img->format->BitsPerPixel == 8)
|
||||||
|
{
|
||||||
|
if(img->flags & SDL_SRCCOLORKEY)
|
||||||
|
{
|
||||||
|
img->format->palette->colors[img->format->colorkey].r = r;
|
||||||
|
img->format->palette->colors[img->format->colorkey].g = g;
|
||||||
|
img->format->palette->colors[img->format->colorkey].b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It's RGBA. If there's no alpha channel, we have nothing to do. */
|
||||||
|
if(!img->format->Amask)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Uint32 trans = SDL_MapRGBA(img->format, r, g, b, 0);
|
||||||
|
for(int y = 0; y < img->h; ++y)
|
||||||
|
{
|
||||||
|
Uint8 *row = (Uint8 *)img->pixels + img->pitch*y;
|
||||||
|
|
||||||
|
for(int x = 0; x < img->w; ++x)
|
||||||
|
{
|
||||||
|
Uint32 val = decodepixel(row, img->format->BytesPerPixel);
|
||||||
|
if(val != trans && !(val&img->format->Amask))
|
||||||
|
{
|
||||||
|
encodepixel(row, img->format->BytesPerPixel, trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
row += img->format->BytesPerPixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,5 +20,7 @@ SDL_Surface *SDL_CreateRGBSurfaceSane
|
|||||||
(Uint32 flags, int width, int height, int depth,
|
(Uint32 flags, int width, int height, int depth,
|
||||||
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
|
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
|
||||||
|
|
||||||
|
void SetAlphaRGB(SDL_Surface *img, Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user