Example #1
0
/**
 * @brief Loads the already padded SDL_Surface to a glTexture.
 *
 *    @param name Name to load with.
 *    @param surface Surface to load.
 *    @param flags Flags to use.
 *    @param w Non-padded width.
 *    @param h Non-padded height.
 *    @param sx X sprites.
 *    @param sy Y sprites.
 *    @param freesur Whether or not to free the surface.
 *    @return The glTexture for surface.
 */
glTexture* gl_loadImagePad( const char *name, SDL_Surface* surface,
      unsigned int flags, int w, int h, int sx, int sy, int freesur )
{
   glTexture *texture;
   int rw, rh;
   uint8_t *trans;

   /* Make sure doesn't already exist. */
   if (name != NULL) {
      texture = gl_texExists( name );
      if (texture != NULL)
         return texture;
   }

   /* set up the texture defaults */
   texture = calloc( 1, sizeof(glTexture) );

   /* Map transparency if needed .*/
   if (flags & OPENGL_TEX_MAPTRANS) {
      SDL_LockSurface(surface);
      trans = SDL_MapTrans( surface, w, h );
      SDL_UnlockSurface(surface);
   }
   else
      trans = NULL;

   texture->w     = (double) w;
   texture->h     = (double) h;
   texture->sx    = (double) sx;
   texture->sy    = (double) sy;

   texture->texture = gl_loadSurface( surface, &rw, &rh, flags, freesur );

   texture->rw    = (double) rw;
   texture->rh    = (double) rh;
   texture->sw    = texture->w / texture->sx;
   texture->sh    = texture->h / texture->sy;
   texture->srw   = texture->sw / texture->rw;
   texture->srh   = texture->sh / texture->rh;

   texture->trans = trans;
   if (name != NULL) {
      texture->name = strdup(name);
      gl_texAdd( texture );
   }
   else
      texture->name = NULL;

   return texture;
}
Example #2
0
/**
 * @brief Wrapper for gl_loadImagePad that includes transparency mapping.
 *
 *    @param name Name to load with.
 *    @param surface Surface to load.
 *    @param rw RWops containing data to hash.
 *    @param flags Flags to use.
 *    @param w Non-padded width.
 *    @param h Non-padded height.
 *    @param sx X sprites.
 *    @param sy Y sprites.
 *    @param freesur Whether or not to free the surface.
 *    @return The glTexture for surface.
 */
glTexture* gl_loadImagePadTrans( const char *name, SDL_Surface* surface, SDL_RWops *rw,
      unsigned int flags, int w, int h, int sx, int sy, int freesur )
{
   glTexture *texture;
   int i, filesize;
   size_t cachesize, pngsize;
   uint8_t *trans;
   char *cachefile, *data;
   char digest[33];
   md5_state_t md5;
   md5_byte_t *md5val;

   if (name != NULL) {
      texture = gl_texExists( name );
      if (texture != NULL)
         return texture;
   }

   if (flags & OPENGL_TEX_MAPTRANS)
      flags ^= OPENGL_TEX_MAPTRANS;

   /* Appropriate size for the transparency map, see SDL_MapTrans */
   cachesize = gl_transSize(w, h);

   cachefile = NULL;
   trans     = NULL;

   if (rw != NULL) {
      md5val = malloc(16);
      md5_init(&md5);

      pngsize = SDL_RWseek( rw, 0, SEEK_END );
      SDL_RWseek( rw, 0, SEEK_SET );

      data = malloc(pngsize);
      if (data == NULL)
         WARN("Out of memory!");
      else {
         SDL_RWread( rw, data, pngsize, 1 );
         md5_append( &md5, (md5_byte_t*)data, pngsize );
         free(data);
      }
      md5_finish( &md5, md5val );

      for (i=0; i<16; i++)
         nsnprintf( &digest[i * 2], 3, "%02x", md5val[i] );
      free(md5val);

      cachefile = malloc( PATH_MAX );
      nsnprintf( cachefile, PATH_MAX, "%scollisions/%s",
         nfile_cachePath(), digest );

      /* Attempt to find a cached transparency map. */
      if (nfile_fileExists(cachefile)) {
         trans = (uint8_t*)nfile_readFile( &filesize, cachefile );

         /* Consider cached data invalid if the length doesn't match. */
         if (trans != NULL && cachesize != (unsigned int)filesize) {
            free(trans);
            trans = NULL;
         }
         /* Cached data matches, no need to overwrite. */
         else {
            free(cachefile);
            cachefile = NULL;
         }
      }
   }
   else {
      /* We could hash raw pixel data here, but that's slower than just
       * generating the map from scratch.
       */
      WARN("Texture '%s' has no RWops", name);
   }

   if (trans == NULL) {
      SDL_LockSurface(surface);
      trans = SDL_MapTrans( surface, w, h );
      SDL_UnlockSurface(surface);

      if (cachefile != NULL) {
         /* Cache newly-generated transparency map. */
         nfile_dirMakeExist( "%s/collisions/", nfile_cachePath() );
         nfile_writeFile( (char*)trans, cachesize, cachefile );
         free(cachefile);
      }
   }

   texture = gl_loadImagePad( name, surface, flags, w, h, sx, sy, freesur );
   texture->trans = trans;
   return texture;
}