image: Use get_surface to load texture images.
The texture-only code was missing huge sections, and otherwise a direct duplication. If it is desired that surfaces do not get cached when loading textures, then an option should be added to get_surface to explicitly disable caching.
This commit is contained in:
parent
cb164b4d82
commit
3530d6f3ff
1 changed files with 7 additions and 195 deletions
202
src/picture.cpp
202
src/picture.cpp
|
@ -1122,8 +1122,9 @@ save_result save_image(const surface& surf, const std::string& filename)
|
|||
/*
|
||||
* TEXTURE INTERFACE ======================================================================
|
||||
*
|
||||
* I'm keeping this separate from the surface-based handling above since the two approaches
|
||||
* are so different. Might move this to a file of its own in the future.
|
||||
* The only important difference here is that textures must have their
|
||||
* scale quality set before creation. All other handling is done by
|
||||
* get_surface.
|
||||
*/
|
||||
namespace
|
||||
{
|
||||
|
@ -1136,161 +1137,6 @@ void set_scale_quality_pre_texture_creation(scale_quality quality)
|
|||
set_texture_scale_quality(quality == scale_quality::nearest ? n_scale_str : l_scale_str);
|
||||
}
|
||||
|
||||
/** Loads a new texture directly from disk. */
|
||||
texture create_texture_from_file(const image::locator& loc)
|
||||
{
|
||||
texture res;
|
||||
|
||||
// We need the window renderer to load the texture.
|
||||
SDL_Renderer* renderer = CVideo::get_singleton().get_renderer();
|
||||
if(!renderer) {
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string location = filesystem::get_binary_file_location("images", loc.get_filename());
|
||||
|
||||
if(!location.empty()) {
|
||||
#if 0
|
||||
// Check if there is a localized image.
|
||||
const std::string loc_location = get_localized_path(location);
|
||||
if(!loc_location.empty()) {
|
||||
location = loc_location;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: if we need to use SDL_RWops we should use IMG_LoadTexture_RW here instead.
|
||||
{
|
||||
res.assign(IMG_LoadTexture(renderer, location.c_str()));
|
||||
}
|
||||
|
||||
// TODO: decide what to do about this.
|
||||
#if 0
|
||||
// If there was no standalone localized image, check if there is an overlay.
|
||||
if(!res.null() && loc_location.empty()) {
|
||||
const std::string ovr_location = get_localized_path(location, "--overlay");
|
||||
if(!ovr_location.empty()) {
|
||||
add_localized_overlay(ovr_location, res);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!res && !loc.get_filename().empty()) {
|
||||
ERR_DP << "Could not load texture for image '" << loc.get_filename() << "'" << std::endl;
|
||||
|
||||
// Also decide what to do here.
|
||||
#if 0
|
||||
if(game_config::debug && loc.get_filename() != game_config::images::missing) {
|
||||
return get_texture(game_config::images::missing, UNSCALED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle IPF manipulation. Since we don't have shaders yet, we need to use the surface
|
||||
* modification code for now. It appears each result is saved in the relevant cache,
|
||||
* so this should hopefully only result in a small slowdown when first processing the
|
||||
* results.
|
||||
*/
|
||||
texture create_texture_from_sub_file(const image::locator& loc)
|
||||
{
|
||||
surface surf = get_image(loc.get_filename(), UNSCALED);
|
||||
if(surf == nullptr) {
|
||||
return texture();
|
||||
}
|
||||
|
||||
modification_queue mods = modification::decode(loc.get_modifications());
|
||||
|
||||
while(!mods.empty()) {
|
||||
modification* mod = mods.top();
|
||||
|
||||
try {
|
||||
surf = (*mod)(surf);
|
||||
} catch(const image::modification::imod_exception& e) {
|
||||
std::ostringstream ss;
|
||||
ss << "\n";
|
||||
|
||||
for(const std::string& mod2 : utils::parenthetical_split(loc.get_modifications(), '~')) {
|
||||
ss << "\t" << mod2 << "\n";
|
||||
}
|
||||
|
||||
ERR_CFG << "Failed to apply a modification to an image:\n"
|
||||
<< "Image: " << loc.get_filename() << "\n"
|
||||
<< "Modifications: " << ss.str() << "\n"
|
||||
<< "Error: " << e.message << "\n";
|
||||
}
|
||||
|
||||
// NOTE: do this *after* applying the mod or you'll get crashes!
|
||||
mods.pop();
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(loc.get_loc().valid()) {
|
||||
SDL_Rect srcrect = sdl::create_rect(
|
||||
((tile_size * 3) / 4) * loc.get_loc().x,
|
||||
tile_size * loc.get_loc().y + (tile_size / 2) * (loc.get_loc().x % 2),
|
||||
tile_size,
|
||||
tile_size
|
||||
);
|
||||
|
||||
if(loc.get_center_x() >= 0 && loc.get_center_y() >= 0) {
|
||||
srcrect.x += surf->w / 2 - loc.get_center_x();
|
||||
srcrect.y += surf->h / 2 - loc.get_center_y();
|
||||
}
|
||||
|
||||
// cut and hex mask, but also check and cache if empty result
|
||||
surface cut(cut_surface(surf, srcrect));
|
||||
bool is_empty = false;
|
||||
surf = mask_surface(cut, get_hexmask(), &is_empty);
|
||||
|
||||
// discard empty images to free memory
|
||||
if(is_empty) {
|
||||
// Safe because those images are only used by terrain rendering
|
||||
// and it filters them out.
|
||||
// A safer and more general way would be to keep only one copy of it
|
||||
surf = nullptr;
|
||||
}
|
||||
|
||||
loc.add_to_cache(is_empty_hex_, is_empty);
|
||||
}
|
||||
#endif
|
||||
|
||||
return texture(surf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Small wrapper for creating a texture after applying a specific type of surface op.
|
||||
* Won't be necessary once we get shader support.
|
||||
*/
|
||||
texture create_texture_post_surface_op(const image::locator& i_locator, TYPE type)
|
||||
{
|
||||
surface surf = get_image(i_locator, type);
|
||||
if(!surf) {
|
||||
return texture();
|
||||
}
|
||||
|
||||
return texture(surf);
|
||||
}
|
||||
|
||||
texture create_texture_from_disk(const locator& loc)
|
||||
{
|
||||
switch(loc.get_type()) {
|
||||
case locator::FILE:
|
||||
if(loc.is_data_uri()){
|
||||
return texture(load_image_data_uri(loc));
|
||||
} else {
|
||||
return create_texture_from_file(loc);
|
||||
}
|
||||
case locator::SUB_FILE:
|
||||
return create_texture_from_sub_file(loc);
|
||||
default:
|
||||
return texture();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
texture get_texture(const image::locator& i_locator, TYPE type)
|
||||
|
@ -1307,8 +1153,7 @@ texture get_texture(const image::locator& i_locator, scale_quality quality, TYPE
|
|||
return res;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
//type = simplify_type(i_locator, type);
|
||||
type = simplify_type(i_locator, type);
|
||||
|
||||
//
|
||||
// Select the appropriate cache. We don't need caches for every single image types,
|
||||
|
@ -1344,43 +1189,10 @@ texture get_texture(const image::locator& i_locator, scale_quality quality, TYPE
|
|||
//
|
||||
set_scale_quality_pre_texture_creation(quality);
|
||||
|
||||
switch(type) {
|
||||
case TOD_COLORED:
|
||||
case HEXED:
|
||||
res = create_texture_post_surface_op(i_locator, type);
|
||||
break;
|
||||
default:
|
||||
res = create_texture_from_disk(i_locator);
|
||||
}
|
||||
// Get it from the surface cache.
|
||||
res = texture(get_surface(i_locator, type));
|
||||
|
||||
// If the texture is null at this point, return without any further action (like caching).
|
||||
if(!res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply the appropriate render flags. (TODO)
|
||||
//
|
||||
#if 0
|
||||
switch(type) {
|
||||
case SCALED_TO_ZOOM:
|
||||
|
||||
break;
|
||||
case SCALED_TO_HEX:
|
||||
|
||||
break;
|
||||
case BRIGHTENED:
|
||||
|
||||
break;
|
||||
default:
|
||||
// Ignore other types.
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// And finally add the texture to the cache.
|
||||
//
|
||||
// Cache the texture.
|
||||
i_locator.add_to_cache(*cache, res);
|
||||
|
||||
return res;
|
||||
|
|
Loading…
Add table
Reference in a new issue