Implement ~BLEND(r,g,b,o) image path function (bug #11590)

It takes a specified RGB color and blends it with the target image by
certain opacity, specified either as a factor (e.g. 0.25) or percentage
(25%).

I chose BLEND over TINT for consistency with AnimationWML. Feel free to
discuss.
This commit is contained in:
Ignacio R. Morelle 2012-02-08 02:08:11 +00:00
parent 3edb598556
commit 30790b5736
4 changed files with 88 additions and 0 deletions

View file

@ -44,6 +44,9 @@ Version 1.11.0-svn:
* Added [modify_side] color= attribute, which changes a side's team color
range (feature/bug #18772)
* Removed support for the deprecated [removeitem]
* Implemented ~BLEND(r,g,b,o) image path function, which blends the image
with a specified RGB color according to certain opacity (factor or
percentage) (feature/bug #11590)
* Unit changes and balancing:
* New extra_define ENABLE_WOLF_ADVANCEMENT to optionally enable Wolves
advancement to Great Wolves and Direwolves

View file

@ -59,6 +59,14 @@ Xu , Xu , Qxu , Qxu , Ql , Ql
max_hitpoints=90
experience=99
alignment=liminal
[modifications]
[object]
[effect]
apply_to=image_mod
add="BLEND(255,0,255,25%)"
[/effect]
[/object]
[/modifications]
[/leader]
side=1
controller=human

View file

@ -15,6 +15,7 @@
#include "color_range.hpp"
#include "config.hpp"
#include "display.hpp"
#include "foreach.hpp"
#include "game_config.hpp"
#include "image.hpp"
@ -339,6 +340,32 @@ int cs_modification::get_b() const
return b_;
}
surface blend_modification::operator()(const surface& src) const
{
return blend_surface(src, a_, display::rgb(r_, g_, b_));
}
int blend_modification::get_r() const
{
return r_;
}
int blend_modification::get_g() const
{
return g_;
}
int blend_modification::get_b() const
{
return b_;
}
float blend_modification::get_a() const
{
return a_;
}
surface bl_modification::operator()(const surface& src) const
{
return blur_alpha_surface(src, depth_);
@ -586,6 +613,36 @@ REGISTER_MOD_PARSER(CS, args)
return new cs_modification(r, g, b);
}
// Color blending
REGISTER_MOD_PARSER(BLEND, args)
{
const std::vector<std::string>& params = utils::split(args, ',');
if(params.size() != 4) {
ERR_DP << "~BLEND() requires exactly 4 arguments\n";
return NULL;
}
float opacity = 0.0f;
const std::string& opacity_str = params[3];
const std::string::size_type p100_pos = opacity_str.find('%');
if(p100_pos == std::string::npos)
opacity = lexical_cast_default<float>(opacity_str);
else {
// make multiplier
const std::string& parsed_field = opacity_str.substr(0, p100_pos);
opacity = lexical_cast_default<float>(parsed_field);
opacity /= 100.0f;
}
return new blend_modification(
lexical_cast_default<int>(params[0]),
lexical_cast_default<int>(params[1]),
lexical_cast_default<int>(params[2]),
opacity);
}
// Crop/slice
REGISTER_MOD_PARSER(CROP, args)
{

View file

@ -298,6 +298,26 @@ private:
int r_, g_, b_;
};
/**
* Color blending (BLEND) modification
*/
class blend_modification : public modification
{
public:
blend_modification(int r, int g, int b, float a)
: r_(r), g_(g), b_(b), a_(a)
{}
virtual surface operator()(const surface& src) const;
int get_r() const;
int get_g() const;
int get_b() const;
float get_a() const;
private:
int r_, g_, b_;
float a_;
};
/**
* Gaussian-like blur (BL) modification.
*/