box inherits sdl_rect; color comparison operators; pixels operator() returns pointer of void, 8bit, 16bit, or 32bit; remap texture uses pixel class

This commit is contained in:
Frank DeMarco 2020-08-26 16:43:43 -04:00
parent 8346f43f21
commit edc836908d
11 changed files with 232 additions and 172 deletions

View File

@ -13,7 +13,7 @@
resolution, debug display, loading wheel animation, shadowed sprite, separate resolution, debug display, loading wheel animation, shadowed sprite, separate
update and draw, sprite movement cage, multiple windows, multiple renderers, update and draw, sprite movement cage, multiple windows, multiple renderers,
node children list, node animations list, copy constructor for node, private node children list, node animations list, copy constructor for node, private
and public class members and public class members, pixel class iterator
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :) :) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)

View File

@ -1,45 +1,51 @@
#include "Box.hpp" #include "Box.hpp"
Box::Box(const glm::vec2& nw, const glm::vec2& size) : rect({nw.x, nw.y, size.x, size.y}) {} Box::Box(const glm::vec2& nw, const glm::vec2& size)
{
x = nw.x;
y = nw.y;
w = size.x;
h = size.y;
}
float Box::get_x() const float Box::get_x() const
{ {
return rect.x; return x;
} }
float Box::get_y() const float Box::get_y() const
{ {
return rect.y; return y;
} }
float Box::get_w() const float Box::get_w() const
{ {
return rect.w; return w;
} }
float Box::get_h() const float Box::get_h() const
{ {
return rect.h; return h;
} }
void Box::set_x(float x) void Box::set_x(float x)
{ {
rect.x = x; this->x = x;
} }
void Box::set_y(float y) void Box::set_y(float y)
{ {
rect.y = y; this->y = y;
} }
void Box::set_w(float w) void Box::set_w(float width)
{ {
rect.w = w; w = width;
} }
void Box::set_h(float h) void Box::set_h(float height)
{ {
rect.h = h; h = height;
} }
glm::vec2 Box::get_size() const glm::vec2 Box::get_size() const
@ -238,19 +244,12 @@ void Box::set_center(const glm::vec2& center)
move(center - get_center()); move(center - get_center());
} }
SDL_FRect* Box::get_rect()
{
return ▭
}
SDL_Rect Box::get_int_rect() const
{
return {static_cast<int>(rect.x), static_cast<int>(rect.y), static_cast<int>(rect.w), static_cast<int>(rect.h)};
}
Box::operator SDL_Rect() const Box::operator SDL_Rect() const
{ {
return {static_cast<int>(rect.x), static_cast<int>(rect.y), static_cast<int>(rect.w), static_cast<int>(rect.h)}; return {
static_cast<int>(get_x()), static_cast<int>(get_y()),
static_cast<int>(get_w()), static_cast<int>(get_h())
};
} }
void Box::clear() void Box::clear()
@ -327,7 +326,7 @@ bool Box::collide(const Box& box, Box& overlap) const
std::ostream& Box::to_string (std::ostream& out) const std::ostream& Box::to_string (std::ostream& out) const
{ {
out << "{(" << rect.x << ", " << rect.y << "), (" << rect.w << ", " << rect.h << ")}"; out << "{(" << get_x() << ", " << get_y() << "), (" << get_w() << ", " << get_h() << ")}";
return out; return out;
} }

View File

@ -12,11 +12,9 @@
struct Segment; struct Segment;
struct Box struct Box : SDL_FRect
{ {
SDL_FRect rect = {0, 0, 0, 0};
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0}); Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0});
float get_x() const; float get_x() const;
float get_y() const; float get_y() const;
@ -60,16 +58,14 @@ struct Box
void set_south(const glm::vec2&); void set_south(const glm::vec2&);
void set_west(const glm::vec2&); void set_west(const glm::vec2&);
void set_center(const glm::vec2&); void set_center(const glm::vec2&);
SDL_FRect* get_rect();
SDL_Rect get_int_rect() const;
operator SDL_Rect() const; operator SDL_Rect() const;
void clear(); void clear();
void scale(float, bool = false); void scale(float, bool = false);
void move(const glm::vec2&); void move(const glm::vec2&);
bool collide(const glm::vec2&) const; bool collide(const glm::vec2&) const;
bool collide(const Segment&, glm::vec2* = NULL) const; bool collide(const Segment&, glm::vec2* = nullptr) const;
bool collide(const Segment&, glm::vec2&) const; bool collide(const Segment&, glm::vec2&) const;
bool collide(const Box&, Box* = NULL) const; bool collide(const Box&, Box* = nullptr) const;
bool collide(const Box&, Box&) const; bool collide(const Box&, Box&) const;
std::string get_class_name() { return "Box"; } std::string get_class_name() { return "Box"; }
std::ostream& to_string (std::ostream&) const; std::ostream& to_string (std::ostream&) const;

