Exemplo n.º 1
0
/**
 * @brief Generates an filled circle texture.
 *
 *    @param radius Radius of the circle to generate.
 *    @return The tetxure containing the generated circle.
 */
static glTexture *gl_genCircle( int radius )
{
   int i,j,k, n,m;
   SDL_Surface *sur;
   uint8_t *pix, *buf;
   int h, w;
   double a;
   char name[PATH_MAX];

   /* Calculate parameters. */
   w = 2*radius+1;
   h = 2*radius+1;

   /* Create the surface. */
   sur = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, RGBAMASK );
   pix = sur->pixels;

   /* Generate the circle. */
   SDL_LockSurface( sur );

   /* Create temporary buffer to draw circle in. */
   k = 3;
   buf = malloc( (h*k) * (w*k) );
   for (i=0; i<k*h; i++) {
      for (j=0; j<k*w; j++) {
         if (pow2(i-k*radius)+pow2(j-k*radius) < pow2(k*radius))
            buf[ i*k*w + j] = 0xFF;
      }
   }

   /* Draw the circle with filter. */
   for (i=0; i<h; i++) {
      for (j=0; j<w; j++) {
         /* Calculate blur. */
         a = 0.;
         for (n=0; n<k; n++)
            for (m=0; m<k; m++)
               a += buf[ (i*k+n)*k*w + (j*k+m) ];

         a /= k*k;

         /* Set pixel. */
         pix[i*sur->pitch + j*4 + 0] = 0xFF;
         pix[i*sur->pitch + j*4 + 1] = 0xFF;
         pix[i*sur->pitch + j*4 + 2] = 0xFF;
         pix[i*sur->pitch + j*4 + 3] = (uint8_t)a;
      }
   }

   /* Clean up. */
   free(buf);

   SDL_UnlockSurface( sur );

   /* Return texture. */
   nsnprintf( name, sizeof(name), "gencircle%d", radius );
   return gl_loadImagePad( name, sur, OPENGL_TEX_MIPMAPS, sur->w, sur->h, 1, 1, 1 );
}
Exemplo n.º 2
0
/**
 * @brief Loads the SDL_Surface to a glTexture.
 *
 *    @param surface Surface to load.
 *    @param flags Flags to use.
 *    @return The glTexture for surface.
 */
glTexture* gl_loadImage( SDL_Surface* surface, unsigned int flags )
{
   return gl_loadImagePad( NULL, surface, flags, surface->w, surface->h, 1, 1, 1 );
}
Exemplo n.º 3
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;
}