mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-27 18:28:35 +00:00
Hardware acceleration for unit highlight effect
Uses some tricks to increase brightness by blitting twice.
This commit is contained in:
parent
0fbc12ea01
commit
046f1c932a
@ -1201,23 +1201,20 @@ void display::get_terrain_images(const map_location& loc, const std::string& tim
|
||||
}
|
||||
}
|
||||
|
||||
void display::drawing_buffer_add(const drawing_layer layer,
|
||||
display::blit_helper& display::drawing_buffer_add(const drawing_layer layer,
|
||||
const map_location& loc, const SDL_Rect& dest, const texture& tex,
|
||||
const SDL_Rect &clip, bool hflip, bool vflip, uint8_t alpha_mod)
|
||||
const SDL_Rect &clip)
|
||||
{
|
||||
drawing_buffer_.emplace_back(
|
||||
layer, loc, dest, tex, clip, hflip, vflip, alpha_mod
|
||||
);
|
||||
drawing_buffer_.emplace_back(layer, loc, dest, tex, clip);
|
||||
return drawing_buffer_.back();
|
||||
}
|
||||
|
||||
void display::drawing_buffer_add(const drawing_layer layer,
|
||||
display::blit_helper& display::drawing_buffer_add(const drawing_layer layer,
|
||||
const map_location& loc, const SDL_Rect& dest,
|
||||
const std::vector<texture> &tex,
|
||||
const SDL_Rect &clip, bool hflip, bool vflip, uint8_t alpha_mod)
|
||||
const std::vector<texture> &tex, const SDL_Rect &clip)
|
||||
{
|
||||
drawing_buffer_.emplace_back(
|
||||
layer, loc, dest, tex, clip, hflip, vflip, alpha_mod
|
||||
);
|
||||
drawing_buffer_.emplace_back(layer, loc, dest, tex, clip);
|
||||
return drawing_buffer_.back();
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -1296,18 +1293,27 @@ void display::drawing_buffer_commit()
|
||||
for(const blit_helper& blit : drawing_buffer_) {
|
||||
for(texture tex : blit.tex()) {
|
||||
const SDL_Rect& src = blit.clip();
|
||||
const uint8_t alpha_mod = blit.alpha_mod();
|
||||
const bool hflip = blit.hflip();
|
||||
const bool vflip = blit.vflip();
|
||||
if (alpha_mod != SDL_ALPHA_OPAQUE) {
|
||||
tex.set_alpha_mod(alpha_mod);
|
||||
if (blit.alpha_mod != SDL_ALPHA_OPAQUE) {
|
||||
tex.set_alpha_mod(blit.alpha_mod);
|
||||
}
|
||||
if (src != sdl::empty_rect) {
|
||||
draw::flipped(tex, blit.dest(), src, hflip, vflip);
|
||||
draw::flipped(tex, blit.dest(), src, blit.hflip, blit.vflip);
|
||||
if (blit.highlight) {
|
||||
tex.set_blend_mode(SDL_BLENDMODE_ADD);
|
||||
tex.set_alpha_mod(blit.highlight);
|
||||
draw::flipped(tex, blit.dest(), src, blit.hflip, blit.vflip);
|
||||
tex.set_blend_mode(SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
} else {
|
||||
draw::flipped(tex, blit.dest(), hflip, vflip);
|
||||
draw::flipped(tex, blit.dest(), blit.hflip, blit.vflip);
|
||||
if (blit.highlight) {
|
||||
tex.set_blend_mode(SDL_BLENDMODE_ADD);
|
||||
tex.set_alpha_mod(blit.highlight);
|
||||
draw::flipped(tex, blit.dest(), blit.hflip, blit.vflip);
|
||||
tex.set_blend_mode(SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
if (alpha_mod != SDL_ALPHA_OPAQUE) {
|
||||
if (blit.alpha_mod != SDL_ALPHA_OPAQUE || blit.highlight) {
|
||||
tex.set_alpha_mod(SDL_ALPHA_OPAQUE);
|
||||
}
|
||||
}
|
||||
@ -1508,8 +1514,8 @@ void display::draw_text_in_hex(const map_location& loc,
|
||||
for (int dx=-1; dx <= 1; ++dx) {
|
||||
if (dx!=0 || dy!=0) {
|
||||
const SDL_Rect dest{int(x + dx*zf), int(y + dy*zf), w, h};
|
||||
drawing_buffer_add(layer, loc, dest, back_surf,
|
||||
SDL_Rect(), false, false, 128);
|
||||
auto& bh = drawing_buffer_add(layer, loc, dest, back_surf);
|
||||
bh.alpha_mod = 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1521,12 +1527,15 @@ void display::render_image(int x, int y, const display::drawing_layer drawing_la
|
||||
bool hreverse, bool greyscale, uint8_t alpha, double highlight,
|
||||
color_t blendto, double blend_ratio, double submerged, bool vreverse)
|
||||
{
|
||||
if (alpha <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const point image_size = image::get_size(i_locator);
|
||||
if (!image_size.x || !image_size.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: highdpi - are x,y correct here?
|
||||
rect dest = scaled_to_zoom({x, y, image_size.x, image_size.y});
|
||||
if (!dest.overlaps(map_area())) {
|
||||
return;
|
||||
@ -1557,21 +1566,6 @@ void display::render_image(int x, int y, const display::drawing_layer drawing_la
|
||||
new_modifications += ")";
|
||||
}
|
||||
|
||||
// TODO: highdpi - perhaps this can be done by blitting twice, once in additive blend mode
|
||||
// Note: this may not be identical to the original calculation,
|
||||
// which was to multiply the RGB values by (alpha/255).
|
||||
// But for now it looks close enough.
|
||||
if(highlight > 0.0) {
|
||||
const std::string brighten_string = std::to_string(int(highlight*128.0));
|
||||
new_modifications += "~CS(";
|
||||
new_modifications += brighten_string;
|
||||
new_modifications += ",";
|
||||
new_modifications += brighten_string;
|
||||
new_modifications += ",";
|
||||
new_modifications += brighten_string;
|
||||
new_modifications += ")";
|
||||
}
|
||||
|
||||
// general formula for submerged alpha:
|
||||
// if (y > WATERLINE)
|
||||
// then min(max(alpha_mod, 0), 1) * alpha
|
||||
@ -1604,8 +1598,11 @@ void display::render_image(int x, int y, const display::drawing_layer drawing_la
|
||||
tex = image::get_texture(i_locator);
|
||||
}
|
||||
|
||||
drawing_buffer_add(drawing_layer, loc, dest, tex, sdl::empty_rect,
|
||||
hreverse, vreverse, alpha);
|
||||
blit_helper& bh = drawing_buffer_add(drawing_layer, loc, dest, tex);
|
||||
bh.hflip = hreverse;
|
||||
bh.vflip = vreverse;
|
||||
bh.alpha_mod = alpha;
|
||||
bh.highlight = float_to_color(highlight);
|
||||
}
|
||||
|
||||
void display::select_hex(map_location hex)
|
||||
@ -2620,8 +2617,9 @@ void display::draw_hex(const map_location& loc)
|
||||
&& bool(mouseover_hex_overlay_))
|
||||
{
|
||||
const uint8_t alpha = 196;
|
||||
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, dest,
|
||||
mouseover_hex_overlay_, SDL_Rect(), false, false, alpha);
|
||||
blit_helper& bh = drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY,
|
||||
loc, dest, mouseover_hex_overlay_);
|
||||
bh.alpha_mod = alpha;
|
||||
}
|
||||
|
||||
// Paint arrows
|
||||
|
@ -926,30 +926,41 @@ protected:
|
||||
|
||||
blit_helper(const drawing_layer layer, const map_location& loc,
|
||||
const SDL_Rect& dest, const texture& tex,
|
||||
const SDL_Rect& clip, bool hflip=false, bool vflip=false,
|
||||
uint8_t alpha_mod=SDL_ALPHA_OPAQUE)
|
||||
: dest_(dest), tex_(1, tex), clip_(clip), hflip_(hflip),
|
||||
vflip_(vflip), alpha_mod_(alpha_mod), key_(loc, layer)
|
||||
const SDL_Rect& clip)
|
||||
: dest_(dest), tex_(1, tex), clip_(clip), key_(loc, layer)
|
||||
{}
|
||||
|
||||
blit_helper(const drawing_layer layer, const map_location& loc,
|
||||
const SDL_Rect& dest, const std::vector<texture>& tex,
|
||||
const SDL_Rect& clip, bool hflip=false, bool vflip=false,
|
||||
uint8_t alpha_mod=SDL_ALPHA_OPAQUE)
|
||||
: dest_(dest), tex_(tex), clip_(clip), hflip_(hflip),
|
||||
vflip_(vflip), alpha_mod_(alpha_mod), key_(loc, layer)
|
||||
const SDL_Rect& clip)
|
||||
: dest_(dest), tex_(tex), clip_(clip), key_(loc, layer)
|
||||
{}
|
||||
|
||||
const SDL_Rect& dest() const { return dest_; }
|
||||
const std::vector<texture> &tex() const { return tex_; }
|
||||
const SDL_Rect &clip() const { return clip_; }
|
||||
uint8_t alpha_mod() const { return alpha_mod_; }
|
||||
bool hflip() const { return hflip_; }
|
||||
bool vflip() const { return vflip_; }
|
||||
|
||||
bool operator<(const blit_helper &rhs) const { return key_ < rhs.key_; }
|
||||
|
||||
public:
|
||||
// Auxiliary parameters, can be modified directly as required.
|
||||
|
||||
/** Whether to mirror horizontally on draw */
|
||||
bool hflip = false;
|
||||
/** Whether to mirror vertically on draw */
|
||||
bool vflip = false;
|
||||
/** An alpha modifier to apply when drawing. 0-255. */
|
||||
uint8_t alpha_mod = SDL_ALPHA_OPAQUE;
|
||||
/** Colour modifiers. Multiply colour. 0 = 0.0, 255 = 1.0. */
|
||||
uint8_t r_mod = 255;
|
||||
uint8_t g_mod = 255;
|
||||
uint8_t b_mod = 255;
|
||||
/** Strength of highlight effect to apply, if any. */
|
||||
uint8_t highlight = 0;
|
||||
|
||||
private:
|
||||
// Core info is set on creation.
|
||||
|
||||
/** The location on screen to draw to, in drawing coordinates. */
|
||||
SDL_Rect dest_;
|
||||
/** One or more textures to render. */
|
||||
@ -957,13 +968,7 @@ protected:
|
||||
/** The portion of the source texture to use.
|
||||
* If omitted, the entire source is used. */
|
||||
SDL_Rect clip_;
|
||||
/** Whether to mirror horizontally on draw */
|
||||
bool hflip_;
|
||||
/** Whether to mirror vertically on draw */
|
||||
bool vflip_;
|
||||
/** An alpha modifier to apply when drawing. 0-255. */
|
||||
uint8_t alpha_mod_;
|
||||
// TODO: highdpi - colour mod? blend mode? rotation?
|
||||
// TODO: could also add blend mode and rotation if desirable
|
||||
/** Allows ordering of draw calls by layer and location. */
|
||||
drawing_buffer_key key_;
|
||||
};
|
||||
@ -987,16 +992,14 @@ public:
|
||||
* @param alpha_mod An alpha modifier to apply - multiplies
|
||||
* texture alpha by this value when drawing.
|
||||
*/
|
||||
void drawing_buffer_add(const drawing_layer layer,
|
||||
blit_helper& drawing_buffer_add(const drawing_layer layer,
|
||||
const map_location& loc, const SDL_Rect& dest, const texture& tex,
|
||||
const SDL_Rect &clip = SDL_Rect(), bool hflip=false,
|
||||
bool vflip=false, uint8_t alpha_mod=SDL_ALPHA_OPAQUE);
|
||||
const SDL_Rect &clip = SDL_Rect());
|
||||
|
||||
void drawing_buffer_add(const drawing_layer layer,
|
||||
blit_helper& drawing_buffer_add(const drawing_layer layer,
|
||||
const map_location& loc, const SDL_Rect& dest,
|
||||
const std::vector<texture> &tex,
|
||||
const SDL_Rect &clip = SDL_Rect(), bool hflip=false,
|
||||
bool vflip=false, uint8_t alpha_mod=SDL_ALPHA_OPAQUE);
|
||||
const SDL_Rect &clip = SDL_Rect());
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user