box crop and fits; Pixel class support for reading screen pixels
This commit is contained in:
parent
013f8279d4
commit
72a36a1d57
71
src/Box.cpp
71
src/Box.cpp
|
@ -10,6 +10,8 @@ Box::Box(const glm::vec2& nw, const glm::vec2& size)
|
|||
h = size.y;
|
||||
}
|
||||
|
||||
Box::Box(const SDL_Rect& rect) : Box({rect.x, rect.y}, {rect.w, rect.h}) {}
|
||||
|
||||
float Box::get_x() const
|
||||
{
|
||||
return x;
|
||||
|
@ -101,11 +103,25 @@ float Box::get_center_y() const
|
|||
return get_top() + get_h() / 2;
|
||||
}
|
||||
|
||||
void Box::set_top(float top)
|
||||
void Box::set_top(float top, bool drag)
|
||||
{
|
||||
set_y(top);
|
||||
if (!drag)
|
||||
{
|
||||
set_y(top);
|
||||
}
|
||||
else
|
||||
{
|
||||
drag_top(top - get_top());
|
||||
}
|
||||
}
|
||||
|
||||
void Box::drag_top(float delta)
|
||||
{
|
||||
float previous_top = get_top();
|
||||
set_top(get_top() + delta);
|
||||
set_h(get_h() + previous_top - get_top());
|
||||
}
|
||||
|
||||
void Box::set_right(float right, bool drag)
|
||||
{
|
||||
float delta = right - get_right();
|
||||
|
@ -127,9 +143,25 @@ void Box::drag_right(float delta)
|
|||
set_right(new_right);
|
||||
}
|
||||
|
||||
void Box::set_bottom(float bottom)
|
||||
void Box::set_bottom(float bottom, bool drag)
|
||||
{
|
||||
move({0, bottom - get_bottom()});
|
||||
float delta = bottom - get_bottom();
|
||||
if (!drag)
|
||||
{
|
||||
move({0, delta});
|
||||
}
|
||||
else
|
||||
{
|
||||
drag_bottom(delta);
|
||||
}
|
||||
}
|
||||
|
||||
void Box::drag_bottom(float delta)
|
||||
{
|
||||
float previous_bottom = get_bottom();
|
||||
float new_bottom = get_bottom() + delta;
|
||||
set_h(get_h() + new_bottom - previous_bottom);
|
||||
set_bottom(new_bottom);
|
||||
}
|
||||
|
||||
void Box::set_left(float left, bool drag)
|
||||
|
@ -236,6 +268,11 @@ void Box::set_south(const glm::vec2& s)
|
|||
move(s - get_south());
|
||||
}
|
||||
|
||||
void Box::set_sw(const glm::vec2& sw)
|
||||
{
|
||||
move(sw - get_sw());
|
||||
}
|
||||
|
||||
void Box::set_west(const glm::vec2& w)
|
||||
{
|
||||
move(w - get_west());
|
||||
|
@ -300,6 +337,32 @@ Box Box::stamp(const glm::vec2& delta) const
|
|||
return clone;
|
||||
}
|
||||
|
||||
bool Box::fits(const Box& container) const
|
||||
{
|
||||
return !(get_top() < container.get_top() || get_right() > container.get_right() ||
|
||||
get_bottom() > container.get_bottom() || get_left() < container.get_left());
|
||||
}
|
||||
|
||||
void Box::crop(const Box& area)
|
||||
{
|
||||
if (get_top() < area.get_top())
|
||||
{
|
||||
set_top(area.get_top(), true);
|
||||
}
|
||||
if (get_right() > area.get_right())
|
||||
{
|
||||
set_right(area.get_right(), true);
|
||||
}
|
||||
if (get_bottom() > area.get_bottom())
|
||||
{
|
||||
set_bottom(area.get_bottom(), true);
|
||||
}
|
||||
if (get_left() < area.get_left())
|
||||
{
|
||||
set_left(area.get_left(), true);
|
||||
}
|
||||
}
|
||||
|
||||
bool Box::collide(const glm::vec2& point) const
|
||||
{
|
||||
return point.x >= get_left() && point.x <= get_right() && point.y >= get_top() && point.y <= get_bottom();
|
||||
|
|
10
src/Box.hpp
10
src/Box.hpp
|
@ -16,6 +16,7 @@ struct Box : SDL_FRect
|
|||
{
|
||||
|
||||
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0});
|
||||
Box(const SDL_Rect&);
|
||||
float get_x() const;
|
||||
float get_y() const;
|
||||
float get_w() const;
|
||||
|
@ -33,10 +34,12 @@ struct Box : SDL_FRect
|
|||
float get_left() const;
|
||||
float get_center_x() const;
|
||||
float get_center_y() const;
|
||||
void set_top(float);
|
||||
void set_top(float, bool=false);
|
||||
void drag_top(float);
|
||||
void set_right(float, bool=false);
|
||||
void drag_right(float);
|
||||
void set_bottom(float);
|
||||
void set_bottom(float, bool=false);
|
||||
void drag_bottom(float);
|
||||
void set_left(float, bool=false);
|
||||
void drag_left(float);
|
||||
void set_center_x(float);
|
||||
|
@ -56,6 +59,7 @@ struct Box : SDL_FRect
|
|||
void set_east(const glm::vec2&);
|
||||
void set_se(const glm::vec2&);
|
||||
void set_south(const glm::vec2&);
|
||||
void set_sw(const glm::vec2&);
|
||||
void set_west(const glm::vec2&);
|
||||
void set_center(const glm::vec2&);
|
||||
operator SDL_Rect() const;
|
||||
|
@ -66,6 +70,8 @@ struct Box : SDL_FRect
|
|||
void expand(float, bool = false);
|
||||
void move(const glm::vec2&);
|
||||
Box stamp(const glm::vec2&) const;
|
||||
bool fits(const Box&) const;
|
||||
void crop(const Box&);
|
||||
bool collide(const glm::vec2&) const;
|
||||
bool collide(const Segment&, glm::vec2* = nullptr) const;
|
||||
bool collide(const Segment&, glm::vec2&) const;
|
||||
|
|
|
@ -92,6 +92,9 @@ Game::Game()
|
|||
}
|
||||
else
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetRendererOutputSize(renderer, &w, &h);
|
||||
SDL_Log("renderer output size is (%i, %i)", w, h);
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
|
|
@ -1,18 +1,49 @@
|
|||
#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)
|
||||
Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture, const Box& box) :
|
||||
texture(texture), renderer(renderer)
|
||||
{
|
||||
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)
|
||||
if (texture == nullptr)
|
||||
{
|
||||
bool is_duplicate;
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_DisplayMode display_mode;
|
||||
if (SDL_GetCurrentDisplayMode(0, &display_mode) < 0)
|
||||
{
|
||||
sfw::print_sdl_error("could not get current display mode");
|
||||
}
|
||||
if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0)
|
||||
{
|
||||
sfw::print_sdl_error("could not get renderer output size");
|
||||
}
|
||||
format_enum = display_mode.format;
|
||||
texture_access = TEXTURE_ACCESS_SCREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_QueryTexture(texture, &format_enum, &texture_access, &w, &h);
|
||||
}
|
||||
format = SDL_AllocFormat(format_enum);
|
||||
if (box.fits({{0, 0}, {w, h}}))
|
||||
{
|
||||
rect = box;
|
||||
}
|
||||
else
|
||||
{
|
||||
Box cropped = box;
|
||||
cropped.crop({{0, 0}, {w, h}});
|
||||
rect = cropped;
|
||||
}
|
||||
if (texture == nullptr || texture_access == SDL_TEXTUREACCESS_STATIC || texture_access == SDL_TEXTUREACCESS_TARGET)
|
||||
{
|
||||
bool is_duplicate = false;
|
||||
SDL_Texture* base;
|
||||
if (texture_access == SDL_TEXTUREACCESS_STATIC)
|
||||
if (texture == nullptr)
|
||||
{
|
||||
base = nullptr;
|
||||
}
|
||||
else if (texture_access == SDL_TEXTUREACCESS_STATIC)
|
||||
{
|
||||
base = sfw::duplicate_texture(renderer, texture);
|
||||
is_duplicate = true;
|
||||
|
@ -20,7 +51,6 @@ Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect& rec
|
|||
else
|
||||
{
|
||||
base = texture;
|
||||
is_duplicate = false;
|
||||
}
|
||||
SDL_SetRenderTarget(renderer, base);
|
||||
int bytes_total = get_bytes_per_row() * rect.h;
|
||||
|
@ -53,6 +83,8 @@ Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect& rec
|
|||
}
|
||||
}
|
||||
|
||||
Pixels::Pixels(SDL_Renderer* renderer, SDL_Texture* texture) : Pixels(renderer, texture, sfw::get_texture_box(texture)) {}
|
||||
|
||||
int Pixels::get_bytes_per_row() const
|
||||
{
|
||||
return format->BytesPerPixel * rect.w;
|
||||
|
@ -85,7 +117,19 @@ void Pixels::set(const SDL_Color& color, int x, int y)
|
|||
|
||||
void Pixels::apply()
|
||||
{
|
||||
if (texture_access == SDL_TEXTUREACCESS_STATIC || texture_access == SDL_TEXTUREACCESS_TARGET)
|
||||
if (texture_access == TEXTURE_ACCESS_SCREEN)
|
||||
{
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
for (int x = rect.x; x < rect.x + rect.w; x++)
|
||||
{
|
||||
for (int y = rect.y; y < rect.y + rect.h; y++)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer, get(x, y));
|
||||
SDL_RenderDrawPoint(renderer, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (texture_access == SDL_TEXTUREACCESS_STATIC || texture_access == SDL_TEXTUREACCESS_TARGET)
|
||||
{
|
||||
SDL_UpdateTexture(texture, &rect, source, get_bytes_per_row());
|
||||
}
|
||||
|
|
|
@ -11,17 +11,20 @@ struct Sprite;
|
|||
struct Pixels
|
||||
{
|
||||
|
||||
const int TEXTURE_ACCESS_SCREEN = 128;
|
||||
void* source = nullptr;
|
||||
SDL_PixelFormat* format = nullptr;
|
||||
SDL_Texture* texture;
|
||||
SDL_Renderer* renderer;
|
||||
int texture_access = 0;
|
||||
SDL_Rect rect;
|
||||
bool allocated = false;
|
||||
|
||||
Pixels(SDL_Renderer*, SDL_Texture* texture, const Box&);
|
||||
Pixels(SDL_Renderer*, SDL_Texture* texture);
|
||||
Pixels(SDL_Renderer*, SDL_Texture* texture, const SDL_Rect&);
|
||||
Pixels(SDL_Renderer*);
|
||||
Pixels(Sprite&);
|
||||
Pixels(Sprite&, const SDL_Rect&);
|
||||
Pixels(Sprite&, const Box&);
|
||||
int get_bytes_per_row() const;
|
||||
Color get(int x, int y);
|
||||
void set(const SDL_Color&, int x, int y);
|
||||
|
|
|
@ -1060,6 +1060,6 @@ void Frameset::reverse()
|
|||
}
|
||||
|
||||
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) {}
|
||||
Pixels::Pixels(Sprite& sprite, const Box& box) : Pixels(sprite.get_renderer(), sprite.get_current_frame(), box) {}
|
||||
|
||||
Segment::Segment(const Sprite& start, const Sprite& end) : Segment(start.get_center(), end.get_center()) {}
|
||||
|
|
Loading…
Reference in New Issue