Merge branch 'surface'

Conflicts:
	CMakeLists.txt
This commit is contained in:
Dmitry Marakasov 2014-12-28 04:29:07 +03:00
commit 0557464b56
11 changed files with 827 additions and 6 deletions

View File

@ -99,6 +99,8 @@ SET(LIBRARY_SOURCES
SDL2pp/Renderer.cc
SDL2pp/SDL.cc
SDL2pp/SDLImage.cc
SDL2pp/Surface.cc
SDL2pp/SurfaceLock.cc
SDL2pp/Texture.cc
SDL2pp/TextureLock.cc
SDL2pp/Wav.cc
@ -119,6 +121,7 @@ SET(LIBRARY_HEADERS
SDL2pp/SDL2pp.hh
SDL2pp/SDLImage.hh
SDL2pp/StreamRWops.hh
SDL2pp/Surface.hh
SDL2pp/Texture.hh
SDL2pp/Wav.hh
SDL2pp/Window.hh

View File

@ -30,6 +30,11 @@ Point::Point() {
y = 0;
}
Point::Point(const SDL_Point& point) {
x = point.x;
y = point.y;
}
Point::Point(int nx, int ny) {
x = nx;
y = ny;

View File

@ -54,6 +54,14 @@ public:
////////////////////////////////////////////////////////////
Point();
////////////////////////////////////////////////////////////
/// \brief Construct a point from existing SDL_Point
///
/// \param point Existing SDL_Point
///
////////////////////////////////////////////////////////////
Point(const SDL_Point& point);
////////////////////////////////////////////////////////////
/// \brief Construct the point from given coordinates
///

View File

@ -34,6 +34,13 @@ Rect::Rect() {
h = 0;
}
Rect::Rect(const SDL_Rect& rect) {
x = rect.x;
y = rect.y;
w = rect.w;
h = rect.h;
}
Rect::Rect(int nx, int ny, int nw, int nh) {
x = nx;
y = ny;

View File

@ -58,6 +58,14 @@ public:
////////////////////////////////////////////////////////////
Rect();
////////////////////////////////////////////////////////////
/// \brief Construct a rect from existing SDL_Rect
///
/// \param rect Existing SDL_Rect
///
////////////////////////////////////////////////////////////
Rect(const SDL_Rect& rect);
////////////////////////////////////////////////////////////
/// \brief Construct the rect from given corner coordinates, width and height
///

196
SDL2pp/Surface.cc Normal file
View File

@ -0,0 +1,196 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2014 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 <vector>
#include <SDL2pp/Config.hh>
#include <SDL2/SDL_surface.h>
#ifdef SDL2PP_WITH_IMAGE
# include <SDL2/SDL_image.h>
#endif
#include <SDL2pp/Surface.hh>
#include <SDL2pp/Exception.hh>
#ifdef SDL2PP_WITH_IMAGE
# include <SDL2pp/RWops.hh>
#endif
namespace SDL2pp {
Surface::Surface(SDL_Surface* surface) : surface_(surface) {
}
Surface::Surface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) {
if ((surface_ = SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask)) == nullptr)
throw Exception("SDL_CreateRGBSurface failed");
}
Surface::Surface(void* pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) {
if ((surface_ = SDL_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask)) == nullptr)
throw Exception("SDL_CreateRGBSurfaceFrom failed");
}
#ifdef SDL2PP_WITH_IMAGE
Surface::Surface(RWops& rwops) {
if ((surface_ = IMG_Load_RW(rwops.Get(), 0)) == nullptr)
throw Exception("IMG_Load_RW failed");
}
Surface::Surface(const std::string& path) {
if ((surface_ = IMG_Load(path.c_str())) == nullptr)
throw Exception("IMG_Load failed");
}
#endif
Surface::~Surface() {
if (surface_ != nullptr)
SDL_FreeSurface(surface_);
}
Surface::Surface(Surface&& other) noexcept : surface_(other.surface_) {
other.surface_ = nullptr;
}
Surface& Surface::operator=(Surface&& other) noexcept {
if (&other == this)
return *this;
if (surface_ != nullptr)
SDL_FreeSurface(surface_);
surface_ = other.surface_;
other.surface_ = nullptr;
return *this;
}
SDL_Surface* Surface::Get() const {
return surface_;
}
Surface Surface::Convert(const SDL_PixelFormat& format) {
SDL_Surface* surface = SDL_ConvertSurface(surface_, &format, 0);
if (surface == nullptr)
throw Exception("SDL_ConvertPixels failed");
return surface;
}
Surface Surface::Convert(Uint32 pixel_format) {
SDL_Surface* surface = SDL_ConvertSurfaceFormat(surface_, pixel_format, 0);
if (surface == nullptr)
throw Exception("SDL_ConvertPixels failed");
return surface;
}
void Surface::Blit(const Optional<Rect>& srcrect, Surface& dst, const Rect& dstrect) {
SDL_Rect tmpdstrect = dstrect; // 4th argument is non-const; does it modify rect?
if (SDL_BlitSurface(surface_, srcrect ? &*srcrect : nullptr, dst.Get(), &tmpdstrect) != 0)
throw Exception("SDL_BlitSurface failed");
}
void Surface::BlitScaled(const Optional<Rect>& srcrect, Surface& dst, const Optional<Rect>& dstrect) {
SDL_Rect tmpdstrect; // 4th argument is non-const; does it modify rect?
if (dstrect)
tmpdstrect = *dstrect;
if (SDL_BlitScaled(surface_, srcrect ? &*srcrect : nullptr, dst.Get(), dstrect ? &tmpdstrect : nullptr) != 0)
throw Exception("SDL_BlitScaled failed");
}
Surface::LockHandle Surface::Lock() {
return LockHandle(this);
}
Rect Surface::GetClipRect() const {
SDL_Rect rect;
SDL_GetClipRect(surface_, &rect);
return Rect(rect);
}
Uint32 Surface::GetColorKey() const {
Uint32 key;
if (SDL_GetColorKey(surface_, &key) != 0)
throw Exception("SDL_GetColorKey failed");
return key;
}
Uint8 Surface::GetAlphaMod() const {
Uint8 alpha;
if (SDL_GetSurfaceAlphaMod(surface_, &alpha) != 0)
throw Exception("SDL_GetSurfaceAlphaMod failed");
return alpha;
}
SDL_BlendMode Surface::GetBlendMode() const {
SDL_BlendMode blendMode;
if (SDL_GetSurfaceBlendMode(surface_, &blendMode) != 0)
throw Exception("SDL_GetSurfaceBlendMode failed");
return blendMode;
}
void Surface::GetColorMod(Uint8& r, Uint8& g, Uint8& b) const {
if (SDL_GetSurfaceColorMod(surface_, &r, &g, &b) != 0)
throw Exception("SDL_GetSurfaceColorMod failed");
}
void Surface::SetClipRect(const Optional<Rect>& rect) {
if (SDL_SetClipRect(surface_, rect ? &*rect : nullptr) != 0)
throw Exception("SDL_SetClipRect failed");
}
void Surface::SetColorKey(int flag, Uint32 key) {
if (SDL_SetColorKey(surface_, flag, key) != 0)
throw Exception("SDL_SetColorKey failed");
}
void Surface::SetAlphaMod(Uint8 alpha) {
if (SDL_SetSurfaceAlphaMod(surface_, alpha) != 0)
throw Exception("SDL_SetSurfaceAlphaMod failed");
}
void Surface::SetBlendMode(SDL_BlendMode blendMode) {
if (SDL_SetSurfaceBlendMode(surface_, blendMode) != 0)
throw Exception("SDL_SetSurfaceBlendMode failed");
}
void Surface::SetColorMod(Uint8 r, Uint8 g, Uint8 b) {
if (SDL_SetSurfaceColorMod(surface_, r, g, b) != 0)
throw Exception("SDL_SetSurfaceColorMod failed");
}
void Surface::SetRLE(int flag) {
if (SDL_SetSurfaceRLE(surface_, flag) != 0)
throw Exception("SDL_SetSurfaceRLE failed");
}
void Surface::FillRect(const Optional<Rect>& rect, Uint32 color) {
if (SDL_FillRect(surface_, rect ? &*rect : nullptr, color) != 0)
throw Exception("SDL_FillRect failed");
}
void Surface::FillRects(const Rect* rects, int count, Uint32 color) {
std::vector<SDL_Rect> sdl_rects;
sdl_rects.reserve(count);
for (const Rect* r = rects; r != rects + count; ++r)
sdl_rects.emplace_back(*r);
if (SDL_FillRects(surface_, sdl_rects.data(), sdl_rects.size(), color) != 0)
throw Exception("SDL_FillRects failed");
}
}

487
SDL2pp/Surface.hh Normal file
View File

@ -0,0 +1,487 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2014 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.
*/
#ifndef SDL2PP_SURFACE_HH
#define SDL2PP_SURFACE_HH
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_blendmode.h>
#include <SDL2pp/Config.hh>
#include <SDL2pp/Optional.hh>
#include <SDL2pp/Rect.hh>
struct SDL_Surface;
struct SDL_PixelFormat;
namespace SDL2pp {
class RWops;
////////////////////////////////////////////////////////////
/// \brief Image stored in system memory with direct access
/// to pixel data
///
/// \ingroup rendering
///
/// \headerfile SDL2pp/Surface.hh
///
/// \see http://wiki.libsdl.org/SDL_Surface
///
////////////////////////////////////////////////////////////
class Surface {
private:
SDL_Surface* surface_; ///< Contained SDL_Texture structure
public:
////////////////////////////////////////////////////////////
/// \brief SDL2pp::Surface lock
/// \ingroup rendering
///
/// \details
/// For direct pixel access, SDL surface may need to be locked.
/// This class represents the lock and controls its lifetime
/// as the lock is released as soon as LockHandle is destroyed.
///
////////////////////////////////////////////////////////////
class LockHandle {
friend class Surface;
private:
Surface* surface_; ///< SDL2pp::Surface this lock belongs to
private:
////////////////////////////////////////////////////////////
/// \brief Create lock for specific SDL2pp::Texture
///
/// \throws STL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_LockSurface
///
////////////////////////////////////////////////////////////
LockHandle(Surface* surface);
public:
////////////////////////////////////////////////////////////
/// \brief Create no-op lock
///
/// \details
/// This may be initialized with real lock later with move
/// assignment operator
///
////////////////////////////////////////////////////////////
LockHandle();
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \details
/// Releases the lock
///
/// \see http://wiki.libsdl.org/SDL_UnlockSurface
///
////////////////////////////////////////////////////////////
~LockHandle();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param other SDL2pp::Surface::LockHandle to move data from
///
////////////////////////////////////////////////////////////
LockHandle(LockHandle&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment operator
///
/// \param other SDL2pp::Surface::LockHandle to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
LockHandle& operator=(LockHandle&& other) noexcept;
// Deleted copy constructor and assignment
LockHandle(const LockHandle& other) = delete;
LockHandle& operator=(const LockHandle& other) = delete;
////////////////////////////////////////////////////////////
/// \brief Get pointer to raw pixel data of locked region
///
/// \returns Pointer to raw pixel data of locked region
///
////////////////////////////////////////////////////////////
void* GetPixels() const;
////////////////////////////////////////////////////////////
/// \brief Get pitch of locked pixel data
///
/// \returns Number of bytes in a row of pixel data, including
/// padding between lines
///
////////////////////////////////////////////////////////////
int GetPitch() const;
////////////////////////////////////////////////////////////
/// \brief Get pixel format of the surface
///
/// \returns Format of the pixels stored in the surface
///
////////////////////////////////////////////////////////////
const SDL_PixelFormat& GetFormat() const;
};
private:
////////////////////////////////////////////////////////////
/// \brief Create surface taking existing SDL_surface structure
///
/// \param surface Existing SDL_surface to manage
///
////////////////////////////////////////////////////////////
Surface(SDL_Surface* surface);
public:
////////////////////////////////////////////////////////////
/// \brief Create RGB surface
///
/// \param flags Unused and should be set to 0
/// \param width Width of the surface
/// \param height Height of the surface
/// \param depth Depth of the surface in bits
/// \param Rmask Red mask for the pixels
/// \param Gmask Green mask for the pixels
/// \param Bmask Blue mask for the pixels
/// \param Amask Alpha mask for the pixels
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateRGBSurface
///
////////////////////////////////////////////////////////////
Surface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
////////////////////////////////////////////////////////////
/// \brief Create RGB surface with existing pixel data
///
/// \param pixels Pointer to existing pixel data
/// \param width Width of the surface
/// \param height Height of the surface
/// \param depth depth of the surface in bits
/// \param pitch Number of bytes in a row of pixel data, including padding between lines
/// \param Rmask Red mask for the pixels
/// \param Gmask Green mask for the pixels
/// \param Bmask Blue mask for the pixels
/// \param Amask Alpha mask for the pixels
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateRGBSurfaceFrom
///
////////////////////////////////////////////////////////////
Surface(void* pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
#ifdef SDL2PP_WITH_IMAGE
////////////////////////////////////////////////////////////
/// \brief Create surface loading it via RWops
///
/// \param rwops RWops used to access an image file
///
////////////////////////////////////////////////////////////
Surface(RWops& rwops);
////////////////////////////////////////////////////////////
/// \brief Create surface loading it from file
///
/// \param filename Path to an image file
///
////////////////////////////////////////////////////////////
Surface(const std::string& filename);
#endif
////////////////////////////////////////////////////////////
/// \brief Destructor
///
/// \see http://wiki.libsdl.org/SDL_FreeSurface
///
////////////////////////////////////////////////////////////
virtual ~Surface();
////////////////////////////////////////////////////////////
/// \brief Move constructor
///
/// \param other SDL2pp::Surface object to move data from
///
////////////////////////////////////////////////////////////
Surface(Surface&& other) noexcept;
////////////////////////////////////////////////////////////
/// \brief Move assignment
///
/// \param other SDL2pp::Surface object to move data from
///
/// \returns Reference to self
///
////////////////////////////////////////////////////////////
Surface& operator=(Surface&& other) noexcept;
// Deleted copy constructor and assignment
Surface(const Surface&) = delete;
Surface& operator=(const Surface&) = delete;
////////////////////////////////////////////////////////////
/// \brief Get pointer to contained SDL_Surface structure
///
/// \returns Pointer to contained SDL_Surface structure
///
////////////////////////////////////////////////////////////
SDL_Surface* Get() const;
////////////////////////////////////////////////////////////
/// \brief Copy an existing surface into a new one that is
/// optimized for blitting to a surface of a specified pixel format
///
/// \param format SDL_PixelFormat structure that the new surface is optimized for
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_ConvertSurface
///
////////////////////////////////////////////////////////////
Surface Convert(const SDL_PixelFormat& format);
////////////////////////////////////////////////////////////
/// \brief Copy an existing surface to a new surface of the specified format
///
/// \param pixel_format One of the enumerated values in SDL_PixelFormatEnum
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_PixelFormatEnum
/// \see http://wiki.libsdl.org/SDL_ConvertSurfaceFormat
///
////////////////////////////////////////////////////////////
Surface Convert(Uint32 pixel_format);
////////////////////////////////////////////////////////////
/// \brief Fast surface copy to a destination surface
///
/// \param srcrect Rectangle to be copied, or NullOpt to copy the entire surface
/// \param dst Blit target surface
/// \param srcrect Rectangle that is copied into
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_BlitSurface
///
////////////////////////////////////////////////////////////
void Blit(const Optional<Rect>& srcrect, Surface& dst, const Rect& dstrect);
////////////////////////////////////////////////////////////
/// \brief Scaled surface copy to a destination surface
///
/// \param srcrect Rectangle to be copied, or NullOpt to copy the entire surface
/// \param dst Blit target surface
/// \param srcrect Rectangle that is copied into, or NullOpt to copy into entire surface
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_BlitScaled
///
////////////////////////////////////////////////////////////
void BlitScaled(const Optional<Rect>& srcrect, Surface& dst, const Optional<Rect>& dstrect);
////////////////////////////////////////////////////////////
/// \brief Lock surface for direct pixel access
///
/// \return Lock handle used to access pixel data and to control lock lifetime
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_LockSurface
///
////////////////////////////////////////////////////////////
LockHandle Lock();
////////////////////////////////////////////////////////////
/// \brief Get the clipping rectangle for a surface
///
/// \return Rect filled in with the clipping rectangle for the surface
///
/// \see http://wiki.libsdl.org/SDL_GetClipRect
///
////////////////////////////////////////////////////////////
Rect GetClipRect() const;
////////////////////////////////////////////////////////////
/// \brief Get the color key (transparent pixel) for a surface
///
/// \return Transparent pixel value
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_GetColorKey
///
////////////////////////////////////////////////////////////
Uint32 GetColorKey() const;
////////////////////////////////////////////////////////////
/// \brief Get the additional alpha value used in blit operations
///
/// \return Current alpha value
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_GetSurfaceAlphaMod
///
////////////////////////////////////////////////////////////
Uint8 GetAlphaMod() const;
////////////////////////////////////////////////////////////
/// \brief Get blend mode used for blit operations
///
/// \return Current SDL_BlendMode
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_GetSurfaceBlendMode
///
////////////////////////////////////////////////////////////
SDL_BlendMode GetBlendMode() const;
////////////////////////////////////////////////////////////
/// \brief Get the additional color value multiplied into blit operations
///
/// \param r Variable to be filled in with the current red color value
/// \param g Variable to be filled in with the current green color value
/// \param b Variable to be filled in with the current blue color value
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_GetSurfaceColorMod
///
////////////////////////////////////////////////////////////
void GetColorMod(Uint8& r, Uint8& g, Uint8& b) const;
////////////////////////////////////////////////////////////
/// \brief Set the clipping rectangle for a surface
///
/// \param rect SDL22::Rect representing the clipping rectangle, or NullOpt to disable clipping
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetClipRect
///
////////////////////////////////////////////////////////////
void SetClipRect(const Optional<Rect>& rect = NullOpt);
////////////////////////////////////////////////////////////
/// \brief Set the color key (transparent pixel) in a surface
///
/// \param flag True to enabled color key, false to disable
/// \param key Transparent pixel value
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetColorKey
///
////////////////////////////////////////////////////////////
void SetColorKey(int flag, Uint32 key);
////////////////////////////////////////////////////////////
/// \brief Set an additional alpha value used in blit operations
///
/// \param alpha Alpha value multiplied into blit operations
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetSurfaceAlphaMod
///
////////////////////////////////////////////////////////////
void SetAlphaMod(Uint8 alpha = 255);
////////////////////////////////////////////////////////////
/// \brief Set the blend mode used for blit operations
///
/// \param blendMode SDL_BlendMode to use for blit blending
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetSurfaceBlendMode
///
////////////////////////////////////////////////////////////
void SetBlendMode(SDL_BlendMode blendMode);
////////////////////////////////////////////////////////////
/// \brief Set an additional color value multiplied into blit operations
///
/// \param r Red color value multiplied into blit operations
/// \param g Green color value multiplied into blit operations
/// \param b Blue color value multiplied into blit operations
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetSurfaceColorMod
///
////////////////////////////////////////////////////////////
void SetColorMod(Uint8 r = 255, Uint8 g = 255, Uint8 b = 255);
////////////////////////////////////////////////////////////
/// \brief Set the RLE acceleration hint for a surface
///
/// \param flag 0 to disable, non-zero to enable RLE acceleration
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_SetSurfaceRLE
///
////////////////////////////////////////////////////////////
void SetRLE(int flag);
////////////////////////////////////////////////////////////
/// \brief Perform a fast fill of a rectangle with a specific color
///
/// \param rect Rectangle to fill, or NullOpt to fill the entire surface
/// \param color Color to fill with
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_FillRect
///
////////////////////////////////////////////////////////////
void FillRect(const Optional<Rect>& rect, Uint32 color);
////////////////////////////////////////////////////////////
/// \brief Perform a fast fill of a set of rectangles with a specific color
///
/// \param rects Array rectangles to be filled
/// \param count Number of rectangles in the array
/// \param color Color to fill with
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_FillRects
///
////////////////////////////////////////////////////////////
void FillRects(const Rect* rects, int count, Uint32 color);
};
}
#endif

79
SDL2pp/SurfaceLock.cc Normal file
View File

@ -0,0 +1,79 @@
/*
libSDL2pp - C++11 bindings/wrapper for SDL2
Copyright (C) 2014 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 <SDL2/SDL_surface.h>
#include <SDL2pp/Exception.hh>
#include <SDL2pp/Surface.hh>
namespace SDL2pp {
Surface::LockHandle::LockHandle() : surface_(nullptr) {
}
Surface::LockHandle::LockHandle(Surface* surface) : surface_(surface) {
if (SDL_MUSTLOCK(surface_->Get())) {
if (SDL_LockSurface(surface_->Get()))
throw Exception("SDL_LockSurface failed");
}
}
Surface::LockHandle::LockHandle(Surface::LockHandle&& other) noexcept : surface_(other.surface_) {
other.surface_ = nullptr;
}
Surface::LockHandle& Surface::LockHandle::operator=(Surface::LockHandle&& other) noexcept {
if (&other == this)
return *this;
if (surface_ != nullptr) {
if (SDL_MUSTLOCK(surface_->Get()))
SDL_UnlockSurface(surface_->Get());
}
surface_ = other.surface_;
other.surface_ = nullptr;
return *this;
}
Surface::LockHandle::~LockHandle() {
if (surface_ != nullptr) {
if (SDL_MUSTLOCK(surface_->Get()))
SDL_UnlockSurface(surface_->Get());
}
}
void* Surface::LockHandle::GetPixels() const {
return surface_->Get()->pixels;
}
int Surface::LockHandle::GetPitch() const {
return surface_->Get()->pitch;
}
const SDL_PixelFormat& Surface::LockHandle::GetFormat() const {
return *surface_->Get()->format;
}
}

View File

@ -33,6 +33,7 @@
#include <SDL2pp/Renderer.hh>
#include <SDL2pp/Exception.hh>
#include <SDL2pp/Rect.hh>
#include <SDL2pp/Surface.hh>
#ifdef SDL2PP_WITH_IMAGE
# include <SDL2pp/RWops.hh>
#endif
@ -56,6 +57,11 @@ Texture::Texture(Renderer& renderer, const std::string& path) {
}
#endif
Texture::Texture(Renderer& renderer, const Surface& surface) {
if ((texture_ = SDL_CreateTextureFromSurface(renderer.Get(), surface.Get())) == nullptr)
throw Exception("SDL_CreateTextureFromSurface failed");
}
Texture::~Texture() {
if (texture_ != nullptr)
SDL_DestroyTexture(texture_);

View File

@ -37,6 +37,7 @@ namespace SDL2pp {
class Renderer;
class RWops;
class Surface;
////////////////////////////////////////////////////////////
/// \brief Image stored in the graphics card memory that
@ -211,6 +212,19 @@ public:
Texture(Renderer& renderer, const std::string& filename);
#endif
////////////////////////////////////////////////////////////
/// \brief Create texture from surface
///
/// \param renderer Rendering context to create texture for
/// \param surface Surface containing pixel data used to fill the texture
///
/// \throws SDL2pp::Exception
///
/// \see http://wiki.libsdl.org/SDL_CreateTextureFromSurface
///
////////////////////////////////////////////////////////////
Texture(Renderer& renderer, const Surface& surface);
////////////////////////////////////////////////////////////
/// \brief Destructor
///

View File

@ -29,6 +29,7 @@
#include <SDL2pp/Window.hh>
#include <SDL2pp/Renderer.hh>
#include <SDL2pp/Texture.hh>
#include <SDL2pp/Surface.hh>
#include <SDL2pp/Exception.hh>
using namespace SDL2pp;
@ -39,9 +40,16 @@ int Run() {
Window window("libSDL2pp demo: loading", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE);
Renderer render(window, -1, SDL_RENDERER_ACCELERATED);
// Load sprite texture
Texture sprite(render, TESTDATA_DIR "/test.png");
sprite.SetBlendMode(SDL_BLENDMODE_BLEND);
// 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 "/test.png");
Texture sprite1(render, TESTDATA_DIR "/test.png");
Texture sprite2(render, surf);
sprite1.SetBlendMode(SDL_BLENDMODE_BLEND);
sprite2.SetBlendMode(SDL_BLENDMODE_BLEND);
render.SetDrawBlendMode(SDL_BLENDMODE_BLEND);
@ -58,9 +66,9 @@ int Run() {
// Simple copy
float angle = SDL_GetTicks() / 5000.0 * 2.0 * M_PI;
render.Copy(sprite, NullOpt, Rect(320 - 64, 240 - 64, 128, 128), angle / M_PI * 180.0);
render.Copy(sprite, NullOpt, Rect(320 - 32 + sin(angle) * 40, 240 - 32 + cos(angle) * 40, 64, 64));
render.Copy(sprite, NullOpt, Rect(320 - 32 - sin(angle) * 40, 240 - 32 - cos(angle) * 40, 64, 64));
render.Copy(sprite1, NullOpt, Rect(320 - 64, 240 - 64, 128, 128), angle / M_PI * 180.0);
render.Copy(sprite1, NullOpt, Rect(320 - 32 + sin(angle) * 40, 240 - 32 + cos(angle) * 40, 64, 64));
render.Copy(sprite2, NullOpt, Rect(320 - 32 - sin(angle) * 40, 240 - 32 - cos(angle) * 40, 64, 64));
render.Present();