Code: Select all
template<class T, template<class> class RectType, class Func>
void for_each_XY( const RectType<T>& Rect, Func&& Fn )
{
constexpr auto one = static_cast<T>( 1 );
for( T y = Rect.top; y < Rect.bottom; y += one )
{
for( T x = Rect.left; x < Rect.right; x += one )
{
Fn( x, y );
}
}
}
// Usage
template<typename E>
void DrawSprite( int x,int y,RectI srcRect,const RectI& clip,const Surface& s,E effect )
{
assert( srcRect.left >= 0 );
assert( srcRect.right <= s.GetWidth() );
assert( srcRect.top >= 0 );
assert( srcRect.bottom <= s.GetHeight() );
if( x < clip.left )
{
srcRect.left += clip.left - x;
x = clip.left;
}
if( y < clip.top )
{
srcRect.top += clip.top - y;
y = clip.top;
}
if( x + srcRect.GetWidth() > clip.right )
{
srcRect.right -= x + srcRect.GetWidth() - clip.right;
}
if( y + srcRect.GetHeight() > clip.bottom )
{
srcRect.bottom -= y + srcRect.GetHeight() - clip.bottom;
}
auto DrawUsingEffect = [&effect, &s, this]( int X, int Y)
{
effect(
s.GetPixel( sx,sy ),
X + sx - srcRect.left,
Y + sy - srcRect.top,
*this
);
};
for_each_XY(srcRect, DrawUsingEffect);
}
I could take this even further I suppose to make it take in multiple dimensions ( 1D, 2D, 3D ), but the STL already has a std::for_each that handles 1D arrays and I never iterate over 3D arrays, so meh.