- Pixel class generalizes pixel access, reads, writes, and applies
pixel value modifications to textures of any SDL_TEXTUREACCESS_* and any pixel format - Color inherits SDL_Color directly instead of emulating it - added cast operator for converting Box to SDL_Rect
This commit is contained in:
parent
14afcef0ce
commit
8346f43f21
|
@ -248,6 +248,11 @@ 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)};
|
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
|
||||||
|
{
|
||||||
|
return {static_cast<int>(rect.x), static_cast<int>(rect.y), static_cast<int>(rect.w), static_cast<int>(rect.h)};
|
||||||
|
}
|
||||||
|
|
||||||
void Box::clear()
|
void Box::clear()
|
||||||
{
|
{
|
||||||
set_nw(glm::vec2(0, 0));
|
set_nw(glm::vec2(0, 0));
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct Segment;
|
||||||
|
|
||||||
struct Box
|
struct Box
|
||||||
{
|
{
|
||||||
|
|
||||||
SDL_FRect rect = {0, 0, 0, 0};
|
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});
|
||||||
|
@ -61,6 +62,7 @@ struct Box
|
||||||
void set_center(const glm::vec2&);
|
void set_center(const glm::vec2&);
|
||||||
SDL_FRect* get_rect();
|
SDL_FRect* get_rect();
|
||||||
SDL_Rect get_int_rect() const;
|
SDL_Rect get_int_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&);
|
||||||
|
|
|
@ -2,37 +2,36 @@
|
||||||
|
|
||||||
Color::Color() : Color(0, 0, 0, 255) {}
|
Color::Color() : Color(0, 0, 0, 255) {}
|
||||||
|
|
||||||
Color::Color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) : r(r), g(g), b(b), a(a) {};
|
|
||||||
|
|
||||||
Color::Color(const SDL_Color& color) : Color(color.r, color.g, color.b, color.a) {};
|
Color::Color(const SDL_Color& color) : Color(color.r, color.g, color.b, color.a) {};
|
||||||
|
|
||||||
void Color::set_rgb_float(const float& rf, const float& gf, const float& bf)
|
void Color::set_percent(const float& red, const float& green, const float& blue)
|
||||||
{
|
{
|
||||||
r = std::round(255.0f * rf);
|
r = std::round(255.0f * red);
|
||||||
g = std::round(255.0f * gf);
|
g = std::round(255.0f * green);
|
||||||
b = std::round(255.0f * bf);
|
b = std::round(255.0f * blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Color::set_hsv(const float& h, const float& s, const float& v)
|
void Color::set_percent(const float& red, const float& green, const float& blue, const float& alpha)
|
||||||
{
|
{
|
||||||
float rf, gf, bf;
|
a = std::round(255.0f * alpha);
|
||||||
HSVtoRGB(rf, gf, bf, h, s, v);
|
set_percent(red, green, blue);
|
||||||
set_rgb_float(rf, gf, bf);
|
}
|
||||||
|
|
||||||
|
void Color::set_hsv(const float& hue, const float& saturation, const float& value)
|
||||||
|
{
|
||||||
|
float red_percent, green_percent, blue_percent;
|
||||||
|
HSVtoRGB(red_percent, green_percent, blue_percent, hue, saturation, value);
|
||||||
|
set_percent(red_percent, green_percent, blue_percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Color::shift_hue(float offset)
|
void Color::shift_hue(float offset)
|
||||||
{
|
{
|
||||||
float h, s, v;
|
float hue, saturation, value;
|
||||||
float rf = r / 255.0f, gf = g / 255.0f, bf = b / 255.0f;
|
float red_percent = r / 255.0f, green_percent = g / 255.0f, blue_percent = b / 255.0f;
|
||||||
RGBtoHSV(rf, gf, bf, h, s, v);
|
RGBtoHSV(red_percent, green_percent, blue_percent, hue, saturation, value);
|
||||||
h = std::fmod(h + offset, 360.0);
|
hue = std::fmod(hue + offset, 360.0);
|
||||||
HSVtoRGB(rf, gf, bf, h, s, v);
|
HSVtoRGB(red_percent, green_percent, blue_percent, hue, saturation, value);
|
||||||
set_rgb_float(rf, gf, bf);
|
set_percent(red_percent, green_percent, blue_percent);
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Color Color::get_sdl_color()
|
|
||||||
{
|
|
||||||
return {r, g, b, a};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Color& color)
|
std::ostream& operator<<(std::ostream& out, const Color& color)
|
||||||
|
|
|
@ -5,21 +5,36 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "SDL_pixels.h"
|
#include "SDL_pixels.h"
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
struct Color
|
struct Color : SDL_Color
|
||||||
{
|
{
|
||||||
|
|
||||||
std::uint8_t r, g, b, a;
|
|
||||||
|
|
||||||
Color();
|
Color();
|
||||||
Color(std::uint8_t, std::uint8_t, std::uint8_t, std::uint8_t = 255);
|
|
||||||
Color(const SDL_Color&);
|
Color(const SDL_Color&);
|
||||||
void set_rgb_float(const float&, const float&, const float&);
|
void set_percent(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);
|
||||||
SDL_Color get_sdl_color();
|
|
||||||
|
template <typename T>
|
||||||
|
Color(T red, T green, T blue, T alpha = 255)
|
||||||
|
{
|
||||||
|
if (std::is_floating_point<T>())
|
||||||
|
{
|
||||||
|
red = std::round(red);
|
||||||
|
green = std::round(green);
|
||||||
|
blue = std::round(blue);
|
||||||
|
alpha = std::round(alpha);
|
||||||
|
}
|
||||||
|
r = static_cast<int>(red) & 255;
|
||||||
|
g = static_cast<int>(green) & 255;
|
||||||
|
b = static_cast<int>(blue) & 255;
|
||||||
|
a = static_cast<int>(alpha) & 255;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
#include "Pixels.hpp"
|
||||||
|
|
||||||
|
Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture) : Pixels(renderer, texture, sfw::get_texture_box(texture)) {}
|
||||||
|
|
||||||
|
Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect& rect) : texture(texture), rect(rect)
|
||||||
|
{
|
||||||
|
Uint32 format_enum;
|
||||||
|
int w, h;
|
||||||
|
SDL_QueryTexture(texture, &format_enum, &texture_access, &w, &h);
|
||||||
|
format = SDL_AllocFormat(format_enum);
|
||||||
|
if (texture_access == SDL_TEXTUREACCESS_STATIC || texture_access == SDL_TEXTUREACCESS_TARGET)
|
||||||
|
{
|
||||||
|
bool is_duplicate;
|
||||||
|
SDL_Texture* base;
|
||||||
|
if (texture_access == SDL_TEXTUREACCESS_STATIC)
|
||||||
|
{
|
||||||
|
base = sfw::duplicate_texture(renderer, texture);
|
||||||
|
is_duplicate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base = texture;
|
||||||
|
is_duplicate = false;
|
||||||
|
}
|
||||||
|
SDL_SetRenderTarget(renderer, base);
|
||||||
|
int bytes_total = get_bytes_per_row() * rect.h;
|
||||||
|
source = operator new(bytes_total);
|
||||||
|
if (SDL_RenderReadPixels(renderer, &rect, format->format, source, format->BytesPerPixel * rect.w) < 0)
|
||||||
|
{
|
||||||
|
sfw::print_sdl_error("could not read pixels");
|
||||||
|
operator delete(source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allocated = true;
|
||||||
|
}
|
||||||
|
if (is_duplicate)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (texture_access == SDL_TEXTUREACCESS_STREAMING)
|
||||||
|
{
|
||||||
|
int pitch;
|
||||||
|
if (SDL_LockTexture(texture, &rect, &source, &pitch) < 0)
|
||||||
|
{
|
||||||
|
sfw::print_sdl_error("could not lock texture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sfw::print_error("unknown texture format for loading pixels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pixels::get_bytes_per_row() const
|
||||||
|
{
|
||||||
|
return format->BytesPerPixel * rect.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Pixels::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 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;
|
||||||
|
SDL_GetRGBA(*pixel, const_cast<SDL_PixelFormat*>(format), &color.r, &color.g, &color.b, &color.a);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (format->BytesPerPixel == 1)
|
||||||
|
{
|
||||||
|
std::uint8_t* access = reinterpret_cast<std::uint8_t*>((*this)(x, y));
|
||||||
|
*access = static_cast<std::uint8_t>(pixel);
|
||||||
|
}
|
||||||
|
else if (format->BytesPerPixel == 2)
|
||||||
|
{
|
||||||
|
std::uint16_t* access = reinterpret_cast<std::uint16_t*>((*this)(x, y));
|
||||||
|
*access = static_cast<std::uint16_t>(pixel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::uint32_t* access = reinterpret_cast<std::uint32_t*>((*this)(x, y));
|
||||||
|
*access = static_cast<std::uint32_t>(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pixels::apply()
|
||||||
|
{
|
||||||
|
if (texture_access == SDL_TEXTUREACCESS_STATIC || texture_access == SDL_TEXTUREACCESS_TARGET)
|
||||||
|
{
|
||||||
|
SDL_UpdateTexture(texture, &rect, source, get_bytes_per_row());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_UnlockTexture(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixels::~Pixels()
|
||||||
|
{
|
||||||
|
if (allocated)
|
||||||
|
{
|
||||||
|
operator delete(source);
|
||||||
|
}
|
||||||
|
if (texture_access == SDL_TEXTUREACCESS_STREAMING)
|
||||||
|
{
|
||||||
|
SDL_UnlockTexture(texture);
|
||||||
|
}
|
||||||
|
SDL_FreeFormat(format);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef Pixels_h_
|
||||||
|
#define Pixels_h_
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "Box.hpp"
|
||||||
|
#include "Color.hpp"
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
struct Sprite;
|
||||||
|
|
||||||
|
struct Pixels
|
||||||
|
{
|
||||||
|
|
||||||
|
void* source = nullptr;
|
||||||
|
SDL_PixelFormat* format = nullptr;
|
||||||
|
SDL_Texture* texture;
|
||||||
|
int texture_access = 0;
|
||||||
|
SDL_Rect rect;
|
||||||
|
bool allocated = false;
|
||||||
|
|
||||||
|
Pixels(SDL_Renderer*, SDL_Texture* texture);
|
||||||
|
Pixels(SDL_Renderer*, SDL_Texture* texture, const SDL_Rect&);
|
||||||
|
Pixels(Sprite&);
|
||||||
|
Pixels(Sprite&, const SDL_Rect&);
|
||||||
|
int get_bytes_per_row() const;
|
||||||
|
void* operator()(int x, int y);
|
||||||
|
Color operator()(int x, int y) const;
|
||||||
|
void set(const SDL_Color&, int x, int y);
|
||||||
|
void apply();
|
||||||
|
~Pixels();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -797,3 +797,6 @@ void Frameset::reverse()
|
||||||
{
|
{
|
||||||
reversed = !reversed;
|
reversed = !reversed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pixels::Pixels(Sprite& sprite) : Pixels(sprite.get_renderer(), sprite.get_current_frame()) {}
|
||||||
|
Pixels::Pixels(Sprite& sprite, const SDL_Rect& rect) : Pixels(sprite.get_renderer(), sprite.get_current_frame(), rect) {}
|
||||||
|
|
|
@ -156,6 +156,7 @@ struct Frameset
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "Pixels.hpp"
|
||||||
#include "Game.hpp"
|
#include "Game.hpp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -201,48 +201,56 @@ SDL_Texture* sfw::get_hue_shifted_texture(SDL_Renderer* renderer, SDL_Texture* b
|
||||||
SDL_Texture* hue_shifted_texture = sfw::duplicate_texture(renderer, base);
|
SDL_Texture* hue_shifted_texture = sfw::duplicate_texture(renderer, base);
|
||||||
Uint32 pixel_format;
|
Uint32 pixel_format;
|
||||||
int w, h;
|
int w, h;
|
||||||
SDL_QueryTexture(hue_shifted_texture, &pixel_format, NULL, &w, &h);
|
if (SDL_QueryTexture(hue_shifted_texture, &pixel_format, nullptr, &w, &h) < 0)
|
||||||
SDL_PixelFormat* pixel_format_struct = SDL_AllocFormat(pixel_format);
|
|
||||||
SDL_SetRenderTarget(renderer, hue_shifted_texture);
|
|
||||||
int bytes_per_pixel = SDL_BYTESPERPIXEL(pixel_format);
|
|
||||||
int bytes_per_row = bytes_per_pixel * w;
|
|
||||||
int bytes_total = bytes_per_row * h;
|
|
||||||
int length = bytes_total / 4 + (bytes_total % 4 ? 1 : 0);
|
|
||||||
Uint32* pixels = new Uint32[length];
|
|
||||||
if (SDL_RenderReadPixels(renderer, NULL, pixel_format, pixels, bytes_per_row) < 0)
|
|
||||||
{
|
{
|
||||||
print_sdl_error("Could not read pixels");
|
print_sdl_error("could not query texture");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Color rgba;
|
SDL_PixelFormat* pixel_format_struct = SDL_AllocFormat(pixel_format);
|
||||||
for (int ii = 0; ii < length; ii++)
|
SDL_SetRenderTarget(renderer, hue_shifted_texture);
|
||||||
|
int bytes_per_pixel = SDL_BYTESPERPIXEL(pixel_format);
|
||||||
|
int bytes_per_row = bytes_per_pixel * w;
|
||||||
|
int bytes_total = bytes_per_row * h;
|
||||||
|
int length = bytes_total / 4 + (bytes_total % 4 ? 1 : 0);
|
||||||
|
Uint32* pixels = new Uint32[length];
|
||||||
|
if (SDL_RenderReadPixels(renderer, NULL, pixel_format, pixels, bytes_per_row) < 0)
|
||||||
{
|
{
|
||||||
SDL_GetRGBA(pixels[ii], const_cast<const SDL_PixelFormat*>(pixel_format_struct),
|
print_sdl_error("Could not read pixels");
|
||||||
&rgba.r, &rgba.g, &rgba.b, &rgba.a);
|
|
||||||
rgba.shift_hue(offset);
|
|
||||||
pixels[ii] = SDL_MapRGBA(const_cast<const SDL_PixelFormat*>(pixel_format_struct), rgba.r, rgba.g, rgba.b, rgba.a);
|
|
||||||
}
|
}
|
||||||
if (SDL_UpdateTexture(hue_shifted_texture, NULL, pixels, bytes_per_row) < 0)
|
else
|
||||||
{
|
{
|
||||||
print_sdl_error("Could not apply hue shifted pixels update to texture");
|
Color rgba;
|
||||||
|
for (int ii = 0; ii < length; ii++)
|
||||||
|
{
|
||||||
|
SDL_GetRGBA(pixels[ii], const_cast<const SDL_PixelFormat*>(pixel_format_struct),
|
||||||
|
&rgba.r, &rgba.g, &rgba.b, &rgba.a);
|
||||||
|
rgba.shift_hue(offset);
|
||||||
|
pixels[ii] = SDL_MapRGBA(const_cast<const SDL_PixelFormat*>(pixel_format_struct), rgba.r, rgba.g, rgba.b, rgba.a);
|
||||||
|
}
|
||||||
|
if (SDL_UpdateTexture(hue_shifted_texture, NULL, pixels, bytes_per_row) < 0)
|
||||||
|
{
|
||||||
|
print_sdl_error("Could not apply hue shifted pixels update to texture");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
delete[] pixels;
|
||||||
|
SDL_FreeFormat(pixel_format_struct);
|
||||||
}
|
}
|
||||||
delete[] pixels;
|
|
||||||
SDL_FreeFormat(pixel_format_struct);
|
|
||||||
return hue_shifted_texture;
|
return hue_shifted_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, Uint32 format)
|
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base)
|
||||||
{
|
{
|
||||||
Box box = get_texture_box(base);
|
Box box = get_texture_box(base);
|
||||||
return duplicate_texture(renderer, base, box.get_size(), format);
|
return duplicate_texture(renderer, base, box.get_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, const glm::vec2& size, Uint32 format)
|
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, const glm::vec2& size)
|
||||||
{
|
{
|
||||||
SDL_BlendMode original_blend_mode;
|
SDL_BlendMode original_blend_mode;
|
||||||
SDL_GetTextureBlendMode(base, &original_blend_mode);
|
SDL_GetTextureBlendMode(base, &original_blend_mode);
|
||||||
|
Uint32 format;
|
||||||
|
SDL_QueryTexture(base, &format, nullptr, nullptr, nullptr);
|
||||||
SDL_Texture* duplicate = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
|
SDL_Texture* duplicate = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
|
||||||
if (duplicate == NULL)
|
if (duplicate == NULL)
|
||||||
{
|
{
|
||||||
|
@ -256,10 +264,10 @@ SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, c
|
||||||
}
|
}
|
||||||
SDL_SetTextureBlendMode(base, SDL_BLENDMODE_NONE);
|
SDL_SetTextureBlendMode(base, SDL_BLENDMODE_NONE);
|
||||||
SDL_SetTextureBlendMode(duplicate, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(duplicate, SDL_BLENDMODE_BLEND);
|
||||||
if ((SDL_RenderCopyF(renderer, base, NULL, NULL)) < 0)
|
if ((SDL_RenderCopyF(renderer, base, nullptr, nullptr)) < 0)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not render base onto duplicate");
|
print_sdl_error("could not render base onto duplicate");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
SDL_SetTextureBlendMode(base, original_blend_mode);
|
SDL_SetTextureBlendMode(base, original_blend_mode);
|
||||||
SDL_SetTextureBlendMode(duplicate, original_blend_mode);
|
SDL_SetTextureBlendMode(duplicate, original_blend_mode);
|
||||||
|
@ -267,27 +275,29 @@ 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, Uint32 format)
|
SDL_Renderer* renderer, SDL_Texture* base, const std::map<SDL_Color, SDL_Color>& map)
|
||||||
{
|
{
|
||||||
SDL_Texture* remapped = duplicate_texture(renderer, base, format);
|
SDL_Texture* remapped = duplicate_texture(renderer, base);
|
||||||
if (remapped == NULL)
|
if (remapped == nullptr)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not duplicate base texture");
|
print_sdl_error("could not duplicate base texture");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if ((SDL_SetRenderTarget(renderer, remapped)) < 0)
|
if ((SDL_SetRenderTarget(renderer, remapped)) < 0)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not set render target to remapped texture");
|
print_sdl_error("could not set render target to remapped texture");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Box box = get_texture_box(remapped);
|
Box box = get_texture_box(remapped);
|
||||||
|
std::uint32_t format;
|
||||||
|
SDL_QueryTexture(remapped, &format, nullptr, nullptr, nullptr);
|
||||||
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
|
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
|
||||||
int bytes_total = bytes_per_pixel * box.get_w() * box.get_h();
|
int bytes_total = bytes_per_pixel * box.get_w() * box.get_h();
|
||||||
unsigned char* pixels = new unsigned char[bytes_total];
|
unsigned char* pixels = new unsigned char[bytes_total];
|
||||||
if ((SDL_RenderReadPixels(renderer, NULL, format, pixels, bytes_total / box.get_h())) < 0)
|
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");
|
print_sdl_error("could not read pixels after setting remapped texture as target");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
SDL_Color color;
|
SDL_Color color;
|
||||||
for (int ii = 0; ii < bytes_total; ii += bytes_per_pixel)
|
for (int ii = 0; ii < bytes_total; ii += bytes_per_pixel)
|
||||||
|
@ -312,7 +322,7 @@ SDL_Texture* sfw::get_remapped_texture(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SDL_UpdateTexture(remapped, NULL, pixels, bytes_total / box.get_h()) < 0)
|
if (SDL_UpdateTexture(remapped, nullptr, pixels, bytes_total / box.get_h()) < 0)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not update remapped texture");
|
print_sdl_error("could not update remapped texture");
|
||||||
}
|
}
|
||||||
|
@ -321,19 +331,19 @@ SDL_Texture* sfw::get_remapped_texture(
|
||||||
}
|
}
|
||||||
|
|
||||||
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, Uint32 format)
|
SDL_Renderer* renderer, const std::string& path, const std::map<SDL_Color, SDL_Color>& map)
|
||||||
{
|
{
|
||||||
SDL_Texture* base = IMG_LoadTexture(renderer, path.c_str());
|
SDL_Texture* base = IMG_LoadTexture(renderer, path.c_str());
|
||||||
if (base == NULL)
|
if (base == nullptr)
|
||||||
{
|
{
|
||||||
print_sdl_error("error loading file");
|
print_sdl_error("error loading file");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
SDL_Texture* remapped = get_remapped_texture(renderer, base, map, format);
|
SDL_Texture* remapped = get_remapped_texture(renderer, base, map);
|
||||||
if (remapped == NULL)
|
if (remapped == nullptr)
|
||||||
{
|
{
|
||||||
print_error("could not remap texture");
|
print_error("could not remap texture");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
SDL_DestroyTexture(base);
|
SDL_DestroyTexture(base);
|
||||||
return remapped;
|
return remapped;
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace sfw
|
||||||
Box get_texture_box(SDL_Texture*);
|
Box get_texture_box(SDL_Texture*);
|
||||||
void populate_pixel_2d_array(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&);
|
void populate_pixel_2d_array(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&);
|
||||||
void populate_pixel_2d_array(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&, const Box&);
|
void populate_pixel_2d_array(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&, const Box&);
|
||||||
|
void apply_array_to_texture(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&);
|
||||||
|
void apply_array_to_texture(SDL_Renderer*, SDL_Texture*, std::vector<std::vector<SDL_Color>>&, const Box&);
|
||||||
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);
|
||||||
|
@ -47,13 +49,10 @@ namespace sfw
|
||||||
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*, Uint32 = SDL_PIXELFORMAT_RGBA32);
|
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*);
|
||||||
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, const glm::vec2&, Uint32 = SDL_PIXELFORMAT_RGBA32);
|
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, const glm::vec2&);
|
||||||
SDL_Texture* get_remapped_texture(
|
SDL_Texture* get_remapped_texture(SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&);
|
||||||
SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&, Uint32 = SDL_PIXELFORMAT_RGBA32);
|
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<SDL_Color, SDL_Color>&,
|
|
||||||
Uint32 = SDL_PIXELFORMAT_RGBA32);
|
|
||||||
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(
|
||||||
|
@ -80,7 +79,7 @@ namespace sfw
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
float mod(N a, N b)
|
inline float mod(N a, N b)
|
||||||
{
|
{
|
||||||
return (b + (a % b)) % b;
|
return (b + (a % b)) % b;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue