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}
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
PRIVATE ${PNG_DEFINITIONS}
|
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)
|
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 <SDL2/SDL.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
# include "compatibility.h"
|
||||||
|
# include <cmath>
|
||||||
|
# include <limits>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
namespace {
|
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) {
|
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) {
|
bool clip_rect (Rect<float>& parSrc, Rect<float>& parDest, const Rect<float>& parClip) {
|
||||||
typedef Rect<float> RectFloat;
|
typedef Rect<float> RectFloat;
|
||||||
|
assert(are_equal_rel(parSrc.width(), parDest.width(), std::numeric_limits<float>::epsilon()));
|
||||||
assert(parSrc.is_valid());
|
assert(parSrc.is_valid());
|
||||||
assert(parDest.is_valid());
|
assert(parDest.is_valid());
|
||||||
|
|
||||||
|
@ -60,29 +75,34 @@ namespace curry {
|
||||||
if (parDest.to <= parClip.from or parDest.from >= parClip.to)
|
if (parDest.to <= parClip.from or parDest.from >= parClip.to)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
{
|
RectFloat dst;
|
||||||
const RectFloat clip(vec2f(0.0f), vec2f(1.0f));
|
dst.from.x() = std::max(parDest.from.x(), parClip.from.x());
|
||||||
const vec2f srcWidthHeight(parSrc.width_height());
|
dst.from.y() = std::max(parDest.from.y(), parClip.from.y());
|
||||||
const vec2f scaledOffs((parDest.from - parClip.from) / parClip.width_height());
|
dst.to.x() = std::min(parDest.to.x(), parClip.to.x());
|
||||||
parSrc.from -= vec2f(std::min(0.0f, scaledOffs.x() * srcWidthHeight.x()), std::min(0.0f, scaledOffs.y() * srcWidthHeight.y()));
|
dst.to.y() = std::min(parDest.to.y(), parClip.to.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());
|
|
||||||
|
|
||||||
if (not dst.is_valid())
|
if (not dst.is_valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
parDest.from += parClip.from;
|
assert(parDest.from <= dst.from);
|
||||||
parDest.to += parClip.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;
|
return true;
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
@ -149,6 +169,8 @@ namespace curry {
|
||||||
|
|
||||||
auto src = make_sdlrect(parSrc);
|
auto src = make_sdlrect(parSrc);
|
||||||
auto dst = make_sdlrect(parDest);
|
auto dst = make_sdlrect(parDest);
|
||||||
|
assert(src.w == dst.w);
|
||||||
|
assert(src.h == dst.h);
|
||||||
SDL_RenderCopy(m_sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
SDL_RenderCopy(m_sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
||||||
}
|
}
|
||||||
} //namespace curry
|
} //namespace curry
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace curry {
|
||||||
public:
|
public:
|
||||||
typedef vwr::Vec<std::array<T, 2>> VecType;
|
typedef vwr::Vec<std::array<T, 2>> VecType;
|
||||||
|
|
||||||
|
Rect() = default;
|
||||||
Rect (T parLeft, T parTop, T parRight, T parBottom);
|
Rect (T parLeft, T parTop, T parRight, T parBottom);
|
||||||
template <typename V1, typename V2>
|
template <typename V1, typename V2>
|
||||||
Rect (const vwr::Vec<V1>& parLeftTop, const vwr::Vec<V2>& parBottomRight);
|
Rect (const vwr::Vec<V1>& parLeftTop, const vwr::Vec<V2>& parBottomRight);
|
||||||
|
|
Loading…
Reference in a new issue