Fix rect clipping
This commit is contained in:
parent
89ac57eee7
commit
5d231206ef
4 changed files with 43 additions and 19 deletions
|
@ -108,6 +108,7 @@ target_compile_features(${PROJECT_NAME}
|
|||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE ${PNG_DEFINITIONS}
|
||||
PRIVATE VWR_WITH_IMPLICIT_CONVERSIONS=1
|
||||
)
|
||||
|
||||
configure_file(src/${PROJECT_NAME}Config.h.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.h)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 736e83893a645cce2cc0767237f538785cf8651d
|
||||
Subproject commit 2f4d31967541c9c4a87b2511fb0c6d3792c72c2d
|
|
@ -8,9 +8,23 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#if !defined(NDEBUG)
|
||||
# include "compatibility.h"
|
||||
# include <cmath>
|
||||
# include <limits>
|
||||
#endif
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
#if !defined(NDEBUG)
|
||||
bool are_equal_rel (float parA, float parB, float parEpsilon) a_pure;
|
||||
|
||||
//see: http://stackoverflow.com/questions/4548004/how-to-correctly-and-standardly-compare-floats
|
||||
bool are_equal_rel (float parA, float parB, float parEpsilon) {
|
||||
return (std::fabs(parA - parB) <= parEpsilon * std::max(std::fabs(parA), std::fabs(parB)));
|
||||
}
|
||||
#endif
|
||||
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
bool DoEvents (cloonel::InputBag& parInput, cloonel::SDLMain* parSdlMain) {
|
||||
|
@ -52,6 +66,7 @@ namespace curry {
|
|||
///----------------------------------------------------------------------
|
||||
bool clip_rect (Rect<float>& parSrc, Rect<float>& parDest, const Rect<float>& parClip) {
|
||||
typedef Rect<float> RectFloat;
|
||||
assert(are_equal_rel(parSrc.width(), parDest.width(), std::numeric_limits<float>::epsilon()));
|
||||
assert(parSrc.is_valid());
|
||||
assert(parDest.is_valid());
|
||||
|
||||
|
@ -60,29 +75,34 @@ namespace curry {
|
|||
if (parDest.to <= parClip.from or parDest.from >= parClip.to)
|
||||
return false;
|
||||
|
||||
{
|
||||
const RectFloat clip(vec2f(0.0f), vec2f(1.0f));
|
||||
const vec2f srcWidthHeight(parSrc.width_height());
|
||||
const vec2f scaledOffs((parDest.from - parClip.from) / parClip.width_height());
|
||||
parSrc.from -= vec2f(std::min(0.0f, scaledOffs.x() * srcWidthHeight.x()), std::min(0.0f, scaledOffs.y() * srcWidthHeight.y()));
|
||||
const vec2f scaledCrop((parClip.to - parDest.to) / parClip.width_height());
|
||||
parSrc.to += vec2f(std::min(0.0f, scaledCrop.x() * srcWidthHeight.x()), std::min(0.0f, scaledCrop.y() * srcWidthHeight.y()));
|
||||
assert(parSrc.is_valid());
|
||||
}
|
||||
|
||||
RectFloat dst(parDest.from - parClip.from, parDest.to - parClip.from);
|
||||
dst.from.x() = std::max(dst.from.x(), parClip.from.x());
|
||||
dst.from.y() = std::max(dst.from.y(), parClip.from.y());
|
||||
dst.to.x() = std::min(dst.to.x(), parClip.to.x());
|
||||
dst.to.y() = std::min(dst.to.y(), parClip.to.y());
|
||||
RectFloat dst;
|
||||
dst.from.x() = std::max(parDest.from.x(), parClip.from.x());
|
||||
dst.from.y() = std::max(parDest.from.y(), parClip.from.y());
|
||||
dst.to.x() = std::min(parDest.to.x(), parClip.to.x());
|
||||
dst.to.y() = std::min(parDest.to.y(), parClip.to.y());
|
||||
|
||||
if (not dst.is_valid())
|
||||
return false;
|
||||
|
||||
parDest.from += parClip.from;
|
||||
parDest.to += parClip.from;
|
||||
assert(parDest.from <= dst.from);
|
||||
assert(parDest.to >= dst.to);
|
||||
|
||||
assert(parDest.is_valid());
|
||||
RectFloat src;
|
||||
{
|
||||
const vec2f srcWidthHeight(parSrc.width_height());
|
||||
const vec2f scaledOffs((dst.from - parDest.from) / parDest.width_height());
|
||||
src.from = parSrc.from + scaledOffs * srcWidthHeight;
|
||||
const vec2f scaledCrop((parDest.to - dst.to) / parDest.width_height());
|
||||
src.to = parSrc.to - scaledCrop * srcWidthHeight;
|
||||
assert(src.is_valid());
|
||||
|
||||
assert(dst.is_valid());
|
||||
assert(dst.from >= parClip.from);
|
||||
assert(dst.to <= parClip.to);
|
||||
assert(are_equal_rel(src.width(), dst.width(), std::numeric_limits<float>::epsilon()));
|
||||
}
|
||||
parDest = dst;
|
||||
parSrc = src;
|
||||
return true;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
@ -149,6 +169,8 @@ namespace curry {
|
|||
|
||||
auto src = make_sdlrect(parSrc);
|
||||
auto dst = make_sdlrect(parDest);
|
||||
assert(src.w == dst.w);
|
||||
assert(src.h == dst.h);
|
||||
SDL_RenderCopy(m_sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
||||
}
|
||||
} //namespace curry
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace curry {
|
|||
public:
|
||||
typedef vwr::Vec<std::array<T, 2>> VecType;
|
||||
|
||||
Rect() = default;
|
||||
Rect (T parLeft, T parTop, T parRight, T parBottom);
|
||||
template <typename V1, typename V2>
|
||||
Rect (const vwr::Vec<V1>& parLeftTop, const vwr::Vec<V2>& parBottomRight);
|
||||
|
|
Loading…
Reference in a new issue