Merge branch 'fill-copy'

This commit is contained in:
Dmitry Marakasov 2015-06-10 00:08:47 +03:00
commit 0fd5aafea3
5 changed files with 190 additions and 0 deletions

View File

@ -114,6 +114,86 @@ Renderer& Renderer::Copy(Texture& texture, const Optional<Rect>& srcrect, const
return Copy(texture, srcrect, dstrect, angle, center, flip);
}
Renderer& Renderer::FillCopy(Texture& texture, const Optional<Rect>& srcrect, const Optional<Rect>& dstrect, const Point& offset, int flip) {
// resolve rectangles
Rect src = srcrect ? *srcrect : Rect(0, 0, texture.GetWidth(), texture.GetHeight());
Rect dst = dstrect ? *dstrect : Rect(0, 0, GetOutputWidth(), GetOutputHeight());
// rectangle for single tile
Rect start_tile(
offset.x,
offset.y,
src.w,
src.h
);
// ensure tile is leftmost and topmost
if (start_tile.x + start_tile.w <= 0)
start_tile.x += (-start_tile.x) / start_tile.w * start_tile.w;
if (start_tile.x > 0)
start_tile.x -= (start_tile.x + start_tile.w - 1) / start_tile.w * start_tile.w;
if (start_tile.y + start_tile.h <= 0)
start_tile.y += (-start_tile.y) / start_tile.h * start_tile.h;
if (start_tile.y > 0)
start_tile.y -= (start_tile.y + start_tile.h - 1) / start_tile.h * start_tile.h;
// paint tile array
for (int y = start_tile.y; y < dst.h; y += start_tile.h) {
for (int x = start_tile.x; x < dst.w; x += start_tile.w) {
Rect tile_src = src;
Rect tile_dst(x, y, start_tile.w, start_tile.h);
// clamp with dstrect
int xunderflow = -x;
if (xunderflow > 0) {
tile_src.w -= xunderflow;
tile_src.x += xunderflow;
tile_dst.w -= xunderflow;
tile_dst.x += xunderflow;
}
int yunderflow = -y;
if (yunderflow > 0) {
tile_src.h -= yunderflow;
tile_src.y += yunderflow;
tile_dst.h -= yunderflow;
tile_dst.y += yunderflow;
}
int xoverflow = tile_dst.x + tile_dst.w - dst.w;
if (xoverflow > 0) {
tile_src.w -= xoverflow;
tile_dst.w -= xoverflow;
}
int yoverflow = tile_dst.y + tile_dst.h - dst.h;
if (yoverflow > 0) {
tile_src.h -= yoverflow;
tile_dst.h -= yoverflow;
}
// make tile_dst absolute
tile_dst.x += dst.x;
tile_dst.y += dst.y;
if (flip != 0) {
// mirror tile_src inside src to take flipping into account
if (flip & SDL_FLIP_HORIZONTAL)
tile_src.x = src.w - tile_src.x - tile_src.w;
if (flip & SDL_FLIP_VERTICAL)
tile_src.y = src.h - tile_src.y - tile_src.h;
Copy(texture, tile_src, tile_dst, 0.0, NullOpt, flip);
} else {
Copy(texture, tile_src, tile_dst);
}
}
}
return *this;
}
Renderer& Renderer::SetDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
if (SDL_SetRenderDrawColor(renderer_, r, g, b, a) != 0)
throw Exception("SDL_SetRenderDrawColor");

View File

@ -275,6 +275,29 @@ public:
////////////////////////////////////////////////////////////
Renderer& Copy(Texture& texture, const Optional<Rect>& srcrect, const SDL2pp::Point& dstpoint, double angle, const Optional<Point>& center = NullOpt, int flip = 0);
////////////////////////////////////////////////////////////
/// \brief Fill the target with repeated source texture
///
/// \param[in] texture Source texture
/// \param[in] srcrect Source rectangle, NullOpt for the entire texture
/// \param[in] dstrect Destination rectangle, NullOpt for the entire
/// rendering target
/// \param[in] offset Offset of tiled texture in pixels relative to
/// dstrect
/// \param[in] flip SDL_RendererFlip value stating which flipping
/// actions should be performed on the texture
///
/// \returns Reference to self
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_RendererFlip
/// \see http://wiki.libsdl.org/SDL_RenderCopy
/// \see http://wiki.libsdl.org/SDL_RenderCopyEx
///
////////////////////////////////////////////////////////////
Renderer& FillCopy(Texture& texture, const Optional<Rect>& srcrect = NullOpt, const Optional<Rect>& dstrect = NullOpt, const Point& offset = Point(0, 0), int flip = 0);
////////////////////////////////////////////////////////////
/// \brief Set color user for drawing operations
///

View File

@ -18,6 +18,9 @@ TARGET_LINK_LIBRARIES(audio_wav SDL2pp)
IF(SDL2PP_WITH_IMAGE)
ADD_EXECUTABLE(image image.cc)
TARGET_LINK_LIBRARIES(image SDL2pp)
ADD_EXECUTABLE(fill fill.cc)
TARGET_LINK_LIBRARIES(fill SDL2pp)
ENDIF(SDL2PP_WITH_IMAGE)
IF(SDL2PP_WITH_TTF)

84
examples/fill.cc Normal file
View File

@ -0,0 +1,84 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2013-2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <iostream>
#include <cmath>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2pp/SDL.hh>
#include <SDL2pp/SDLImage.hh>
#include <SDL2pp/Window.hh>
#include <SDL2pp/Renderer.hh>
#include <SDL2pp/Texture.hh>
#include <SDL2pp/Surface.hh>
using namespace SDL2pp;
int Run() {
SDL sdl(SDL_INIT_VIDEO);
SDLImage image(IMG_INIT_PNG); // optional
Window window("libSDL2pp demo: fill", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE);
Renderer render(window, -1, SDL_RENDERER_ACCELERATED);
// Load sprite texture; sprite1 and sprite2 are actually the same
// however first one is loaded directly into texture, and second
// one is loaded through an intermediary surface
Surface surf(TESTDATA_DIR "/crate.png");
Texture sprite(render, TESTDATA_DIR "/crate.png");
while (1) {
// Process input
SDL_Event event;
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q)))
return 0;
// Clear screen
render.SetDrawColor(255, 255, 255);
render.Clear();
// Fill
float dx = sin(SDL_GetTicks() / 5000.0 * M_PI) * 32;
float dy = cos(SDL_GetTicks() / 10000.0 * M_PI) * 32;
render.FillCopy(sprite, NullOpt, Rect(32, 32, window.GetWidth() - 64, window.GetHeight() - 64), SDL2pp::Point(dx, dy), SDL_FLIP_HORIZONTAL);
render.Present();
// Frame limiter
SDL_Delay(1);
}
return 0;
}
int main() {
try {
return Run();
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return -1;
}

BIN
testdata/crate.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B