#include "Image.h" // base constructor, Create a new image from a file name, by default no alpha graphic::Image::Image(std::string file, bool graphic_mode) { // Temporary surface SDL_Surface * temp; // Load image temp = IMG_Load(file.c_str()); // an error occurred if(temp == NULL) throw Exception("Image", IMG_GetError()); if(temp->format->BitsPerPixel == ALPHA_BPP) { _surface = SDL_DisplayFormatAlpha(temp); _uses_alpha = true; } else { _surface = SDL_DisplayFormat(temp); _uses_alpha = false; } // Free temporary surface SDL_FreeSurface(temp); // an error occurred if(_surface == NULL) throw Exception("Image", IMG_GetError()); // Setting default position _rectangle->x = 0; _rectangle->y = 0; // Setting image dimensions _rectangle->w = _surface->w; _rectangle->h = _surface->h; // no trans color _has_trans_color = false; _trans_color = 0; _vis_rect = new SDL_Rect; SetVisibleLimits(); #ifdef WITH_OPENGL // GL SURFACE if(graphic_mode == GL_GRAPHIC) { SDL_SetAlpha(_surface, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); // Checking for max texture size if (!CheckTexSize(_surface)) throw Exception("image", "Max texture size exceeded\n"); // Setting real power-of-two texture dimensions _wreal = (int)powf(2.0, ceilf(logf((float)_surface->w)/logf(2.0f))); _hreal = (int)powf(2.0, ceilf(logf((float)_surface->h)/logf(2.0f))); // Texture creation if (!Surf2Tex(_surface)) throw Exception("Image", "Texture not created, image format unknown\n"); } else #endif SDL_SetAlpha(_surface, SDL_SRCALPHA|SDL_RLEACCEL, SDL_ALPHA_OPAQUE); _graphic_mode = graphic_mode; } // create a new image from a file name setting a color as transparent graphic::Image::Image(std::string file, SDL_Color trans_color, bool graphic_mode) { // Temporary surface SDL_Surface *temp; // Load image temp = IMG_Load(file.c_str()); // An error occurred if(temp == NULL) throw Exception("Image", IMG_GetError()); _surface = SDL_DisplayFormat(temp); // Free temporary surface SDL_FreeSurface(temp); // an error occurred if(_surface == NULL) throw Exception("Image", IMG_GetError()); // Setting default position _rectangle->x = 0; _rectangle->y = 0; // Setting image dimensions _rectangle->w = _surface->w; _rectangle->h = _surface->h; // set trans color _has_trans_color = true; _trans_color = SDL_MapRGB(_surface->format, trans_color.r, trans_color.g, trans_color.b); SDL_SetColorKey(_surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, _trans_color); // Set alpha flag _uses_alpha = false; _vis_rect = new SDL_Rect; SetVisibleLimits(); #ifdef WITH_OPENGL // GL SURFACE if(graphic_mode == GL_GRAPHIC) { SDL_SetAlpha(_surface, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); // Checking for max texture size if (!CheckTexSize(_surface)) throw Exception("Image", "Max texture size exceeded\n"); // Setting real power-of-two texture dimensions _wreal = (int)powf(2.0, ceilf(logf((float)_surface->w)/logf(2.0f))); _hreal = (int)powf(2.0, ceilf(logf((float)_surface->h)/logf(2.0f))); // Texture creation if (!Surf2Tex(_surface)) throw Exception("Image", "Texture not created, image format unknown\n"); } else #endif SDL_SetAlpha(_surface, SDL_SRCALPHA|SDL_RLEACCEL, SDL_ALPHA_OPAQUE); _graphic_mode = graphic_mode; } // set visible limits of the image void graphic::Image::SetVisibleLimits() { int first_x = _surface->w - 1; int first_y = _surface->h - 1; int last_x = 0; int last_y = 0; // set visible area - the image uses alpha or has a trans color if(_uses_alpha || _has_trans_color || _opacity < SDL_ALPHA_OPAQUE) { Lock(); for(int x = 0; x < _surface->w; x++) { for(int y = 0; y < _surface->h; y++) { // opaque color if((_uses_alpha && GetAlpha(x, y) > MIN_TRANS) || (!_uses_alpha && !_has_trans_color && _surface->format->alpha > MIN_TRANS) || (_has_trans_color && GetPixel(x, y) != _trans_color && _surface->format->alpha > MIN_TRANS)) { if(x < first_x) first_x = x; if(x > last_x) last_x = x; if(y < first_y) first_y = y; if(y > last_y) last_y = y; } } } Unlock(); _vis_rect->x = first_x; _vis_rect->y = first_y; _vis_rect->w = last_x; _vis_rect->h = last_y; } // set visible area - the image doesn't use alpha nor have a trans color ==> all the image else { _vis_rect->x = 0; _vis_rect->y = 0; _vis_rect->w = _rectangle->w - 1; _vis_rect->h = _rectangle->h - 1; } } // return true if the pixel at (x,y) is transparent, false otherwise bool graphic::Image::IsTrans(Uint16 x, Uint16 y) { bool val; Lock(); if((_uses_alpha && GetAlpha(x, y) <= MIN_TRANS) || (!_uses_alpha && _surface->format->alpha <= MIN_TRANS) || (_has_trans_color && GetPixel(x, y) == _trans_color)) val = true; else val = false; Unlock(); return val; }