mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-12 11:17:57 +00:00
Implement a mirror mode for tiling textures.
It mirrors such that tiles always share a common edge. This isn't currently used for anything, simply included for completeness.
This commit is contained in:
parent
638c02b59e
commit
743a1b5655
36
src/draw.cpp
36
src/draw.cpp
@ -241,6 +241,15 @@ void draw::blit(const texture& tex)
|
||||
}
|
||||
|
||||
|
||||
static SDL_RendererFlip get_flip(bool flip_h, bool flip_v)
|
||||
{
|
||||
// This should be easier than it is.
|
||||
return static_cast<SDL_RendererFlip>(
|
||||
static_cast<int>(flip_h ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE)
|
||||
| static_cast<int>(flip_v ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE)
|
||||
);
|
||||
}
|
||||
|
||||
void draw::flipped(
|
||||
const texture& tex,
|
||||
const SDL_Rect& dst,
|
||||
@ -248,9 +257,7 @@ void draw::flipped(
|
||||
bool flip_h,
|
||||
bool flip_v)
|
||||
{
|
||||
SDL_RendererFlip flip =
|
||||
flip_h ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE
|
||||
| flip_v ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
|
||||
SDL_RenderCopyEx(renderer(), tex, &src, &dst, 0.0, nullptr, flip);
|
||||
}
|
||||
|
||||
@ -260,22 +267,19 @@ void draw::flipped(
|
||||
bool flip_h,
|
||||
bool flip_v)
|
||||
{
|
||||
SDL_RendererFlip flip =
|
||||
flip_h ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE
|
||||
| flip_v ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
|
||||
SDL_RenderCopyEx(renderer(), tex, nullptr, &dst, 0.0, nullptr, flip);
|
||||
}
|
||||
|
||||
void draw::flipped(const texture& tex, bool flip_h, bool flip_v)
|
||||
{
|
||||
SDL_RendererFlip flip =
|
||||
flip_h ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE
|
||||
| flip_v ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
|
||||
SDL_RenderCopyEx(renderer(), tex, nullptr, nullptr, 0.0, nullptr, flip);
|
||||
}
|
||||
|
||||
|
||||
void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered)
|
||||
void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered,
|
||||
bool mirrored)
|
||||
{
|
||||
// TODO: highdpi - should this draw at full res? Or game res? For now it's using game res to ensure consistency of the result.
|
||||
// TODO: highdpi - does this ever need to clip the source texture? It doesn't seem so
|
||||
@ -284,10 +288,16 @@ void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered)
|
||||
const int yoff = centered ? (dst.h - tex.h()) / 2 : 0;
|
||||
|
||||
// Just blit the image however many times is necessary.
|
||||
bool vf = false;
|
||||
SDL_Rect t{dst.x - xoff, dst.y - yoff, tex.w(), tex.h()};
|
||||
for (; t.y < dst.y + dst.h; t.y += tex.h()) {
|
||||
for (t.x = dst.x - xoff; t.x < dst.x + dst.w; t.x += tex.w()) {
|
||||
draw::blit(tex, t);
|
||||
for (; t.y < dst.y + dst.h; t.y += t.h, vf = !vf) {
|
||||
bool hf = false;
|
||||
for (t.x = dst.x - xoff; t.x < dst.x + dst.w; t.x += t.w, hf = !hf) {
|
||||
if (mirrored) {
|
||||
draw::flipped(tex, t, hf, vf);
|
||||
} else {
|
||||
draw::blit(tex, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +295,15 @@ void flipped(const texture& tex, bool flip_h = true, bool flip_v = false);
|
||||
* @param dst The region to fill, in draw space.
|
||||
* @param centered If true the tiled texture will be centered.
|
||||
* If false, it will align at the top-left.
|
||||
* @param mirrored If true the texture will be mirrored in such a way that
|
||||
* adjacent tiles always share a common edge. This can look
|
||||
* better for images that are not perfect tiles.
|
||||
*/
|
||||
void tiled(const texture& tex, const SDL_Rect& dst, bool centered = false);
|
||||
void tiled(const texture& tex,
|
||||
const SDL_Rect& dst,
|
||||
bool centered = false,
|
||||
bool mirrored = false
|
||||
);
|
||||
|
||||
|
||||
} // namespace draw
|
||||
|
@ -413,26 +413,18 @@ void image_shape::draw(
|
||||
|
||||
// TODO: highdpi - clipping?
|
||||
|
||||
if (mirror_(variables) && (resize_mode_ == resize_mode::tile
|
||||
|| resize_mode_ == resize_mode::tile_center)) {
|
||||
// Not difficult to implement, but will anyone ever use it?
|
||||
WRN_GUI_D << "mirrored tiling images unimplemented" << std::endl;
|
||||
}
|
||||
|
||||
// What to do with the image depends on whether we need to tile it or not.
|
||||
switch (resize_mode_) {
|
||||
case (resize_mode::tile):
|
||||
draw::tiled(tex, adjusted_draw_loc, false);
|
||||
draw::tiled(tex, adjusted_draw_loc, false, mirror_(variables));
|
||||
break;
|
||||
case (resize_mode::tile_center):
|
||||
draw::tiled(tex, adjusted_draw_loc, true);
|
||||
draw::tiled(tex, adjusted_draw_loc, true, mirror_(variables));
|
||||
break;
|
||||
case (resize_mode::stretch):
|
||||
case (resize_mode::scale):
|
||||
case (resize_mode::scale_sharp):
|
||||
// TODO: highdpi - examine the necessity of doing this here. It is better to set the filtering mode per-texture, rather than per-draw.
|
||||
// TODO: highdpi - texture API to set filtering mode, if actually needed
|
||||
// TODO: highdpi - set texture filtering here, if this is desirable
|
||||
// TODO: highdpi - SDL requires that filtering mode be set per-texture, at texture creation. This will require either texture caches according to filtering mode, or an overhaul in how filtering type is requested so that the filter mode is specified as part of image loading, not image drawing.
|
||||
// TODO: highdpi - is there any real difference between scale and stretch?
|
||||
if (mirror_(variables)) {
|
||||
draw::flipped(tex, adjusted_draw_loc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user