[*] Grayscale works in OpenGL too
This commit is contained in:
parent
0ec029274b
commit
9af911808b
4 changed files with 51 additions and 25 deletions
src
|
@ -126,6 +126,7 @@ public:
|
|||
|
||||
public:
|
||||
CGraphic *G; /// Graphic data
|
||||
CGraphic *GrayScale; /// Icon when drawn grayscaled
|
||||
int Frame; /// Frame number in graphic
|
||||
private:
|
||||
std::string Ident; /// Icon identifier
|
||||
|
|
|
@ -107,11 +107,11 @@ public:
|
|||
static CGraphic *New(const std::string &file, int w = 0, int h = 0);
|
||||
static CGraphic *ForceNew(const std::string &file, int w = 0, int h = 0);
|
||||
|
||||
CGraphic *Clone() const;
|
||||
CGraphic *Clone(bool grayscale = false) const;
|
||||
|
||||
static void Free(CGraphic *g);
|
||||
|
||||
void Load();
|
||||
void Load(bool grayscale = false);
|
||||
void Flip();
|
||||
void UseDisplayFormat();
|
||||
void Resize(int w, int h);
|
||||
|
|
|
@ -60,7 +60,7 @@ static IconMap Icons; /// Map of ident to icon.
|
|||
/**
|
||||
** CIcon constructor
|
||||
*/
|
||||
CIcon::CIcon(const std::string &ident) : G(NULL), Frame(0), Ident(ident)
|
||||
CIcon::CIcon(const std::string &ident) : G(NULL), GrayScale(NULL), Frame(0), Ident(ident)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,7 @@ CIcon::CIcon(const std::string &ident) : G(NULL), Frame(0), Ident(ident)
|
|||
CIcon::~CIcon()
|
||||
{
|
||||
CGraphic::Free(this->G);
|
||||
CGraphic::Free(this->GrayScale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,6 +112,7 @@ void CIcon::Load()
|
|||
{
|
||||
Assert(G);
|
||||
G->Load();
|
||||
GrayScale = G->Clone(true);
|
||||
if (Frame >= G->NumFrames) {
|
||||
DebugPrint("Invalid icon frame: %s - %d\n" _C_ Ident.c_str() _C_ Frame);
|
||||
Frame = 0;
|
||||
|
@ -134,30 +136,13 @@ void CIcon::DrawIcon(const CPlayer &player, const PixelPos &pos) const
|
|||
}
|
||||
|
||||
/**
|
||||
** Draw icon at pos.
|
||||
** Draw grayscale icon at pos.
|
||||
**
|
||||
** @param pos display pixel position
|
||||
*/
|
||||
void CIcon::DrawGrayscaleIcon(const PixelPos &pos) const
|
||||
{
|
||||
SDL_LockSurface(this->G->Surface);
|
||||
SDL_Color colors[256], backup[256];
|
||||
SDL_Palette &pal = *this->G->Surface->format->palette;
|
||||
memcpy(backup, pal.colors, sizeof(SDL_Color) * 256);
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
int gray = 0.21 * pal.colors[i].r + 0.72 * pal.colors[i].g + 0.07 * pal.colors[i].b;
|
||||
colors[i].r = colors[i].g = colors[i].b = gray;
|
||||
}
|
||||
SDL_SetColors(this->G->Surface, &colors[0], 0, 256);
|
||||
if (this->G->SurfaceFlip) {
|
||||
SDL_SetColors(this->G->SurfaceFlip, &colors[0], 0, 256);
|
||||
}
|
||||
SDL_UnlockSurface(this->G->Surface);
|
||||
this->G->DrawFrameClip(this->Frame, pos.x, pos.y);
|
||||
SDL_LockSurface(this->G->Surface);
|
||||
SDL_SetColors(this->G->Surface, &backup[0], 0, 256);
|
||||
SDL_UnlockSurface(this->G->Surface);
|
||||
|
||||
this->GrayScale->DrawFrameClip(this->Frame, pos.x, pos.y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -587,13 +587,15 @@ CGraphic *CGraphic::ForceNew(const std::string &file, int w, int h)
|
|||
|
||||
/**
|
||||
** Clone a graphic
|
||||
**
|
||||
** @param grayscale Make grayscale texture
|
||||
*/
|
||||
CGraphic *CGraphic::Clone() const
|
||||
CGraphic *CGraphic::Clone(bool grayscale) const
|
||||
{
|
||||
CGraphic *g = CGraphic::ForceNew(this->File, this->Width, this->Height);
|
||||
|
||||
if (this->IsLoaded()) {
|
||||
g->Load();
|
||||
g->Load(grayscale);
|
||||
}
|
||||
|
||||
return g;
|
||||
|
@ -664,8 +666,10 @@ void CGraphic::GenFramesMap()
|
|||
|
||||
/**
|
||||
** Load a graphic
|
||||
**
|
||||
** @param grayscale Make a grayscale surface
|
||||
*/
|
||||
void CGraphic::Load()
|
||||
void CGraphic::Load(bool grayscale)
|
||||
{
|
||||
if (Surface) {
|
||||
return;
|
||||
|
@ -700,6 +704,42 @@ void CGraphic::Load()
|
|||
|
||||
NumFrames = GraphicWidth / Width * GraphicHeight / Height;
|
||||
|
||||
if (grayscale) {
|
||||
SDL_LockSurface(Surface);
|
||||
const SDL_PixelFormat *f = Surface->format;
|
||||
const int bpp = Surface->format->BytesPerPixel;
|
||||
const double redGray = 0.21;
|
||||
const double greenGray = 0.72;
|
||||
const double blueGray = 0.07;
|
||||
switch (bpp) {
|
||||
case 1: {
|
||||
SDL_Color colors[256];
|
||||
SDL_Palette &pal = *Surface->format->palette;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
const int gray = redGray * pal.colors[i].r + greenGray * pal.colors[i].g + blueGray * pal.colors[i].b;
|
||||
colors[i].r = colors[i].g = colors[i].b = gray;
|
||||
}
|
||||
SDL_SetColors(Surface, &colors[0], 0, 256);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
Uint32* p;
|
||||
for (int i = 0; i < Height; ++i) {
|
||||
for (int j = 0; j < Width; ++j) {
|
||||
p = (Uint32 *)(Surface->pixels) + i * Width + j * bpp;
|
||||
const Uint32 gray = ((Uint8)((*p) * redGray) >> f->Rshift) +
|
||||
((Uint8)(*(p + 1) * greenGray) >> f->Gshift) +
|
||||
((Uint8)(*(p + 2) * blueGray) >> f->Bshift) +
|
||||
((Uint8)(*(p + 3)) >> f->Ashift);
|
||||
*p = gray;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSurface(Surface);
|
||||
}
|
||||
|
||||
#if defined(USE_OPENGL) || defined(USE_GLES)
|
||||
if (UseOpenGL) {
|
||||
MakeTexture(this);
|
||||
|
|
Loading…
Add table
Reference in a new issue