}
+Texture Canvas::CreateStaticTexture(Vector<int> size) {
+ return Texture(canv, Color::Format, SDL_TEXTUREACCESS_STATIC, size);
+}
+
+
+void Canvas::Copy(Texture &tex, Vector<int> to) {
+ tex.Copy(canv, to);
+}
+
+
void Canvas::SetColor(Color c) {
SDL_SetRenderDrawColor(canv, c.r, c.g, c.b, c.a);
}
#define GWORM_CANVAS_H_
#include "Color.h"
+#include "Texture.h"
#include "Vector.h"
#include <SDL.h>
void Present();
+ Texture CreateStaticTexture(Vector<int> size);
+
+ void Copy(Texture &, Vector<int> to);
+
void SetColor(Color);
void Fill();
struct Color {
+ // NOTE: this depends on endianness and should be defined accordingly
+ static constexpr Uint32 Format = SDL_PIXELFORMAT_ABGR8888;
+
constexpr Color()
: Color(0, 0, 0) { }
constexpr Color(Uint8 r, Uint8 g, Uint8 b, Uint8 a = 0xFF)
--- /dev/null
+#ifndef GWORM_RECT_H_
+#define GWORM_RECT_H_
+
+#include "Vector.h"
+
+#include <SDL.h>
+
+
+namespace gworm {
+
+template<class Scalar>
+class Rect {
+
+public:
+ constexpr Rect() : x(0), y(0), w(0), h(0) { }
+ constexpr Rect(Vector<Scalar> pos, Vector<Scalar> size)
+ : x(pos.x), y(pos.y), w(size.x), h(size.y) { }
+
+public:
+ constexpr Vector<Scalar> Pos() const { return Vector<Scalar>(x, y); }
+ constexpr Vector<Scalar> Size() const { return Vector<Scalar>(w, h); }
+
+public:
+ Scalar x;
+ Scalar y;
+ Scalar w;
+ Scalar h;
+
+};
+
+
+/// specialization with same layout as SDL_Rect
+template<>
+class Rect<int>
+: public SDL_Rect {
+
+public:
+ constexpr Rect() : SDL_Rect({0, 0, 0, 0}) { }
+ constexpr Rect(Vector<int> pos, Vector<int> size)
+ : SDL_Rect({pos.x, pos.y, size.x, size.y}) { }
+
+public:
+ constexpr Vector<int> Pos() const { return Vector<int>(x, y); }
+ constexpr Vector<int> Size() const { return Vector<int>(w, h); }
+
+};
+
+}
+
+#endif
--- /dev/null
+#include "Texture.h"
+
+
+namespace gworm {
+
+Texture::Texture()
+: tex(nullptr)
+, format(Color::Format)
+, size(0, 0) {
+
+}
+
+Texture::~Texture() {
+ if (tex) SDL_DestroyTexture(tex);
+}
+
+Texture::Texture(Texture &&other)
+: Texture() {
+ Swap(other);
+}
+
+Texture &Texture::operator =(Texture &&other) {
+ Texture temp(std::move(other));
+ Swap(temp);
+ return *this;
+}
+
+
+Texture::Texture(
+ SDL_Renderer *c,
+ Uint32 f,
+ int u,
+ Vector<int> s)
+: tex(SDL_CreateTexture(c, f, u, s.x, s.y))
+, format(f)
+, size(s) {
+
+}
+
+
+void Texture::Swap(Texture &other) {
+ std::swap(tex, other.tex);
+ std::swap(format, other.format);
+ std::swap(size, other.size);
+}
+
+
+void Texture::SetColors(const Color *values) {
+ if (format == Color::Format) {
+ SDL_UpdateTexture(tex, nullptr, values, Size().x * sizeof(Color));
+ } else {
+ // TODO: implement for non-Color pixel formats
+ }
+}
+
+
+void Texture::Fill(SDL_Renderer *canv) {
+ SDL_RenderCopy(canv, tex, nullptr, nullptr);
+}
+
+void Texture::Copy(SDL_Renderer *canv, Vector<int> to) {
+ Copy(canv, Rect<int>(to, Size()));
+}
+
+void Texture::Copy(SDL_Renderer *canv, Rect<int> to) {
+ SDL_RenderCopy(canv, tex, nullptr, &to);
+}
+
+}
--- /dev/null
+#ifndef GWORM_TEXTURE_H_
+#define GWORM_TEXTURE_H_
+
+#include "Color.h"
+#include "Rect.h"
+#include "Vector.h"
+
+#include <algorithm>
+#include <SDL.h>
+
+
+namespace gworm {
+
+class Texture {
+
+public:
+ Texture();
+ ~Texture();
+
+ Texture(Texture &&);
+ Texture &operator =(Texture &&);
+
+ Texture(const Texture &) = delete;
+ Texture &operator =(const Texture &) = delete;
+
+ Texture(SDL_Renderer *, Uint32 format, int use, Vector<int> size);
+
+ void Swap(Texture &);
+
+public:
+ Vector<int> Size() const { return size; }
+
+ /// stretch this texture to completely fill given render target
+ void Fill(SDL_Renderer *);
+ /// copy entire texture as is to given coordinates
+ void Copy(SDL_Renderer *, Vector<int> to);
+ /// copy entire texture stretched to given rect
+ void Copy(SDL_Renderer *, Rect<int> to);
+
+ /// set all color values
+ /// given array must hold at least Size().x * Size().y values
+ void SetColors(const Color *);
+
+private:
+ SDL_Texture *tex;
+ Uint32 format;
+ Vector<int> size;
+
+};
+
+}
+
+
+namespace std {
+
+template<>
+inline void swap<gworm::Texture>(gworm::Texture &lhs, gworm::Texture &rhs) {
+ lhs.Swap(rhs);
+}
+
+}
+
+#endif