Big optimization of terrain rendering by removing all empty images.
This make screen update (zooming, ToD changes, etc) several times faster, gain some fps (esp. for complex map), optimize some animated terrains (stop refreshing empty parts) and spare some memory (sometimes, not clear yet) Also remove the noise in :layers. Note: This is an improved version of 2010-10-06T16:07:43Z!alinkmaze@gmail.com from the OGL branch
This commit is contained in:
parent
4999183fa0
commit
7ca44f7ac6
7 changed files with 71 additions and 9 deletions
|
@ -89,8 +89,9 @@ public:
|
|||
int get_current_frame_duration() const;
|
||||
int get_current_frame_time() const;
|
||||
const T& get_first_frame() const;
|
||||
const T& get_frame(size_t n) const;
|
||||
const T& get_last_frame() const;
|
||||
int get_frames_count() const;
|
||||
size_t get_frames_count() const;
|
||||
void force_change() {does_not_change_ = false ; }
|
||||
bool does_not_change() const {return does_not_change_;}
|
||||
|
||||
|
|
|
@ -283,6 +283,14 @@ const T& animated<T,T_void_value>::get_first_frame() const
|
|||
return frames_[0].value_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_frame(size_t n) const
|
||||
{
|
||||
if(n >= frames_.size())
|
||||
return void_value_;
|
||||
return frames_[n].value_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_last_frame() const
|
||||
{
|
||||
|
@ -292,7 +300,7 @@ const T& animated<T,T_void_value>::get_last_frame() const
|
|||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_frames_count() const
|
||||
size_t animated<T,T_void_value>::get_frames_count() const
|
||||
{
|
||||
return frames_.size();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,21 @@ void terrain_builder::tile::rebuild_cache(const std::string& tod, logs* log)
|
|||
//need to break parity pattern in RNG
|
||||
/** @todo improve this */
|
||||
unsigned int rnd = ri.rand / 7919; //just the 1000th prime
|
||||
img_list.push_back(variant.images[rnd % variant.images.size()]);
|
||||
const animated<image::locator>& anim = variant.images[rnd % variant.images.size()];
|
||||
|
||||
bool is_empty = true;
|
||||
for(size_t i = 0; i < anim.get_frames_count(); ++i) {
|
||||
if(!image::is_empty_hex(anim.get_frame(i))) {
|
||||
is_empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_empty)
|
||||
continue;
|
||||
|
||||
img_list.push_back(anim);
|
||||
|
||||
if(variant.random_start)
|
||||
img_list.back().set_animation_time(ri.rand % img_list.back().get_animation_duration());
|
||||
|
||||
|
|
|
@ -125,6 +125,9 @@ image::image_cache images_,
|
|||
// cache storing if each image fit in a hex
|
||||
image::bool_cache in_hex_info_;
|
||||
|
||||
// cache storing if this is an empty hex
|
||||
image::bool_cache is_empty_hex_;
|
||||
|
||||
// caches storing the diffrent lighted cases for each image
|
||||
image::lit_cache lit_images_,
|
||||
lit_scaled_images_;
|
||||
|
@ -174,6 +177,7 @@ void flush_cache()
|
|||
lit_images_.flush();
|
||||
lit_scaled_images_.flush();
|
||||
in_hex_info_.flush();
|
||||
is_empty_hex_.flush();
|
||||
mini_terrain_cache.clear();
|
||||
mini_fogged_terrain_cache.clear();
|
||||
reversed_images_.clear();
|
||||
|
@ -572,8 +576,11 @@ surface locator::load_image_sub_file() const
|
|||
srcrect.y += surf->h/2 - val_.center_y_;
|
||||
}
|
||||
|
||||
// cut and hex mask, but also check and cache if empty result
|
||||
surface cut(cut_surface(surf, srcrect));
|
||||
surf = mask_surface(cut, get_hexmask());
|
||||
bool is_empty = false;
|
||||
surf = mask_surface(cut, get_hexmask(), &is_empty);
|
||||
add_to_cache(is_empty_hex_, is_empty);
|
||||
}
|
||||
|
||||
return surf;
|
||||
|
@ -689,8 +696,11 @@ void set_zoom(int amount)
|
|||
static surface get_hexed(const locator& i_locator)
|
||||
{
|
||||
surface image(get_image(i_locator, UNSCALED));
|
||||
// Re-cut scaled tiles according to a mask.
|
||||
return mask_surface(image, get_hexmask());
|
||||
// hex cut tiles, also check and cache if empty result
|
||||
bool is_empty = false;
|
||||
surface res = mask_surface(image, get_hexmask(), &is_empty);
|
||||
i_locator.add_to_cache(is_empty_hex_, is_empty);
|
||||
return res;
|
||||
}
|
||||
|
||||
static surface get_scaled_to_hex(const locator& i_locator)
|
||||
|
@ -929,6 +939,24 @@ bool is_in_hex(const locator& i_locator)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool is_empty_hex(const locator& i_locator)
|
||||
{
|
||||
if(!i_locator.in_cache(is_empty_hex_)) {
|
||||
const surface surf = get_image(i_locator, HEXED);
|
||||
// emptiness of terrain image is checked during hex cut
|
||||
// so, maybe in cache now, let's recheck
|
||||
if(!i_locator.in_cache(is_empty_hex_)) {
|
||||
//should never reach here
|
||||
//but do it manually if it happens
|
||||
//assert(false);
|
||||
bool is_empty = false;
|
||||
mask_surface(surf, get_hexmask(), &is_empty);
|
||||
i_locator.add_to_cache(is_empty_hex_, is_empty);
|
||||
}
|
||||
}
|
||||
return i_locator.locate_in_cache(is_empty_hex_);
|
||||
}
|
||||
|
||||
|
||||
surface reverse_image(const surface& surf)
|
||||
{
|
||||
|
|
|
@ -220,6 +220,10 @@ namespace image {
|
|||
///return false if the image has not the standard size.
|
||||
bool is_in_hex(const locator& i_locator);
|
||||
|
||||
///function to check if an image is empty after hex cut
|
||||
///should be only used on terrain image (cache the hex cut version)
|
||||
bool is_empty_hex(const locator& i_locator);
|
||||
|
||||
///function to reverse an image. The image MUST have originally been returned from
|
||||
///an image:: function. Returned images have the same semantics as for get_image()
|
||||
///and must be freed using SDL_FreeSurface()
|
||||
|
|
|
@ -809,7 +809,7 @@ surface adjust_surface_alpha_add(const surface &surf, int amount, bool optimize)
|
|||
return optimize ? create_optimized_surface(nsurf) : nsurf;
|
||||
}
|
||||
|
||||
surface mask_surface(const surface &surf, const surface &mask)
|
||||
surface mask_surface(const surface &surf, const surface &mask, bool* empty_result)
|
||||
{
|
||||
if(surf == NULL) {
|
||||
return NULL;
|
||||
|
@ -835,6 +835,7 @@ surface mask_surface(const surface &surf, const surface &mask)
|
|||
return nsurf;
|
||||
}
|
||||
|
||||
bool empty = true;
|
||||
{
|
||||
surface_lock lock(nsurf);
|
||||
const_surface_lock mlock(nmask);
|
||||
|
@ -854,7 +855,11 @@ surface mask_surface(const surface &surf, const surface &mask)
|
|||
b = (*beg);
|
||||
|
||||
Uint8 malpha = (*mbeg) >> 24;
|
||||
if (alpha > malpha) alpha = malpha;
|
||||
if (alpha > malpha) {
|
||||
alpha = malpha;
|
||||
}
|
||||
if(alpha)
|
||||
empty = false;
|
||||
|
||||
*beg = (alpha << 24) + (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
@ -863,6 +868,8 @@ surface mask_surface(const surface &surf, const surface &mask)
|
|||
++mbeg;
|
||||
}
|
||||
}
|
||||
if(empty_result)
|
||||
*empty_result = empty;
|
||||
|
||||
return nsurf;
|
||||
//return create_optimized_surface(nsurf);
|
||||
|
|
|
@ -228,7 +228,7 @@ surface adjust_surface_alpha(const surface &surf, fixed_t amount, bool optimize=
|
|||
surface adjust_surface_alpha_add(const surface &surf, int amount, bool optimize=true);
|
||||
|
||||
/** Applies a mask on a surface. */
|
||||
surface mask_surface(const surface &surf, const surface &mask);
|
||||
surface mask_surface(const surface &surf, const surface &mask, bool* empty_result = NULL);
|
||||
|
||||
/** Check if a surface fit into a mask */
|
||||
bool in_mask_surface(const surface &surf, const surface &mask);
|
||||
|
|
Loading…
Add table
Reference in a new issue