diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c94165..d2bd639 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ SET(LIBRARY_SOURCES SDL2pp/AudioDevice.cc SDL2pp/AudioLock.cc SDL2pp/AudioSpec.cc + SDL2pp/Color.cc SDL2pp/Exception.cc SDL2pp/Point.cc SDL2pp/RWops.cc @@ -142,6 +143,7 @@ SET(LIBRARY_SOURCES SET(LIBRARY_HEADERS SDL2pp/AudioDevice.hh SDL2pp/AudioSpec.hh + SDL2pp/Color.hh SDL2pp/ContainerRWops.hh SDL2pp/Exception.hh SDL2pp/Optional.hh diff --git a/SDL2pp/Color.cc b/SDL2pp/Color.cc new file mode 100644 index 0000000..7c2f484 --- /dev/null +++ b/SDL2pp/Color.cc @@ -0,0 +1,27 @@ +/* + libSDL2pp - C++11 bindings/wrapper for SDL2 + Copyright (C) 2017 Vraiment + + 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 + +std::ostream& operator<<(std::ostream& stream, const SDL2pp::Color& color) { + stream << "[r:" << static_cast(color.r) << ",g:" << static_cast(color.g) << ",b:" << static_cast(color.b) << ",a:" << static_cast(color.a) << "]"; + return stream; +} diff --git a/SDL2pp/Color.hh b/SDL2pp/Color.hh new file mode 100644 index 0000000..5bd6e80 --- /dev/null +++ b/SDL2pp/Color.hh @@ -0,0 +1,278 @@ + /* + libSDL2pp - C++11 bindings/wrapper for SDL2 + Copyright (C) 2017 Vraiment + + 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_COLOR_HH +#define SDL2PP_COLOR_HH + +#include + +#include + +#include + +namespace SDL2pp { + +//////////////////////////////////////////////////////////// +/// \brief RGB color with Alpha +/// +/// \ingroup graphics +/// +/// \headerfile SDL2pp/Color.hh +/// +/// This class is public-derived from SDL_Color structure, +/// may generally used as it if passed via pointer or +/// reference. It also supports direct access to r, g, b +/// and a members. +/// +/// \see http://wiki.libsdl.org/SDL_Color +/// +//////////////////////////////////////////////////////////// +class SDL2PP_EXPORT Color : public SDL_Color { +public: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates a Color(0, 0, 0, 0) + /// + //////////////////////////////////////////////////////////// + constexpr Color() : SDL_Color{0, 0, 0, 0} { + } + + //////////////////////////////////////////////////////////// + /// \brief Construct a color from existing SDL_Color + /// + /// \param[in] color Existing SDL_Color + /// + //////////////////////////////////////////////////////////// + constexpr Color(const SDL_Color& color) : SDL_Color{color.r, color.g, color.b, color.a} { + } + + //////////////////////////////////////////////////////////// + /// \brief Construct the color from given RGB, alpha is opaque + /// + /// \param[in] r Red component in the range 0-255 + /// \param[in] g Green component in the range 0-255 + /// \param[in] b Blue component in the range 0-255 + /// + //////////////////////////////////////////////////////////// + constexpr Color(Uint8 r, Uint8 g, Uint8 b) : SDL_Color{r, g, b, SDL_ALPHA_OPAQUE} { + } + + //////////////////////////////////////////////////////////// + /// \brief Construct the color from given RGB and alpha values + /// + /// \param[in] r Red component in the range 0-255 + /// \param[in] g Green component in the range 0-255 + /// \param[in] b Blue component in the range 0-255 + /// \param[in] a Alpha component in the range 0-255 + /// + //////////////////////////////////////////////////////////// + constexpr Color(Uint8 r, Uint8 g, Uint8 b, Uint8 a) : SDL_Color{r, g, b, a} { + } + + //////////////////////////////////////////////////////////// + /// \brief Copy constructor + /// + //////////////////////////////////////////////////////////// + Color(const Color&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + Color(Color&&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Assignment operator + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& operator=(const Color&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment operator + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& operator=(Color&&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Get the red component from the color + /// + /// \returns The red component from the color + /// + //////////////////////////////////////////////////////////// + constexpr Uint8 GetRed() const { + return r; + } + + //////////////////////////////////////////////////////////// + /// \brief Set the red component from the color + /// + /// \param[in] nr New red component value + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& SetRed(int nr) { + r = nr; + return *this; + } + + //////////////////////////////////////////////////////////// + /// \brief Get the green component from the color + /// + /// \returns The green component from the color + /// + //////////////////////////////////////////////////////////// + constexpr Uint8 GetGreen() const { + return g; + } + + //////////////////////////////////////////////////////////// + /// \brief Set the green component from the color + /// + /// \param[in] ng New green component value + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& SetGreen(int ng) { + g = ng; + return *this; + } + + //////////////////////////////////////////////////////////// + /// \brief Get the blue component from the color + /// + /// \returns The blue component from the color + /// + //////////////////////////////////////////////////////////// + constexpr Uint8 GetBlue() const { + return b; + } + + //////////////////////////////////////////////////////////// + /// \brief Set the blue component from the color + /// + /// \param[in] nb New blue component value + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& SetBlue(int nb) { + b = nb; + return *this; + } + + //////////////////////////////////////////////////////////// + /// \brief Get the alpha component from the color + /// + /// \returns The alpha component from the color + /// + //////////////////////////////////////////////////////////// + constexpr Uint8 GetAlpha() const { + return a; + } + + //////////////////////////////////////////////////////////// + /// \brief Set the alpha component from the color + /// + /// \param[in] na New alpha component value + /// + /// \returns Reference to self + /// + //////////////////////////////////////////////////////////// + Color& SetAlpha(int na) { + a = na; + return *this; + } +}; + +} + +//////////////////////////////////////////////////////////// +/// \brief Equality operator for SDL2pp::Color +/// +/// \param[in] a First argument for comparison +/// \param[in] b Second argument for comparison +/// +/// \returns True if two rectangles are identical +/// +//////////////////////////////////////////////////////////// +constexpr bool operator==(const SDL2pp::Color& a, const SDL2pp::Color& b) { + return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; +} + +//////////////////////////////////////////////////////////// +/// \brief Inequality operator for SDL2pp::Color +/// +/// \param[in] a First argument for comparison +/// \param[in] b Second argument for comparison +/// +/// \returns True if two rectangles are not identical +/// +//////////////////////////////////////////////////////////// +constexpr bool operator!=(const SDL2pp::Color& a, const SDL2pp::Color& b) { + return !(a == b); +} + +//////////////////////////////////////////////////////////// +/// \brief Stream output operator overload for SDL2pp::Color +/// +/// \param[in] stream Stream to output to +/// \param[in] color Color to output +/// +/// \returns stream +/// +//////////////////////////////////////////////////////////// +SDL2PP_EXPORT std::ostream& operator<<(std::ostream& stream, const SDL2pp::Color& color); + +namespace std { + +//////////////////////////////////////////////////////////// +/// \brief std::hash specialization for SDL2pp::Color +/// +//////////////////////////////////////////////////////////// +template<> +struct hash { + //////////////////////////////////////////////////////////// + /// \brief Hash function for SDL2pp::Color + /// + /// \param[in] c Input Color + /// + /// \returns Hash value + /// + //////////////////////////////////////////////////////////// + size_t operator()(const SDL2pp::Color& c) const { + size_t seed = std::hash()(c.r); + seed ^= std::hash()(c.g) + 0x9e3779b9 + (seed<<6) + (seed>>2); + seed ^= std::hash()(c.b) + 0x9e3779b9 + (seed<<6) + (seed>>2); + seed ^= std::hash()(c.a) + 0x9e3779b9 + (seed<<6) + (seed>>2); + return seed; + } +}; + +} + +#endif diff --git a/SDL2pp/Renderer.cc b/SDL2pp/Renderer.cc index a3fd63e..86b4df8 100644 --- a/SDL2pp/Renderer.cc +++ b/SDL2pp/Renderer.cc @@ -197,6 +197,10 @@ Renderer& Renderer::SetDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { return *this; } +Renderer& Renderer::SetDrawColor(const Color& color) { + return SetDrawColor(color.r, color.g, color.b, color.a); +} + Renderer& Renderer::SetTarget() { if (SDL_SetRenderTarget(renderer_, nullptr) != 0) throw Exception("SDL_SetRenderTarget"); @@ -411,6 +415,12 @@ SDL_BlendMode Renderer::GetDrawBlendMode() const { return mode; } +Color Renderer::GetDrawColor() const { + Color color; + GetDrawColor(color.r, color.g, color.b, color.a); + return color; +} + void Renderer::GetDrawColor(Uint8& r, Uint8& g, Uint8& b, Uint8& a) const { if (SDL_GetRenderDrawColor(renderer_, &r, &g, &b, &a) != 0) throw Exception("SDL_GetRenderDrawColor"); diff --git a/SDL2pp/Renderer.hh b/SDL2pp/Renderer.hh index c89221a..a8209e5 100644 --- a/SDL2pp/Renderer.hh +++ b/SDL2pp/Renderer.hh @@ -30,6 +30,7 @@ #include #include #include +#include struct SDL_RendererInfo; struct SDL_Renderer; @@ -301,6 +302,20 @@ public: //////////////////////////////////////////////////////////// Renderer& SetDrawColor(Uint8 r = 0, Uint8 g = 0, Uint8 b = 0, Uint8 a = 255); + //////////////////////////////////////////////////////////// + /// \brief Set color user for drawing operations + /// + /// \param[in] color Color to draw on the rendering target + /// + /// \returns Reference to self + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetRenderDrawColor + /// + //////////////////////////////////////////////////////////// + Renderer& SetDrawColor(const Color& color); + //////////////////////////////////////////////////////////// /// \brief Set current render target to default /// @@ -752,6 +767,18 @@ public: //////////////////////////////////////////////////////////// SDL_BlendMode GetDrawBlendMode() const; + //////////////////////////////////////////////////////////// + /// \brief Get the additional color value multiplied into render copy operations + /// + /// \return Color object with the value used to do render copy operations + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetRenderDrawColor + /// + //////////////////////////////////////////////////////////// + Color GetDrawColor() const; + //////////////////////////////////////////////////////////// /// \brief Get the additional color value multiplied into render copy operations /// diff --git a/SDL2pp/SDL2pp.hh b/SDL2pp/SDL2pp.hh index 2e567aa..22110b4 100644 --- a/SDL2pp/SDL2pp.hh +++ b/SDL2pp/SDL2pp.hh @@ -73,6 +73,7 @@ #include #include #include +#include //////////////////////////////////////////////////////////// /// \defgroup geometry 2D geometry diff --git a/SDL2pp/Surface.cc b/SDL2pp/Surface.cc index 4400114..7babeaf 100644 --- a/SDL2pp/Surface.cc +++ b/SDL2pp/Surface.cc @@ -145,6 +145,13 @@ SDL_BlendMode Surface::GetBlendMode() const { return blendMode; } +Color Surface::GetColorAndAlphaMod() const { + Color color; + GetColorMod(color.r, color.g, color.b); + color.a = GetAlphaMod(); + return color; +} + void Surface::GetColorMod(Uint8& r, Uint8& g, Uint8& b) const { if (SDL_GetSurfaceColorMod(surface_, &r, &g, &b) != 0) throw Exception("SDL_GetSurfaceColorMod"); @@ -180,6 +187,10 @@ Surface& Surface::SetColorMod(Uint8 r, Uint8 g, Uint8 b) { return *this; } +Surface& Surface::SetColorAndAlphaMod(const Color& color) { + return SetColorMod(color.r, color.g, color.b).SetAlphaMod(color.a); +} + Surface& Surface::SetRLE(bool flag) { if (SDL_SetSurfaceRLE(surface_, flag ? 1 : 0) != 0) throw Exception("SDL_SetSurfaceRLE"); diff --git a/SDL2pp/Surface.hh b/SDL2pp/Surface.hh index c3930e6..7cacfdb 100644 --- a/SDL2pp/Surface.hh +++ b/SDL2pp/Surface.hh @@ -30,6 +30,7 @@ #include #include #include +#include struct SDL_Surface; struct SDL_PixelFormat; @@ -390,6 +391,19 @@ public: //////////////////////////////////////////////////////////// SDL_BlendMode GetBlendMode() const; + //////////////////////////////////////////////////////////// + /// \brief Get the additional color value multiplied into blit operations + /// + /// \return Color object with the values used to do blit operations + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetSurfaceAlphaMod + /// \see http://wiki.libsdl.org/SDL_GetSurfaceColorMod + /// + //////////////////////////////////////////////////////////// + Color GetColorAndAlphaMod() const; + //////////////////////////////////////////////////////////// /// \brief Get the additional color value multiplied into blit operations /// @@ -477,6 +491,21 @@ public: //////////////////////////////////////////////////////////// Surface& SetColorMod(Uint8 r = 255, Uint8 g = 255, Uint8 b = 255); + //////////////////////////////////////////////////////////// + /// \brief Set an additional color value multiplied into blit operations + /// + /// \param[in] color Color to be multiplied into blit operations + /// + /// \returns Reference to self + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetSurfaceAlphaMod + /// \see http://wiki.libsdl.org/SDL_SetSurfaceColorMod + /// + //////////////////////////////////////////////////////////// + Surface& SetColorAndAlphaMod(const Color& color); + //////////////////////////////////////////////////////////// /// \brief Set the RLE acceleration hint for a surface /// diff --git a/SDL2pp/Texture.cc b/SDL2pp/Texture.cc index 2398efb..9218e2a 100644 --- a/SDL2pp/Texture.cc +++ b/SDL2pp/Texture.cc @@ -157,6 +157,10 @@ Texture& Texture::SetColorMod(Uint8 r, Uint8 g, Uint8 b) { return *this; } +Texture& Texture::SetColorAndAlphaMod(const Color& color) { + return SetColorMod(color.r, color.g, color.b).SetAlphaMod(color.a); +} + Texture::LockHandle Texture::Lock(const Optional& rect) { return LockHandle(this, rect); } @@ -215,4 +219,11 @@ void Texture::GetColorMod(Uint8& r, Uint8& g, Uint8& b) const { throw Exception("SDL_GetTextureColorMod"); } +Color Texture::GetColorAndAlphaMod() const { + Color color; + GetColorMod(color.r, color.g, color.b); + color.a = GetAlphaMod(); + return color; +} + } diff --git a/SDL2pp/Texture.hh b/SDL2pp/Texture.hh index 1e923f2..70f947d 100644 --- a/SDL2pp/Texture.hh +++ b/SDL2pp/Texture.hh @@ -31,6 +31,7 @@ #include #include #include +#include struct SDL_Texture; @@ -421,6 +422,21 @@ public: //////////////////////////////////////////////////////////// Texture& SetColorMod(Uint8 r = 255, Uint8 g = 255, Uint8 b = 255); + //////////////////////////////////////////////////////////// + /// \brief Set an additional color value multiplied into render copy operations + /// + /// \param[in] color Color to be used when multiplied into render copy operations + /// + /// \returns Reference to self + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetTextureAlphaMod + /// \see http://wiki.libsdl.org/SDL_SetTextureColorMod + /// + //////////////////////////////////////////////////////////// + Texture& SetColorAndAlphaMod(const Color& color = Color{255, 255, 255, SDL_ALPHA_OPAQUE}); + //////////////////////////////////////////////////////////// /// \brief Lock texture for write-only pixel access /// @@ -536,6 +552,19 @@ public: /// //////////////////////////////////////////////////////////// void GetColorMod(Uint8& r, Uint8& g, Uint8 &b) const; + + //////////////////////////////////////////////////////////// + /// \brief Get the additional color value multiplied into render copy operations + /// + /// \return Color object with the values used to do render copy operations + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetTextureAlphaMod + /// \see http://wiki.libsdl.org/SDL_GetTextureColorMod + /// + //////////////////////////////////////////////////////////// + Color GetColorAndAlphaMod() const; }; }