- extended version of sdl gfx primitives

- drag left and right edge box
- complete segment member functions
- extension functions: get segments, get relative step, populate
pixel array
This commit is contained in:
Frank DeMarco 2020-08-06 18:54:50 -04:00
parent 1861b80aa4
commit f5d03b9be6
16 changed files with 5585 additions and 3863 deletions

View File

@ -11,7 +11,7 @@
dict with metadata, move added sprite locations by offset when location is
changed, gradients, level select code input, logging, variable screen
resolution, debug display, loading wheel animation, shadowed sprite, separate
update and draw, sprite movement cage
update and draw, sprite movement cage, multiple windows, multiple renderers
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
SDL2_gfxPrimitives.h: graphics primitives for SDL
Copyright (C) 2012-2014 Andreas Schiffler
Additions for BBC BASIC (C) 2016-2019 Richard Russell
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -24,6 +25,7 @@ misrepresented as being the original software.
distribution.
Andreas Schiffler -- aschiffler at ferzkopp dot net
Richard Russell -- richard at rtrussell dot co dot uk
*/
@ -35,7 +37,7 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net
#define M_PI 3.1415926535897932384626433832795
#endif
#include "SDL.h"
#include "SDL2/SDL.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
@ -46,7 +48,7 @@ extern "C" {
#define SDL2_GFXPRIMITIVES_MAJOR 1
#define SDL2_GFXPRIMITIVES_MINOR 0
#define SDL2_GFXPRIMITIVES_MICRO 4
#define SDL2_GFXPRIMITIVES_MICRO 1
/* ---- Function Prototypes */
@ -64,7 +66,8 @@ extern "C" {
# define SDL2_GFXPRIMITIVES_SCOPE extern
#endif
/* Note: all ___Color routines expect the color to be in format 0xRRGGBBAA */
/* Note: all ___Color routines expect the color to be in format 0xAABBGGRR */
/* assuming a little-endian CPU (or 0xRRGGBBAA for a big-endian CPU) */
/* Pixel */
@ -228,11 +231,37 @@ extern "C" {
SDL2_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch);
SDL2_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFontRotation(Uint32 rotation);
SDL2_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFontZoom(Uint32 zoomx, Uint32 zoomy);
SDL2_GFXPRIMITIVES_SCOPE int characterColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, char c, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int characterRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int stringColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int stringRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Richard Russell's additions */
SDL2_GFXPRIMITIVES_SCOPE int thickEllipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int thickEllipseRGBA(SDL_Renderer * renderer, Sint16 xc, Sint16 yc, Sint16 xr, Sint16 yr, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int thickArcColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int thickArcRGBA(SDL_Renderer * renderer, Sint16 xc, Sint16 yc, Sint16 rad, Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int thickCircleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int thickCircleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint8 thick);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledEllipseColor(SDL_Renderer * renderer, float cx, float cy, float rx, float ry, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledEllipseRGBA(SDL_Renderer * renderer, float cx, float cy, float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPolygonColor(SDL_Renderer * renderer, const double * vx, const double * vy, int n, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPolygonRGBA(SDL_Renderer * renderer, const double * vx, const double * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPieColor(SDL_Renderer * renderer, float cx, float cy, float rx, float ry, float start, float end, Uint32 chord, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPieRGBA(SDL_Renderer * renderer, float cx, float cy, float rx, float ry,
float start, float end, Uint32 chord, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int aaArcColor(SDL_Renderer * renderer, float cx, float cy, float rx, float ry, float start, float end, float thick, Uint32 color);
SDL2_GFXPRIMITIVES_SCOPE int aaArcRGBA(SDL_Renderer * renderer, float cx, float cy, float rx, float ry,
float start, float end, float thick, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int aaBezierColor(SDL_Renderer * renderer, double *x, double *y, int n, int s, float thick, int color);
SDL2_GFXPRIMITIVES_SCOPE int aaBezierRGBA(SDL_Renderer * renderer, double *x, double *y, int n, int s, float thick, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPolyBezierColor(SDL_Renderer * renderer, double *x, double *y, int n, int s, int color);
SDL2_GFXPRIMITIVES_SCOPE int aaFilledPolyBezierRGBA(SDL_Renderer * renderer, double *x, double *y, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}

View File

@ -47,6 +47,11 @@ glm::vec2 Box::get_size() const
return glm::vec2(get_w(), get_h());
}
float Box::get_area() const
{
return get_w() * get_h();
}
void Box::set_size(const glm::vec2& size, bool preserve_center)
{
glm::vec2 center = get_center();
@ -78,29 +83,78 @@ float Box::get_left() const
return get_x();
}
float Box::get_center_x() const
{
return get_left() + get_w() / 2;
}
float Box::get_center_y() const
{
return get_top() + get_h() / 2;
}
void Box::set_top(float top)
{
set_y(top);
}
void Box::set_right(float right)
void Box::set_right(float right, bool drag)
{
move(glm::vec2(right - get_right(), 0));
float delta = right - get_right();
if (!drag)
{
move({delta, 0});
}
else
{
drag_right(delta);
}
}
void Box::drag_right(float delta)
{
float previous_right = get_right();
set_right(get_right() + delta);
set_w(get_w() + previous_right - get_right());
}
void Box::set_bottom(float bottom)
{
move(glm::vec2(0, bottom - get_bottom()));
move({0, bottom - get_bottom()});
}
void Box::set_left(float left)
void Box::set_left(float left, bool drag)
{
set_x(left);
if (!drag)
{
set_x(left);
}
else
{
drag_left(left - get_left());
}
}
void Box::drag_left(float delta)
{
float previous_left = get_left();
set_left(get_left() + delta);
set_w(get_w() + previous_left - get_left());
}
void Box::set_center_x(float x)
{
move({x - get_center_x(), 0});
}
void Box::set_center_y(float y)
{
move({0, y - get_center_y()});
}
glm::vec2 Box::get_nw() const
{
return glm::vec2(get_x(), get_y());
return {get_x(), get_y()};
}
glm::vec2 Box::get_north() const
@ -115,12 +169,22 @@ glm::vec2 Box::get_ne() const
glm::vec2 Box::get_east() const
{
return glm::vec2(get_right(), get_y() + get_h() / 2);
return glm::vec2(get_right(), get_top() + get_h() / 2);
}
glm::vec2 Box::get_se() const
{
return glm::vec2(get_right(), get_bottom());
}
glm::vec2 Box::get_south() const
{
return glm::vec2(get_x() + get_w() / 2, get_bottom());
return glm::vec2(get_left() + get_w() / 2, get_bottom());
}
glm::vec2 Box::get_sw() const
{
return glm::vec2(get_left(), get_bottom());
}
glm::vec2 Box::get_west() const
@ -153,6 +217,11 @@ void Box::set_east(const glm::vec2& e)
move(e - get_east());
}
void Box::set_se(const glm::vec2& se)
{
move(se - get_se());
}
void Box::set_south(const glm::vec2& s)
{
move(s - get_south());
@ -173,7 +242,7 @@ SDL_FRect* Box::get_rect()
return ▭
}
SDL_Rect Box::get_int_rect()
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)};
}

View File

@ -24,30 +24,40 @@ struct Box
void set_h(float);
glm::vec2 get_size() const;
void set_size(const glm::vec2&, bool = false);
float get_area() const;
float get_top() const;
float get_right() const;
float get_bottom() const;
float get_left() const;
float get_center_x() const;
float get_center_y() const;
void set_top(float);
void set_right(float);
void set_right(float, bool=false);
void drag_right(float);
void set_bottom(float);
void set_left(float);
void set_left(float, bool=false);
void drag_left(float);
void set_center_x(float);
void set_center_y(float);
glm::vec2 get_nw() const;
glm::vec2 get_north() const;
glm::vec2 get_ne() const;
glm::vec2 get_east() const;
glm::vec2 get_se() const;
glm::vec2 get_south() const;
glm::vec2 get_sw() const;
glm::vec2 get_west() const;
glm::vec2 get_center() const;
void set_nw(const glm::vec2&);
void set_north(const glm::vec2&);
void set_ne(const glm::vec2&);
void set_east(const glm::vec2&);
void set_se(const glm::vec2&);
void set_south(const glm::vec2&);
void set_west(const glm::vec2&);
void set_center(const glm::vec2&);
SDL_FRect* get_rect();
SDL_Rect get_int_rect();
SDL_Rect get_int_rect() const;
void clear();
void scale(float, bool = false);
void move(const glm::vec2&);

View File

@ -40,7 +40,8 @@ void Configuration::set_defaults()
sys_config["display"] = {
{"dimensions", {640, 480}},
{"framerate", 60},
{"title", "sfw"}
{"title", "sfw"},
{"debug", false}
};
sys_config["recording"] = {
{"enabled", false},

View File

@ -455,6 +455,11 @@ SDL_Renderer* Game::get_renderer()
return renderer;
}
glm::vec2 Game::weight(glm::vec2 motion)
{
return {weight(motion.x), weight(motion.y)};
}
void Game::run()
{
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
@ -467,7 +472,7 @@ void Game::run()
while (!done)
{
frame(SDL_GetTicks());
SDL_Delay(0);
SDL_Delay(8);
}
#endif
}
@ -538,11 +543,6 @@ void Game::flag_to_end()
done = true;
}
glm::vec2 Game::weight(glm::vec2 motion)
{
return glm::vec2(weight(motion.x), weight(motion.y));
}
void Game::set_framerate(int f)
{
if (f < 1)

View File

@ -79,11 +79,11 @@ struct Game : Node
std::string get_pixel_format_string(Uint32);
SDL_Window* get_window();
SDL_Renderer* get_renderer();
glm::vec2 weight(glm::vec2);
void run();
void frame(float);
void flag_to_end();
virtual void update() {};
glm::vec2 weight(glm::vec2);
void set_framerate(int);
void handle_quit_event(SDL_Event&);
void quit();
@ -92,7 +92,6 @@ struct Game : Node
template<typename T>
float weight(T amount)
{
// std::cout << amount << " - " << last_frame_length << std::endl;
return (last_frame_length / (1000.0 / 60)) * amount;
}

View File

@ -34,16 +34,6 @@ nlohmann::json& Node::get_configuration()
return get_root()->configuration.config;
}
// Game* Node::get_root()
// {
// Node* current = this;
// while (current->parent != NULL)
// {
// current = current->parent;
// }
// return static_cast<Game*>(current);
// }
Delegate& Node::get_delegate()
{
return get_root()->delegate;
@ -54,6 +44,16 @@ Display& Node::get_display()
return get_root()->display;
}
SDL_Renderer* Node::get_renderer()
{
return get_root()->get_renderer();
}
SDL_Window* Node::get_window()
{
return get_root()->get_window();
}
void Node::suppress_input_temporarily(int length)
{
get_root()->input.suppress();

View File

@ -3,6 +3,7 @@
#include <iostream>
#include "glm/vec2.hpp"
#include "json/json.hpp"
#include "SDL.h"
@ -28,6 +29,8 @@ struct Node
nlohmann::json& get_configuration();
Delegate& get_delegate();
Display& get_display();
SDL_Renderer* get_renderer();
SDL_Window* get_window();
void suppress_input_temporarily(int = 0);
void print_branch();
virtual std::string get_class_name() { return "Node"; };

View File

@ -6,8 +6,34 @@ Segment::Segment(const glm::vec2& location) : Segment(location, location) {};
Segment::Segment(const glm::vec2& start, const glm::vec2& end) : start(start), end(end) {};
glm::vec2 Segment::get_intersection()
glm::vec2 Segment::get_start() const
{
return start;
}
void Segment::set_start(const glm::vec2& s)
{
start = s;
}
glm::vec2 Segment::get_end() const
{
return end;
}
void Segment::set_end(const glm::vec2& e)
{
end = e;
}
bool Segment::intersect(const Segment& segment)
{
return sfw::segments_intersect(*this, segment);
}
bool Segment::intersect(const Segment& segment, glm::vec2& intersection)
{
return sfw::segments_intersect(*this, segment, intersection);
}
float Segment::get_dx()
@ -28,10 +54,12 @@ void Segment::move(const glm::vec2& delta)
glm::vec2 Segment::get_center()
{
return sfw::get_segments(*this, 2)[0].end;
}
std::ostream& operator<<(std::ostream& out, const Segment& segment)
{
out << "{(" << segment.start.x << ", " << segment.start.y << "), (" << segment.end.x << ", " << segment.end.y << ")}";
out << "{(" << segment.start.x << ", " << segment.start.y << "), (" <<
segment.end.x << ", " << segment.end.y << ")}";
return out;
}

View File

@ -14,7 +14,12 @@ struct Segment
Segment();
Segment(const glm::vec2&);
Segment(const glm::vec2&, const glm::vec2&);
glm::vec2 get_intersection();
glm::vec2 get_start() const;
void set_start(const glm::vec2&);
glm::vec2 get_end() const;
void set_end(const glm::vec2&);
bool intersect(const Segment&);
bool intersect(const Segment&, glm::vec2&);
float get_dx();
float get_length();
void move(const glm::vec2&);
@ -24,4 +29,6 @@ struct Segment
std::ostream& operator<<(std::ostream&, const Segment&);
#include "extension.hpp"
#endif

View File

@ -53,7 +53,16 @@ void Sprite::load_file(fs::path path)
Game *game = get_root();
const char* previous_scale_quality = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scale_quality.c_str());
SDL_Texture *texture = IMG_LoadTexture(game->renderer, path.string().c_str());
SDL_Texture *base = IMG_LoadTexture(game->renderer, path.string().c_str()), *texture;
if (texture_access == SDL_TEXTUREACCESS_TARGET)
{
texture = sfw::duplicate_texture(get_renderer(), base);
SDL_DestroyTexture(base);
}
else
{
texture = base;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, previous_scale_quality);
if (not texture)
{
@ -109,6 +118,11 @@ Frameset& Sprite::get_current_frameset()
return framesets[current_frameset_name];
}
SDL_Texture* Sprite::get_current_frame()
{
return frames[get_current_frameset().get_current_frame_index()];
}
Box& Sprite::get_box(int index)
{
return boxes[index];
@ -245,6 +259,16 @@ float Sprite::get_left(int index)
return get_box(index).get_left();
}
float Sprite::get_center_x(int index)
{
return get_box(index).get_center_x();
}
float Sprite::get_center_y(int index)
{
return get_box(index).get_center_y();
}
glm::vec2 Sprite::get_nw(int index)
{
return get_box(index).get_nw();
@ -265,11 +289,21 @@ glm::vec2 Sprite::get_east(int index)
return get_box(index).get_east();
}
glm::vec2 Sprite::get_se(int index)
{
return get_box(index).get_se();
}
glm::vec2 Sprite::get_south(int index)
{
return get_box(index).get_south();
}
glm::vec2 Sprite::get_sw(int index)
{
return get_box(index).get_sw();
}
glm::vec2 Sprite::get_west(int index)
{
return get_box(index).get_west();
@ -300,11 +334,31 @@ void Sprite::set_left(float left)
move({left - get_left(), 0}, false);
}
void Sprite::set_center_x(float x)
{
move({x - get_center_x(), 0}, false);
}
void Sprite::set_center_y(float y)
{
move({0, y - get_center_y()}, false);
}
void Sprite::set_se(const glm::vec2& se)
{
move(se - get_se(), false);
}
void Sprite::set_south(const glm::vec2& south)
{
move(south - get_south(), false);
}
void Sprite::set_sw(const glm::vec2& sw)
{
move(sw - get_sw(), false);
}
void Sprite::set_nw(const glm::vec2& nw)
{
move(nw - get_nw(), false);
@ -391,8 +445,7 @@ void Sprite::update()
blink_animation.update();
if (is_loaded() && !is_hidden() && get_current_frameset().get_frame_count())
{
int index = get_current_frameset().get_current_frame_index();
SDL_Texture* texture = frames[index];
SDL_Texture* texture = get_current_frame();
SDL_Renderer* renderer = get_root()->renderer;
SDL_SetTextureAlphaMod(texture, alpha_mod);
SDL_SetRenderTarget(renderer, NULL);

View File

@ -34,6 +34,7 @@ struct Sprite : Node
std::map<std::string, Frameset> framesets;
std::string current_frameset_name;
glm::bvec2 wrap = {false, false};
int texture_access = SDL_TEXTUREACCESS_TARGET;
Box wrap_frame;
Sprite();
@ -47,6 +48,7 @@ struct Sprite : Node
Frameset& add_frameset(std::string);
Frameset& set_frameset(std::string);
Frameset& get_current_frameset();
SDL_Texture* get_current_frame();
Box& get_box(int = 0);
void add_box(glm::vec2, bool = false);
void update_size(bool = false);
@ -70,20 +72,28 @@ struct Sprite : Node
float get_right(int = 0);
float get_bottom(int = 0);
float get_left(int = 0);
float get_center_x(int = 0);
float get_center_y(int = 0);
glm::vec2 get_nw(int = 0);
glm::vec2 get_north(int = 0);
glm::vec2 get_ne(int = 0);
glm::vec2 get_east(int = 0);
glm::vec2 get_se(int = 0);
glm::vec2 get_south(int = 0);
glm::vec2 get_sw(int = 0);
glm::vec2 get_west(int = 0);
glm::vec2 get_center(int = 0);
void set_top(float);
void set_right(float);
void set_bottom(float);
void set_left(float);
void set_center_x(float);
void set_center_y(float);
void set_nw(const glm::vec2&);
void set_ne(const glm::vec2&);
void set_se(const glm::vec2&);
void set_south(const glm::vec2&);
void set_sw(const glm::vec2&);
void set_center(const glm::vec2&);
void add_wrap(bool, bool);
void add_wrap(bool, bool, Box);

View File

@ -1,26 +1,47 @@
#include "extension.hpp"
glm::vec2 sfw::get_step(glm::vec2 start, glm::vec2 end, float speed)
glm::vec2 sfw::get_step(const Segment& segment, float speed)
{
float angle = glm::atan(end.x - start.x, end.y - start.y);
float angle = glm::atan(segment.end.x - segment.start.x, segment.end.y - segment.start.y);
return glm::vec2(speed * glm::sin(angle), speed * glm::cos(angle));
}
glm::vec2 sfw::get_step_relative(const Segment& segment, float relative_length_per_step)
{
return get_step(
segment, glm::distance(segment.start, segment.end) * relative_length_per_step);
}
std::vector<Segment> sfw::get_segments(const Segment& base, int count)
{
glm::vec2 step = get_step_relative(base, 1.0f / count);
std::vector<Segment> segments;
segments.reserve(count);
glm::vec2 start = base.start, end;
for (int ii = 0; ii < count; ii++)
{
end = start + step;
segments.emplace_back(start, end);
start = end;
}
return segments;
}
void sfw::set_magnitude(glm::vec2& vector, float magnitude)
{
vector = glm::normalize(vector) * magnitude;
}
bool sfw::lines_intersect(const Segment& segment_a, const Segment& segment_b)
bool sfw::segments_intersect(const Segment& segment_a, const Segment& segment_b)
{
glm::vec2 intersection;
return lines_intersect(segment_a, segment_b, intersection);
return segments_intersect(segment_a, segment_b, intersection);
}
/*
from http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
*/
bool sfw::lines_intersect(const Segment& segment_a, const Segment& segment_b, glm::vec2& intersection)
// ---
// from http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
// ---
bool sfw::segments_intersect(const Segment& segment_a, const Segment& segment_b, glm::vec2& intersection)
{
float x1 = segment_a.start.x, y1 = segment_a.start.y, x2 = segment_a.end.x,
y2 = segment_a.end.y, x3 = segment_b.start.x, y3 = segment_b.start.y,
@ -82,6 +103,63 @@ Box sfw::get_texture_box(SDL_Texture* texture)
return Box(glm::vec2(0, 0), glm::vec2(w, h));
}
void sfw::populate_pixel_2d_array(SDL_Renderer* renderer, SDL_Texture* texture, std::vector<std::vector<SDL_Color>>& pixels)
{
populate_pixel_2d_array(renderer, texture, pixels, get_texture_box(texture));
}
void sfw::populate_pixel_2d_array(
SDL_Renderer* renderer, SDL_Texture* texture, std::vector<std::vector<SDL_Color>>& pixels, const Box& region)
{
int access;
if (SDL_QueryTexture(texture, NULL, &access, NULL, NULL) < 0)
{
print_sdl_error("Could not query texture for access flag");
}
else
{
if (access != SDL_TEXTUREACCESS_TARGET)
{
texture = duplicate_texture(renderer, texture);
}
if (SDL_SetRenderTarget(renderer, texture) < 0)
{
print_sdl_error("Could not set render target");
}
else
{
Uint32 format = SDL_PIXELFORMAT_RGBA32;
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
int bytes_per_row = bytes_per_pixel * region.get_w();
int bytes_total = bytes_per_row * region.get_h();
Uint8* source = new Uint8[bytes_total];
SDL_Rect int_rect = region.get_int_rect();
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");
}
else
{
pixels.reserve(region.get_w());
for (int x = 0; x < region.get_w(); x++)
{
std::vector<SDL_Color> column;
pixels.push_back(column);
pixels[x].reserve(region.get_h());
}
for (int y = 0, ii = 0; y < region.get_h(); y++)
{
for (int x = 0; x < region.get_w(); x++)
{
pixels[x][y] = {source[ii++], source[ii++], source[ii++], source[ii++]};
}
}
}
delete[] source;
}
}
}
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_SetRenderTarget(renderer, texture);
@ -133,6 +211,8 @@ SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, U
print_sdl_error("could not set render target to duplicate");
return NULL;
}
SDL_SetTextureBlendMode(base, SDL_BLENDMODE_NONE);
SDL_SetTextureBlendMode(duplicate, SDL_BLENDMODE_BLEND);
if ((SDL_RenderCopyF(renderer, base, NULL, NULL)) < 0)
{
print_sdl_error("could not render base onto duplicate");
@ -408,6 +488,7 @@ bool operator==(const SDL_Color& color_1, const SDL_Color& color_2)
std::ostream& operator<<(std::ostream& out, const SDL_Color& color)
{
out << "{" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << "}";
out << "{" << static_cast<int>(color.r) << ", " << static_cast<int>(color.g) << ", " <<
static_cast<int>(color.b) << ", " << static_cast<int>(color.a) << "}";
return out;
}

View File

@ -13,6 +13,7 @@
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_pixels.h"
#define GLM_ENABLE_EXPERIMENTAL
#include "glm/trigonometric.hpp"
@ -25,13 +26,18 @@
namespace sfw
{
enum scaler {scale2x, xbr};
glm::vec2 get_step(glm::vec2, glm::vec2, float);
glm::vec2 get_step(const Segment&, float);
glm::vec2 get_step_relative(const Segment&, float);
std::vector<Segment> get_segments(const Segment&, int);
void set_magnitude(glm::vec2&, float);
bool lines_intersect(const Segment&, const Segment&);
bool lines_intersect(const Segment&, const Segment&, glm::fvec2&);
bool segments_intersect(const Segment&, const Segment&);
bool segments_intersect(const Segment&, const Segment&, glm::fvec2&);
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>>&, const Box&);
void fill_texture(SDL_Renderer*, SDL_Texture*, Uint8, Uint8, Uint8, Uint8 = 0xff);
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);