/** * @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; }
/** * @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; /* Make sure doesn't already exist. */ if (name != NULL) { texture = gl_texExists( name ); if (texture != NULL) return texture; } if (flags & OPENGL_TEX_MAPTRANS) return gl_loadImagePadTrans( name, surface, NULL, flags, w, h, sx, sy, freesur ); /* set up the texture defaults */ texture = calloc( 1, sizeof(glTexture) ); 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; if (name != NULL) { texture->name = strdup(name); gl_texAdd( texture ); } else texture->name = NULL; return texture; }
/** * @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; }