Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

convgltex.cpp

Go to the documentation of this file.
00001 
00012 #include "Teddy/TeddyConfig.h"
00013 #include <SDL.h>
00014 #ifdef HAVE_LIB_SDL_IMAGE
00015 #   include <SDL_image.h>
00016 #endif
00017 #include <cstring>
00018 
00019 
00033 SDL_Surface *conv_surf_gl( SDL_Surface *s, int want_alpha ){
00034     Uint32       rmask;
00035     Uint32       gmask;
00036     Uint32       bmask;
00037     Uint32       amask;
00038     SDL_Surface *conv;
00039     int          bpp = want_alpha ? 32 : 24;
00040 
00041     //  SDL interprets each pixel as a 24 or 32-bit number, so our
00042     //  masks must depend on the endianness (byte order) of the
00043     //  machine.
00044 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00045     rmask = 0xff000000 >> (32 - bpp);
00046     gmask = 0x00ff0000 >> (32 - bpp);
00047     bmask = 0x0000ff00 >> (32 - bpp);
00048     amask = 0x000000ff >> (32 - bpp);
00049 #else
00050     rmask = 0x000000ff;
00051     gmask = 0x0000ff00;
00052     bmask = 0x00ff0000;
00053     amask = want_alpha ? 0xff000000 : 0;
00054 #endif
00055 
00056     //  Check if the surface happens to be in the right format
00057     if(
00058         (s->format->BitsPerPixel == bpp  ) &&
00059         (s->format->Rmask        == rmask) &&
00060         (s->format->Gmask        == gmask) &&
00061         (s->format->Bmask        == bmask) &&
00062         (s->format->Amask        == amask) &&
00063         !(s->flags & SDL_SRCCOLORKEY) )
00064     {
00065         //  No conversion needed
00066         return s;
00067     }
00068 
00069     //  Wrong format, conversion necessary
00070 
00071     //  SDL surfaces are created with lines padded to start at 32-bit boundaries
00072     //  which suits OpenGL well (as long as GL_UNPACK_ALIGNMENT remains
00073     //  unchanged from its initial value of 4)
00074     conv = SDL_CreateRGBSurface(
00075         SDL_SWSURFACE, 
00076         s->w, 
00077         s->h, 
00078         bpp,
00079         rmask, 
00080         gmask, 
00081         bmask, 
00082         amask
00083     );
00084     if( !conv ){
00085         SDL_FreeSurface( conv );
00086         return NULL;
00087     }
00088 
00089     //  SDL sets the SDL_SRCALPHA flag on all surfaces with an
00090     //  alpha channel. We need to clear that flag for the copy,
00091     //  since SDL would attempt to alpha-blend our image otherwise */
00092     if( want_alpha ){
00093         SDL_SetAlpha( s, 0, 255 );
00094     }
00095 
00096     //  Do the conversion. If the source surface has a colourkey, then it
00097     //  will be used in the blit. We use the fact that newly created software
00098     //  surfaces are zero-filled, so the pixels not blitted will remain
00099     //  transparent.
00100     if( SDL_BlitSurface(s,NULL,conv,NULL) < 0 ){
00101         //  Blit error
00102         SDL_FreeSurface( conv );
00103         conv = NULL;
00104     }
00105 
00106     //tksuoran: This causes to crash with some images
00107     //SDL_FreeSurface(s);
00108 
00109     return conv;
00110 }
00111 
00112 
00121 SDL_Surface *load_gl_texture( const char *file ){
00122 #ifdef HAVE_LIB_SDL_IMAGE
00123     SDL_Surface *s = IMG_Load(file);
00124 #else
00125     SDL_Surface *s = NULL;
00126 #endif
00127     if( s==NULL ){
00128         return NULL;
00129     }
00130     return conv_surf_gl(s, s->format->Amask || (s->flags & SDL_SRCCOLORKEY));
00131 }
00132