View File

@ -34,6 +34,45 @@ void Color::shift_hue(float offset)
set_percent(red_percent, green_percent, blue_percent); set_percent(red_percent, green_percent, blue_percent);
} }
Color::operator std::uint32_t() const
{
SDL_PixelFormat* format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA32);
std::uint32_t pixel = SDL_MapRGBA(format, r, g, b, a);
SDL_FreeFormat(format);
return pixel;
}
Color::operator std::uint16_t() const
{
SDL_PixelFormat* format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA4444);
std::uint16_t pixel = SDL_MapRGBA(format, r, g, b, a);
SDL_FreeFormat(format);
return pixel;
}
Color::operator std::uint8_t() const
{
SDL_PixelFormat* format = SDL_AllocFormat(SDL_PIXELFORMAT_RGB332);
std::uint8_t pixel = SDL_MapRGBA(format, r, g, b, a);
SDL_FreeFormat(format);
return pixel;
}
bool Color::operator==(const Color& color) const
{
return r == color.r && g == color.g && b == color.b && a == color.a;
}
bool Color::operator!=(const Color& color) const
{
return !(*this == color);
}
bool Color::operator<(const Color& color) const
{
return r < color.r || g < color.g || b < color.b || a < color.a;
}
std::ostream& operator<<(std::ostream& out, const Color& color) std::ostream& operator<<(std::ostream& out, const Color& color)
{ {
float h, s, v; float h, s, v;

View File

@ -8,7 +8,6 @@
#include <type_traits> #include <type_traits>
#include "SDL_pixels.h" #include "SDL_pixels.h"
#include "extension.hpp"
struct Color : SDL_Color struct Color : SDL_Color
{ {
@ -19,6 +18,12 @@ struct Color : SDL_Color
void set_percent(const float&, const float&, const float&, const float&); void set_percent(const float&, const float&, const float&, const float&);
void set_hsv(const float&, const float& = 1.0f, const float& = 1.0f); void set_hsv(const float&, const float& = 1.0f, const float& = 1.0f);
void shift_hue(float); void shift_hue(float);
operator std::uint32_t() const;
operator std::uint16_t() const;
operator std::uint8_t() const;
bool operator==(const Color&) const;
bool operator!=(const Color&) const;
bool operator<(const Color&) const;
template <typename T> template <typename T>
Color(T red, T green, T blue, T alpha = 255) Color(T red, T green, T blue, T alpha = 255)

View File

@ -58,32 +58,9 @@ int Pixels::get_bytes_per_row() const
return format->BytesPerPixel * rect.w; return format->BytesPerPixel * rect.w;
} }
void* Pixels::operator()(int x, int y) Color Pixels::get(int x, int y)
{ {
std::uint8_t* access = static_cast<std::uint8_t*>(source); std::uint32_t* pixel = operator()<std::uint32_t*>(x, y);
if (x < 0 || x >= rect.w)
{
x = sfw::mod(x, static_cast<int>(rect.w));
}
if (y < 0 || y >= rect.y)
{
y = sfw::mod(y, static_cast<int>(rect.h));
}
return access + y * get_bytes_per_row() + x * format->BytesPerPixel;
}
Color Pixels::operator()(int x, int y) const
{
std::uint8_t* access = static_cast<std::uint8_t*>(source);
if (x < 0 || x >= rect.w)
{
x = sfw::mod(x, static_cast<int>(rect.w));
}
if (y < 0 || x >= rect.y)
{
y = sfw::mod(y, static_cast<int>(rect.h));
}
Uint32* pixel = reinterpret_cast<Uint32*>(access + y * get_bytes_per_row() + x * format->BytesPerPixel);
Color color; Color color;
SDL_GetRGBA(*pixel, const_cast<SDL_PixelFormat*>(format), &color.r, &color.g, &color.b, &color.a); SDL_GetRGBA(*pixel, const_cast<SDL_PixelFormat*>(format), &color.r, &color.g, &color.b, &color.a);
return color; return color;
@ -94,18 +71,15 @@ void Pixels::set(const SDL_Color& color, int x, int y)
std::uint32_t pixel = SDL_MapRGBA(const_cast<SDL_PixelFormat*>(format), color.r, color.g, color.b, color.a); std::uint32_t pixel = SDL_MapRGBA(const_cast<SDL_PixelFormat*>(format), color.r, color.g, color.b, color.a);
if (format->BytesPerPixel == 1) if (format->BytesPerPixel == 1)
{ {
std::uint8_t* access = reinterpret_cast<std::uint8_t*>((*this)(x, y)); *operator()<std::uint8_t*>(x, y) = pixel;
*access = static_cast<std::uint8_t>(pixel);
} }
else if (format->BytesPerPixel == 2) else if (format->BytesPerPixel == 2)
{ {
std::uint16_t* access = reinterpret_cast<std::uint16_t*>((*this)(x, y)); *operator()<std::uint16_t*>(x, y) = pixel;
*access = static_cast<std::uint16_t>(pixel);
} }
else else
{ {
std::uint32_t* access = reinterpret_cast<std::uint32_t*>((*this)(x, y)); *operator()<std::uint32_t*>(x, y) = pixel;
*access = static_cast<std::uint32_t>(pixel);
} }
} }

View File

@ -23,12 +23,26 @@ struct Pixels
Pixels(Sprite&); Pixels(Sprite&);
Pixels(Sprite&, const SDL_Rect&); Pixels(Sprite&, const SDL_Rect&);
int get_bytes_per_row() const; int get_bytes_per_row() const;
void* operator()(int x, int y); Color get(int x, int y);
Color operator()(int x, int y) const;
void set(const SDL_Color&, int x, int y); void set(const SDL_Color&, int x, int y);
void apply(); void apply();
~Pixels(); ~Pixels();
template <typename T = void*>
T operator()(int x, int y)
{
std::uint8_t* access = static_cast<std::uint8_t*>(source);
if (x < 0 || x >= rect.w)
{
x = sfw::mod(x, static_cast<int>(rect.w));
}
if (y < 0 || y >= rect.y)
{
y = sfw::mod(y, static_cast<int>(rect.h));
}
return reinterpret_cast<T>(access + y * get_bytes_per_row() + x * format->BytesPerPixel);
}
}; };
#endif #endif

