diff --git a/core/image/image.cpp b/core/image/image.cpp new file mode 100644 index 0000000..faa5a4d --- /dev/null +++ b/core/image/image.cpp @@ -0,0 +1,260 @@ +#include "image.h" + +#include + +void Image::create(const Uint32 flags, const int width, const int height) { + if (_surface) { + free(); + } + + //SDL_PIXELFORMAT_RGBA8888 SDL_pixels.h ból + SDL_CreateRGBSurfaceWithFormat(flags, width, height, 32, SDL_PIXELFORMAT_RGBA8888); +} + +void Image::enable_transparent_color(const Color &color) { + if (!SDL_SetColorKey(_surface, 1, color.to_key())) { + printf("enable_transparent_color error.\n"); + } +} + +void Image::disable_transparent_color() { + if (!SDL_SetColorKey(_surface, 0, 0)) { + printf("disable_transparent_color error.\n"); + } +} + +bool Image::has_transparent_color() { + return SDL_HasColorKey(_surface); +} +Color Image::get_transparent_color() { + uint32_t key; + + SDL_GetColorKey(_surface, &key); + + return Color(key); +} + +Color Image::get_color_mod() { + Uint8 r; + Uint8 g; + Uint8 b; + + SDL_GetSurfaceColorMod(_surface, &r, &g, &b); + + return Color(r, g, b); +} +void Image::set_color_mod(const Color &color) { + SDL_SetSurfaceColorMod(_surface, color.r, color.g, color.b); +} + +Color Image::get_alpha_mod() { + Uint8 a; + + SDL_GetSurfaceAlphaMod(_surface, &a); + + return a; +} +void Image::set_alpha_mod(const Uint8 alpha) { + SDL_SetSurfaceAlphaMod(_surface, alpha); +} + +SDL_BlendMode Image::get_blend_mode() { + SDL_BlendMode mode; + + SDL_GetSurfaceBlendMode(_surface, &mode); + + return mode; +} +void Image::set_blend_mode(const SDL_BlendMode mode) { + SDL_SetSurfaceBlendMode(_surface, mode); +} + +Rect2 Image::get_clip_rect() { + SDL_Rect r; + + SDL_GetClipRect(_surface, &r); + + Rect2 rect; + + rect.x = r.x; + rect.y = r.y; + rect.w = r.w; + rect.h = r.h; + + return rect; +} +void Image::set_clip_rect(const Rect2 &rect) { + SDL_Rect r; + + r.x = rect.x; + r.y = rect.y; + r.w = rect.w; + r.h = rect.h; + + SDL_SetClipRect(_surface, &r); +} + +void Image::duplicate(Image *into) { + if (into == nullptr) { + return; + } + + into->_surface = SDL_DuplicateSurface(_surface); +} + +void Image::fill_rect(const Rect2 &rect, const Color &color) { + SDL_Rect r; + + r.x = rect.x; + r.y = rect.y; + r.w = rect.w; + r.h = rect.h; + + SDL_FillRect(_surface, &r, color.to_key()); +} + +void Image::fill_rects(const Vector &rects, const Color &color) { + SDL_Rect *r = new SDL_Rect[rects.size()]; + + for (int i = 0; i < rects.size(); ++i) { + r[i].x = rects[i].x; + r[i].y = rects[i].y; + r[i].w = rects[i].w; + r[i].h = rects[i].h; + } + + SDL_FillRects(_surface, r, rects.size(), color.to_key()); + + delete[] r; +} + +void Image::set_pixel(const int x, const int y, const Color &color) { + if (_surface == nullptr) { + return; + } + + Uint32 *p = reinterpret_cast(_surface->pixels); + + p[x * _surface->w + y] = color.to_key(); +} + +Color Image::get_pixel(const int x, const int y) { + if (_surface == nullptr) { + return Color(); + } + + Uint32 *p = reinterpret_cast(_surface->pixels); + + return Color(p[x * _surface->w + y]); +} + +void Image::blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect) { + SDL_Rect sr; + + sr.x = srcrect.x; + sr.y = srcrect.y; + sr.w = srcrect.w; + sr.h = srcrect.h; + + SDL_Rect dr; + + dr.x = dstrect.x; + dr.y = dstrect.y; + dr.w = dstrect.w; + dr.h = dstrect.h; + + SDL_BlitSurface(source._surface, &sr, _surface, &dr); +} + +void Image::lock() { + SDL_LockSurface(_surface); +} +void Image::unlock() { + SDL_UnlockSurface(_surface); +} + +void Image::free() { + SDL_FreeSurface(_surface); + + _surface = nullptr; +} + +void Image::load_bmp(const String &file_name) { + if (_surface != nullptr) { + free(); + } + + _surface = SDL_LoadBMP(file_name.c_str()); + + if (_surface != nullptr && _surface->format->format != SDL_PIXELFORMAT_RGBA8888) { + //Nem ARGB8888 as formátum, konvertáljuk át + SDL_Surface *n = SDL_ConvertSurfaceFormat(_surface, SDL_PIXELFORMAT_RGBA8888, 0); + + free(); + + _surface = n; + } +} + +void Image::save_bmp(const String &file_name) { + SDL_SaveBMP(_surface, file_name.c_str()); +} + +Uint32 Image::get_width() const { + if (_surface == nullptr) { + return 0; + } + + return _surface->w; +} +Uint32 Image::get_height() const { + if (_surface == nullptr) { + return 0; + } + + return _surface->h; +} + +SDL_Surface *Image::get_surface() { + return _surface; +} + +void Image::set_surface(SDL_Surface *surface) { + _surface = surface; + + if (_surface != nullptr && _surface->format->format != SDL_PIXELFORMAT_RGBA8888) { + //Nem ARGB8888 as formátum, konvertáljuk át + SDL_Surface *n = SDL_ConvertSurfaceFormat(_surface, SDL_PIXELFORMAT_RGBA8888, 0); + + free(); + + _surface = n; + } +} + +Image::Image() { + _surface = nullptr; +} + +Image::Image(const String &file_name) { + _surface = nullptr; + + load_bmp(file_name); +} + +Image::Image(SDL_Surface *surface) { + _surface = surface; + + if (_surface != nullptr && _surface->format->format != SDL_PIXELFORMAT_RGBA8888) { + //Nem ARGB8888 as formátum, konvertáljuk át + SDL_Surface *n = SDL_ConvertSurfaceFormat(_surface, SDL_PIXELFORMAT_RGBA8888, 0); + + free(); + + _surface = n; + } +} + +Image::~Image() { + free(); +} \ No newline at end of file diff --git a/core/image/image.h b/core/image/image.h new file mode 100644 index 0000000..5b2c782 --- /dev/null +++ b/core/image/image.h @@ -0,0 +1,63 @@ +#ifndef IMAGE_H +#define IMAGE_H + +#include "core/color.h" +#include "core/rect2.h" +#include "core/string.h" +#include "core/vector.h" +#include + +class Image { +public: + void create(const Uint32 flags, const int width, const int height); + + void enable_transparent_color(const Color &color); + void disable_transparent_color(); + bool has_transparent_color(); + Color get_transparent_color(); + + Color get_color_mod(); + void set_color_mod(const Color &color); + + Color get_alpha_mod(); + void set_alpha_mod(const Uint8 alpha); + + SDL_BlendMode get_blend_mode(); + void set_blend_mode(const SDL_BlendMode mode); + + Rect2 get_clip_rect(); + void set_clip_rect(const Rect2 &rect); + + void duplicate(Image *into); + + void fill_rect(const Rect2 &rect, const Color &color); + void fill_rects(const Vector &rects, const Color &color); + void set_pixel(const int x, const int y, const Color &color); + Color get_pixel(const int x, const int y); + + void blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect); + + void lock(); + void unlock(); + + void free(); + + void load_bmp(const String &file_name); + void save_bmp(const String &file_name); + + Uint32 get_width() const; + Uint32 get_height() const; + + SDL_Surface *get_surface(); + void set_surface(SDL_Surface *surface); + + Image(); + Image(const String &file_name); + Image(SDL_Surface *surface); + virtual ~Image(); + +private: + SDL_Surface *_surface; +}; + +#endif \ No newline at end of file diff --git a/core/image/sprite.cpp b/core/image/sprite.cpp new file mode 100644 index 0000000..38d57f5 --- /dev/null +++ b/core/image/sprite.cpp @@ -0,0 +1,238 @@ +#include "sprite.h" + +#include "renderer.h" + +Rect2 Sprite::get_texture_clip_rect() const { + return _texture_clip_rect; +} +void Sprite::set_texture_clip_rect(const Rect2 &rect) { + _texture_clip_rect = rect; +} + +Rect2 Sprite::get_transform() const { + return _transform; +} +void Sprite::set_transform(const Rect2 &rect) { + _transform = rect; +} + +float Sprite::get_x() const { + return _transform.x; +} +void Sprite::set_x(const float val) { + _transform.x = val; +} + +float Sprite::get_y() const { + return _transform.y; +} +void Sprite::set_y(const float val) { + _transform.y = val; +} + +float Sprite::get_w() const { + return _transform.w; +} +void Sprite::set_w(const float val) { + _transform.w = val; +} + +float Sprite::get_h() const { + return _transform.h; +} +void Sprite::set_h(const float val) { + _transform.h = val; +} + +double Sprite::get_angle() const { + return _angle; +} +void Sprite::set_angle(const double val) { + _angle = val; +} + +float Sprite::get_anchor_x() const { + return _anchor_x; +} +void Sprite::set_anchor_x(const float val) { + _anchor_x = val; +} + +float Sprite::get_anchor_y() const { + return _anchor_y; +} +void Sprite::set_anchor_y(const float val) { + _anchor_y = val; +} + +void Sprite::set_anchor(const float x, const float y) { + _anchor_x = x; + _anchor_y = y; +} + +SDL_RendererFlip Sprite::get_flip() const { + return _flip; +} +void Sprite::set_flip(const SDL_RendererFlip val) { + _flip = val; +} + +Color Sprite::get_color_mod() const { + return _color_mod; +} +void Sprite::set_color_mod(const Color &color) { + _color_mod = color; +} + +Texture *Sprite::get_texture() { + return _texture; +} +Texture *Sprite::get_texture() const { + return _texture; +} +void Sprite::set_texture(Texture *texture) { + _texture = texture; +} + +void Sprite::draw() { + Renderer::get_singleton()->draw_sprite(this); +} + +Sprite::Sprite() { + _angle = 0; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = nullptr; + + _color_mod = Color(255, 255, 255, 255); +} +Sprite::Sprite(Texture *texture) { + _angle = 0; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + if (_texture != nullptr) { + _texture_clip_rect.w = texture->get_width(); + _texture_clip_rect.h = texture->get_height(); + + _transform.w = texture->get_width(); + _transform.h = texture->get_height(); + } + + _color_mod = Color(255, 255, 255, 255); +} + +Sprite::Sprite(Texture *texture, const Color &color_mod) { + _angle = 0; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + if (_texture != nullptr) { + _texture_clip_rect.w = texture->get_width(); + _texture_clip_rect.h = texture->get_height(); + + _transform.w = texture->get_width(); + _transform.h = texture->get_height(); + } + + _color_mod = color_mod; +} + +Sprite::Sprite(Texture *texture, const float x, const float y, const double angle) { + _angle = angle; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + _transform.x = x; + _transform.y = y; + + if (_texture != nullptr) { + _texture_clip_rect.w = texture->get_width(); + _texture_clip_rect.h = texture->get_height(); + + _transform.w = texture->get_width(); + _transform.h = texture->get_height(); + } + + _color_mod = Color(255, 255, 255, 255); +} +Sprite::Sprite(Texture *texture, const float x, const float y, const Rect2 &texture_clip_rect, const double angle) { + _angle = angle; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + _transform.x = x; + _transform.y = y; + + if (_texture != nullptr) { + _transform.w = texture->get_width(); + _transform.h = texture->get_height(); + } + + _texture_clip_rect = texture_clip_rect; + + _color_mod = Color(255, 255, 255, 255); +} +Sprite::Sprite(Texture *texture, const Rect2 &transform, const Rect2 &texture_clip_rect, const double angle) { + _angle = angle; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + _transform = transform; + _texture_clip_rect = texture_clip_rect; + + _color_mod = Color(255, 255, 255, 255); +} +Sprite::Sprite(Texture *texture, const float x, const float y, const float w, const float h, const double angle) { + _angle = angle; + + _anchor_x = 0; + _anchor_y = 0; + + _flip = SDL_FLIP_NONE; + + _texture = texture; + + _transform.x = x; + _transform.y = y; + _transform.w = w; + _transform.h = h; + + if (_texture != nullptr) { + _texture_clip_rect.w = texture->get_width(); + _texture_clip_rect.h = texture->get_height(); + } + + _color_mod = Color(255, 255, 255, 255); +} +Sprite::~Sprite() { +} \ No newline at end of file diff --git a/core/image/sprite.h b/core/image/sprite.h new file mode 100644 index 0000000..2b4e153 --- /dev/null +++ b/core/image/sprite.h @@ -0,0 +1,77 @@ +#ifndef SPRITE_H +#define SPRITE_H + +#include + +#include "core/rect2.h" +#include "texture.h" +#include "core/color.h" + +class Sprite { +public: + Rect2 get_texture_clip_rect() const; + void set_texture_clip_rect(const Rect2 &rect); + + Rect2 get_transform() const; + void set_transform(const Rect2 &rect); + + float get_x() const; + void set_x(const float val); + + float get_y() const; + void set_y(const float val); + + float get_w() const; + void set_w(const float val); + + float get_h() const; + void set_h(const float val); + + double get_angle() const; + void set_angle(const double val); + + float get_anchor_x() const; + void set_anchor_x(const float val); + + float get_anchor_y() const; + void set_anchor_y(const float val); + + void set_anchor(const float x, const float y); + + SDL_RendererFlip get_flip() const; + void set_flip(const SDL_RendererFlip val); + + Color get_color_mod() const; + void set_color_mod(const Color &color); + + Texture *get_texture(); + Texture *get_texture() const; + void set_texture(Texture *texture); + + void draw(); + + Sprite(); + Sprite(Texture *texture); + Sprite(Texture *texture, const Color &color_mod); + Sprite(Texture *texture, const float x, const float y, const double angle = 0); + Sprite(Texture *texture, const float x, const float y, const Rect2 &texture_clip_rect, const double angle = 0); + Sprite(Texture *texture, const Rect2 &transform, const Rect2 &texture_clip_rect, const double angle = 0); + Sprite(Texture *texture, const float x, const float y, const float w, const float h, const double angle = 0); + virtual ~Sprite(); + +private: + Rect2 _texture_clip_rect; + Rect2 _transform; + double _angle; + + float _anchor_x; + float _anchor_y; + + SDL_RendererFlip _flip; + + Color _color_mod; + + Texture *_texture; +}; + +#endif \ No newline at end of file diff --git a/core/image/texture.cpp b/core/image/texture.cpp new file mode 100644 index 0000000..c2203dc --- /dev/null +++ b/core/image/texture.cpp @@ -0,0 +1,166 @@ +#include "texture.h" + +#include "renderer.h" + +Color Texture::get_color_mod() const { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; + + SDL_GetTextureColorMod(_texture, &r, &g, &b); + SDL_GetTextureAlphaMod(_texture, &a); + + return Color(r, g, b, a); +} +void Texture::set_color_mod(const Color &color) { + SDL_SetTextureColorMod(_texture, color.r, color.g, color.b); + SDL_SetTextureAlphaMod(_texture, color.a); +} + +SDL_BlendMode Texture::get_blend_mode() const { + SDL_BlendMode blendMode; + + SDL_GetTextureBlendMode(_texture, &blendMode); + + return blendMode; +} +void Texture::set_blend_mode(const SDL_BlendMode blend_mode) { + SDL_SetTextureBlendMode(_texture, blend_mode); +} + +SDL_ScaleMode Texture::get_texture_scale_mode() const { + SDL_ScaleMode scale_mode; + + SDL_GetTextureScaleMode(_texture, &scale_mode); + + return scale_mode; +} +void Texture::set_texture_scale_mode(const SDL_ScaleMode scale_mode) { + SDL_SetTextureScaleMode(_texture, scale_mode); +} + +Image *Texture::get_image() { + return _image; +} +void Texture::set_image(Image *image) { + if (_texture) { + free(); + } + + _image = image; + + refresh(); +} + +int Texture::get_width() const { + Uint32 format; + int access; + int w; + int h; + + if (SDL_QueryTexture(_texture, &format, &access, &w, &h)) { + return 0; + } + + return w; +} +int Texture::get_height() const { + Uint32 format; + int access; + int w; + int h; + + if (SDL_QueryTexture(_texture, &format, &access, &w, &h)) { + return 0; + } + + return h; +} +Uint32 Texture::get_format() const { + Uint32 format; + int access; + int w; + int h; + + if (SDL_QueryTexture(_texture, &format, &access, &w, &h)) { + return 0; + } + + return format; +} +int Texture::get_access() const { + Uint32 format; + int access; + int w; + int h; + + if (SDL_QueryTexture(_texture, &format, &access, &w, &h)) { + return 0; + } + + return access; +} + +void Texture::create(int access, int w, int h) { + if (_texture) { + free(); + } + + _image = nullptr; + + _texture = SDL_CreateTexture(Renderer::get_singleton()->get_renderer(), SDL_PIXELFORMAT_RGBA8888, access, w, h); +} +void Texture::refresh() { + if (_image == nullptr) { + return; + } + + if (_image->get_surface() == nullptr) { + return; + } + + if (_texture) { + free(); + } + + _texture = SDL_CreateTextureFromSurface(Renderer::get_singleton()->get_renderer(), _image->get_surface()); +} +void Texture::free() { + if (_texture) { + SDL_DestroyTexture(_texture); + + _texture = nullptr; + } +} + +SDL_Texture *Texture::get_texture() { + return _texture; +} +SDL_Texture *Texture::get_texture() const { + return _texture; +} + +bool Texture::is_render_target() { + if (_texture == Renderer::get_singleton()->get_render_target()) { + return true; + } + + return false; +} + +Texture::Texture() { + _image = nullptr; + _texture = nullptr; +} +Texture::Texture(Image *image) { + _image = nullptr; + _texture = nullptr; + + set_image(image); +} +Texture::~Texture() { + if (_texture) { + free(); + } +} \ No newline at end of file diff --git a/core/image/texture.h b/core/image/texture.h new file mode 100644 index 0000000..1f94253 --- /dev/null +++ b/core/image/texture.h @@ -0,0 +1,44 @@ +#ifndef TEXTURE_H +#define TEXTURE_H + +#include "image.h" +#include + +class Texture { +public: + Color get_color_mod() const; + void set_color_mod(const Color &color); + + SDL_BlendMode get_blend_mode() const; + void set_blend_mode(const SDL_BlendMode blend_mode); + + SDL_ScaleMode get_texture_scale_mode() const; + void set_texture_scale_mode(const SDL_ScaleMode scale_mode); + + Image *get_image(); + void set_image(Image *image); + + int get_width() const; + int get_height() const; + Uint32 get_format() const; + int get_access() const; + + void create(const int access, const int w, const int h); + void refresh(); + void free(); + + SDL_Texture *get_texture(); + SDL_Texture *get_texture() const; + + bool is_render_target(); + + Texture(); + Texture(Image *image); + virtual ~Texture(); + +private: + Image *_image; + SDL_Texture *_texture; +}; + +#endif \ No newline at end of file