View File

@ -105,6 +105,11 @@ void Sprite::add_frames(const std::vector<SDL_Texture*>& frames)
} }
} }
const std::vector<SDL_Texture*>& Sprite::get_frames() const
{
return frames;
}
Frameset& Sprite::get_all_frames_frameset() Frameset& Sprite::get_all_frames_frameset()
{ {
return framesets[get_configuration()["animation"]["all-frames-frameset-name"]]; return framesets[get_configuration()["animation"]["all-frames-frameset-name"]];
@ -674,12 +679,12 @@ void Sprite::update()
SDL_SetRenderTarget(renderer, NULL); SDL_SetRenderTarget(renderer, NULL);
if (wrap.x || wrap.y) if (wrap.x || wrap.y)
{ {
SDL_Rect wrap_frame_rect = wrap_frame.get_int_rect(); SDL_Rect wrap_frame_rect = wrap_frame;
SDL_RenderSetClipRect(renderer, &wrap_frame_rect); SDL_RenderSetClipRect(renderer, &wrap_frame_rect);
} }
for (auto ii = 0; ii < static_cast<int>(boxes.size()); ii++) for (auto ii = 0; ii < static_cast<int>(boxes.size()); ii++)
{ {
SDL_RenderCopyF(renderer, texture, NULL, boxes[ii].get_rect()); SDL_RenderCopyF(renderer, texture, NULL, &boxes[ii]);
} }
if (wrap.x || wrap.y) if (wrap.x || wrap.y)
{ {
@ -745,11 +750,11 @@ glm::vec2 Frameset::measure() const
int w, h; int w, h;
for (std::size_t index : order) for (std::size_t index : order)
{ {
if (index < sprite->frames.size()) if (index < sprite->get_frames().size())
{ {
SDL_QueryTexture(sprite->frames[index], NULL, NULL, &w, &h); SDL_QueryTexture(sprite->get_frames()[index], nullptr, nullptr, &w, &h);
s.x = std::max(static_cast<float>(w * sprite->scale), s.x); s.x = std::max(static_cast<float>(w * sprite->get_scale()), s.x);
s.y = std::max(static_cast<float>(h * sprite->scale), s.y); s.y = std::max(static_cast<float>(h * sprite->get_scale()), s.y);
} }
} }
return s; return s;

View File

@ -15,7 +15,6 @@
#include "Box.hpp" #include "Box.hpp"
#include "Animation.hpp" #include "Animation.hpp"
#include "Color.hpp" #include "Color.hpp"
#include "extension.hpp"
struct Game; struct Game;
struct Frameset; struct Frameset;
@ -43,12 +42,13 @@ struct Sprite : Node
Sprite(); Sprite();
Sprite(Node*); Sprite(Node*);
Sprite(Node*, std::string); Sprite(Node*, std::string);
void reset(); virtual void reset();
void associate(std::string); virtual void associate(std::string);
void load(); virtual void load();
void load_file(fs::path); void load_file(fs::path);
void add_frames(SDL_Texture*); void add_frames(SDL_Texture*);
void add_frames(const std::vector<SDL_Texture*>&); void add_frames(const std::vector<SDL_Texture*>&);
const std::vector<SDL_Texture*>& get_frames() const;
Frameset& get_all_frames_frameset(); Frameset& get_all_frames_frameset();
Frameset& add_frameset(std::string); Frameset& add_frameset(std::string);
Frameset& set_frameset(std::string); Frameset& set_frameset(std::string);
@ -109,7 +109,7 @@ struct Sprite : Node
void add_wrap(bool, bool); void add_wrap(bool, bool);
void add_wrap(bool, bool, Box); void add_wrap(bool, bool, Box);
void add_hue_shift_frames(int); void add_hue_shift_frames(int);
glm::vec2 move(glm::vec2, bool = true); virtual glm::vec2 move(glm::vec2, bool = true);
bool collide(const glm::vec2&, bool = false) const; bool collide(const glm::vec2&, bool = false) const;
bool collide(const Segment&, glm::vec2* = NULL, bool = false) const; bool collide(const Segment&, glm::vec2* = NULL, bool = false) const;
bool collide(const Segment&, glm::vec2&, bool = false) const; bool collide(const Segment&, glm::vec2&, bool = false) const;
@ -117,8 +117,8 @@ struct Sprite : Node
bool collide(const Box&, Box&, bool = false, bool = false) const; bool collide(const Box&, Box&, bool = false, bool = false) const;
bool collide(const Sprite&, bool = false, Box* = NULL, bool = false, bool = false) const; bool collide(const Sprite&, bool = false, Box* = NULL, bool = false, bool = false) const;
bool collide(const Sprite&, Box&, bool = false, bool = false, bool = false) const; bool collide(const Sprite&, Box&, bool = false, bool = false, bool = false) const;
void update(); virtual void update();
std::string get_class_name() { return "Sprite"; } virtual std::string get_class_name() { return "Sprite"; }
~Sprite() { unload(); } ~Sprite() { unload(); }
}; };
@ -158,5 +158,6 @@ struct Frameset
#include "Pixels.hpp" #include "Pixels.hpp"
#include "Game.hpp" #include "Game.hpp"
#include "extension.hpp"
#endif #endif

View File

@ -69,7 +69,7 @@ void sfw::populate_pixel_2d_array(
int bytes_per_row = bytes_per_pixel * region.get_w(); int bytes_per_row = bytes_per_pixel * region.get_w();
int bytes_total = bytes_per_row * region.get_h(); int bytes_total = bytes_per_row * region.get_h();
Uint8* source = new Uint8[bytes_total]; Uint8* source = new Uint8[bytes_total];
SDL_Rect int_rect = region.get_int_rect(); SDL_Rect int_rect = region;
if (SDL_RenderReadPixels(renderer, &int_rect, format, source, bytes_per_row) < 0) if (SDL_RenderReadPixels(renderer, &int_rect, format, source, bytes_per_row) < 0)
{ {
print_sdl_error("Could not read pixels after setting remapped texture as target"); print_sdl_error("Could not read pixels after setting remapped texture as target");
@ -139,8 +139,7 @@ std::vector<SDL_Texture*> sfw::get_portal_frames(
frames.reserve(count); frames.reserve(count);
float y_margin = 10; float y_margin = 10;
float max_y = size.y - y_margin; float max_y = size.y - y_margin;
std::vector<float> hues = range_step(hue_start, hue_end, count); std::vector<float> hues = range_count(hue_start, hue_end, count);
std::cout << hues << std::endl;
SDL_Texture* frame; SDL_Texture* frame;
Color color; Color color;
for (int frame_ii = 0; frame_ii < count; frame_ii++) for (int frame_ii = 0; frame_ii < count; frame_ii++)
@ -159,40 +158,79 @@ std::vector<SDL_Texture*> sfw::get_portal_frames(
return frames; return frames;
} }
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a) void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Color& color, const Box& box)
{ {
SDL_SetRenderTarget(renderer, texture); SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, r, g, b, a); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderFillRect(renderer, NULL); SDL_RenderFillRectF(renderer, &box);
} }
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture* tile) void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Color& color)
{
fill_texture(renderer, texture, color, get_texture_box(texture));
}
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture* tile, const Box& box)
{ {
SDL_SetRenderTarget(renderer, texture);
Box texture_box = get_texture_box(texture), tile_box = get_texture_box(tile); Box texture_box = get_texture_box(texture), tile_box = get_texture_box(tile);
SDL_FRect draw_rect; SDL_FRect draw_rect;
for (int x = 0; x < texture_box.get_w(); x += tile_box.get_w()) if (SDL_SetRenderTarget(renderer, texture) < 0)
{ {
for (int y = 0; y < texture_box.get_h(); y += tile_box.get_h()) print_sdl_error("could not set render target");
}
else
{
SDL_Rect int_rect = box;
if (SDL_RenderSetClipRect(renderer, &int_rect) < 0)
{ {
draw_rect = {(float) x, (float) y, tile_box.get_w(), tile_box.get_h()}; print_sdl_error("could not set clip");
SDL_RenderCopyF(renderer, tile, NULL, &draw_rect); }
else
{
for (int x = 0; x < texture_box.get_w(); x += tile_box.get_w())
{
for (int y = 0; y < texture_box.get_h(); y += tile_box.get_h())
{
draw_rect = {(float) x, (float) y, tile_box.get_w(), tile_box.get_h()};
SDL_RenderCopyF(renderer, tile, nullptr, &draw_rect);
}
}
SDL_RenderSetClipRect(renderer, nullptr);
} }
} }
} }
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture* tile)
{
fill_texture(renderer, texture, tile, get_texture_box(texture));
}
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, const SDL_Color& color, Uint32 format) SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, const SDL_Color& color, Uint32 format)
{ {
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y); SDL_Texture* texture;
sfw::fill_texture(renderer, texture, color.r, color.g, color.b, color.a); if ((texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y)) == nullptr)
{
print_sdl_error("could not create texture to fill");
}
else
{
sfw::fill_texture(renderer, texture, color);
}
return texture; return texture;
} }
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, SDL_Texture* tile, Uint32 format) SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, SDL_Texture* tile, Uint32 format)
{ {
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y); SDL_Texture* texture;
sfw::fill_texture(renderer, texture, tile); if ((texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y)) == nullptr)
{
print_sdl_error("could not create texture to fill");
}
else
{
sfw::fill_texture(renderer, texture, tile);
}
return texture; return texture;
} }
@ -275,7 +313,7 @@ SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, c
} }
SDL_Texture* sfw::get_remapped_texture( SDL_Texture* sfw::get_remapped_texture(
SDL_Renderer* renderer, SDL_Texture* base, const std::map<SDL_Color, SDL_Color>& map) SDL_Renderer* renderer, SDL_Texture* base, const std::map<Color, Color>& map)
{ {
SDL_Texture* remapped = duplicate_texture(renderer, base); SDL_Texture* remapped = duplicate_texture(renderer, base);
if (remapped == nullptr) if (remapped == nullptr)
@ -288,50 +326,26 @@ SDL_Texture* sfw::get_remapped_texture(
print_sdl_error("could not set render target to remapped texture"); print_sdl_error("could not set render target to remapped texture");
return nullptr; return nullptr;
} }
Box box = get_texture_box(remapped); Pixels pixels = Pixels(renderer, remapped);
std::uint32_t format; for (int x = 0; x < pixels.rect.w; x++)
SDL_QueryTexture(remapped, &format, nullptr, nullptr, nullptr);
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
int bytes_total = bytes_per_pixel * box.get_w() * box.get_h();
unsigned char* pixels = new unsigned char[bytes_total];
if ((SDL_RenderReadPixels(renderer, nullptr, format, pixels, bytes_total / box.get_h())) < 0)
{ {
print_sdl_error("could not read pixels after setting remapped texture as target"); for (int y = 0; y < pixels.rect.h; y++)
return nullptr;
}
SDL_Color color;
for (int ii = 0; ii < bytes_total; ii += bytes_per_pixel)
{
color = {pixels[ii], pixels[ii + 1], pixels[ii + 2], 255};
if (bytes_per_pixel == 4)
{ {
color.a = pixels[ii + 3]; for (auto& [original, replacement] : map)
}
for (auto& pair : map)
{
if (color.r == pair.first.r && color.g == pair.first.g && color.b == pair.first.b &&
(bytes_per_pixel < 4 || color.a == pair.first.a))
{ {
pixels[ii] = pair.second.r; if (pixels.get(x, y) == original)
pixels[ii + 1] = pair.second.g;
pixels[ii + 2] = pair.second.b;
if (bytes_per_pixel == 4)
{ {
pixels[ii + 3] = pair.second.a; pixels.set(replacement, x, y);
} }
} }
} }
} }
if (SDL_UpdateTexture(remapped, nullptr, pixels, bytes_total / box.get_h()) < 0) pixels.apply();
{
print_sdl_error("could not update remapped texture");
}
delete[] pixels;
return remapped; return remapped;
} }
SDL_Texture* sfw::get_remapped_texture( SDL_Texture* sfw::get_remapped_texture(
SDL_Renderer* renderer, const std::string& path, const std::map<SDL_Color, SDL_Color>& map) SDL_Renderer* renderer, const std::string& path, const std::map<Color, Color>& map)
{ {
SDL_Texture* base = IMG_LoadTexture(renderer, path.c_str()); SDL_Texture* base = IMG_LoadTexture(renderer, path.c_str());
if (base == nullptr) if (base == nullptr)
@ -530,16 +544,6 @@ std::ostream& operator<<(std::ostream& out, const glm::vec2& vector)
return out; return out;
} }
bool operator<(const SDL_Color& color_1, const SDL_Color& color_2)
{
return color_1.r < color_2.r || color_1.g < color_2.g || color_1.b < color_2.b || color_1.a < color_2.a;
}
bool operator==(const SDL_Color& color_1, const SDL_Color& color_2)
{
return color_1.r == color_2.r && color_1.g == color_2.g && color_1.b == color_2.b && color_1.a == color_2.a;
}
std::ostream& operator<<(std::ostream& out, const SDL_Color& color) std::ostream& operator<<(std::ostream& out, const SDL_Color& color)
{ {
out << "{" << static_cast<int>(color.r) << ", " << static_cast<int>(color.g) << ", " << out << "{" << static_cast<int>(color.r) << ", " << static_cast<int>(color.g) << ", " <<

View File

@ -44,15 +44,17 @@ namespace sfw
std::vector<SDL_Texture*> get_halo_frames( std::vector<SDL_Texture*> get_halo_frames(
Node&, float, int, const std::vector<SDL_Color>& = {{0, 0, 0, 255}, {255, 255, 255, 255}}, float = 4.0f, bool = true); Node&, float, int, const std::vector<SDL_Color>& = {{0, 0, 0, 255}, {255, 255, 255, 255}}, float = 4.0f, bool = true);
std::vector<SDL_Texture*> get_portal_frames(SDL_Renderer*, glm::vec2, float = 60, float = 30, int = 4, int = 6); std::vector<SDL_Texture*> get_portal_frames(SDL_Renderer*, glm::vec2, float = 60, float = 30, int = 4, int = 6);
void fill_texture(SDL_Renderer*, SDL_Texture*, Uint8, Uint8, Uint8, Uint8 = 0xff); void fill_texture(SDL_Renderer*, SDL_Texture*, const SDL_Color&, const Box&);
void fill_texture(SDL_Renderer*, SDL_Texture*, const SDL_Color&);
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*, const Box&);
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*); void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, const SDL_Color&, Uint32 = SDL_PIXELFORMAT_RGBA32); SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, const SDL_Color&, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32); SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_hue_shifted_texture(SDL_Renderer*, SDL_Texture*, float); SDL_Texture* get_hue_shifted_texture(SDL_Renderer*, SDL_Texture*, float);
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*); SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*);
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, const glm::vec2&); SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, const glm::vec2&);
SDL_Texture* get_remapped_texture(SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&); SDL_Texture* get_remapped_texture(SDL_Renderer*, SDL_Texture*, const std::map<Color, Color>&);
SDL_Texture* get_remapped_texture(SDL_Renderer*, const std::string&, const std::map<SDL_Color, SDL_Color>&); SDL_Texture* get_remapped_texture(SDL_Renderer*, const std::string&, const std::map<Color, Color>&);
SDL_Texture* get_pixel_scaled_texture(SDL_Renderer*, SDL_Texture*, int = 1, int = scaler::scale2x); SDL_Texture* get_pixel_scaled_texture(SDL_Renderer*, SDL_Texture*, int = 1, int = scaler::scale2x);
std::vector<fs::path> glob(fs::path); std::vector<fs::path> glob(fs::path);
fs::path get_next_file_name( fs::path get_next_file_name(
@ -94,49 +96,71 @@ namespace sfw
return padded.str(); return padded.str();
} }
template <typename N> template <typename N, typename N2 = N>
std::vector<N> range_step(N start, N end, int count) std::vector<N2> range(N start, N stop, N2 step)
{ {
float step = (end - start) / (count - 1); if (step == N2(0))
std::vector<N> nums;
nums.reserve(count);
for (int ii = 0; ii < count; ii++)
{
nums.push_back(start + ii * step);
}
return nums;
}
// from https://stackoverflow.com/a/30312659/1256386
template <typename IntType>
std::vector<IntType> range(IntType start, IntType stop, IntType step)
{
if (step == IntType(0))
{ {
throw std::invalid_argument("step for range must be non-zero"); throw std::invalid_argument("step for range must be non-zero");
} }
std::vector<IntType> result; std::vector<N2> result;
IntType i = start; while ((step > 0) ? (start < stop) : (start > stop))
while ((step > 0) ? (i < stop) : (i > stop))
{ {
result.push_back(i); result.push_back(start);
i += step; start += step;
} }
return result; return result;
} }
// from https://stackoverflow.com/a/30312659/1256386 template <typename N>
template <typename IntType> std::vector<N> range(N start, N stop)
std::vector<IntType> range(IntType start, IntType stop)
{ {
return range(start, stop, IntType(1)); return range(start, stop, N(1));
} }
// from https://stackoverflow.com/a/30312659/1256386 template <typename N>
template <typename IntType> std::vector<N> range(N stop)
std::vector<IntType> range(IntType stop)
{ {
return range(IntType(0), stop, IntType(1)); return range(N(0), stop, N(1));
}
template <typename N>
std::vector<float> range_count(N start, N end, int count)
{
float step = (end - start) / (count - 1);
std::vector<float> all;
all.reserve(count);
for (int ii = 0; ii < count; ii++)
{
all.push_back(start + ii * step);
}
return all;
}
template <typename N, typename N2 = N>
std::map<float, N2> range_percent(N start, N end, N2 step = N(1))
{
std::map<float, N2> range_percent_map;
std::vector<N2> all = range(start, end, step);
int ii = 0;
for (N2& current : all)
{
range_percent_map[ii++ / static_cast<float>(all.size() - 1)] = current;
}
return range_percent_map;
}
template <typename N>
std::map<float, float> range_percent_count(N start, N end, int count)
{
std::map<float, float> range_percent_map;
std::vector<float> all = range_count(start, end, count);
int ii = 0;
for (float& current : all)
{
range_percent_map[ii++ / static_cast<float>(all.size() - 1)] = current;
}
return range_percent_map;
} }
} }
@ -154,8 +178,6 @@ std::ostream& operator<<(std::ostream& out, const std::vector<T>& members)
} }
std::ostream& operator<<(std::ostream&, const glm::vec2&); std::ostream& operator<<(std::ostream&, const glm::vec2&);
bool operator<(const SDL_Color& color_1, const SDL_Color& color_2);
bool operator==(const SDL_Color& color_1, const SDL_Color& color_2);
std::ostream& operator<<(std::ostream&, const SDL_Color&); std::ostream& operator<<(std::ostream&, const SDL_Color&);
namespace glm namespace glm
@ -175,5 +197,6 @@ namespace glm
} }
#include "Node.hpp" #include "Node.hpp"
#include "Pixels.hpp"
#endif #endif