summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-07-16 05:04:18 +0200
committerkdx <kikoodx@paranoici.org>2023-07-16 05:04:18 +0200
commitd76287cd9c0db1176c59740b5d1e17b168746bef (patch)
treee16f15587cc8a6842f5a95bd51c03e50f6ecbdc8
parent05a19a8c893bc7f2c951dd81ba3f94678c458a2c (diff)
downloadfld-d76287cd9c0db1176c59740b5d1e17b168746bef.tar.gz
draw image
-rw-r--r--demo.cpp4
-rw-r--r--src/FLD.hpp11
-rw-r--r--src/drawImage.cpp10
-rw-r--r--src/image.cpp13
-rw-r--r--src/imageDraw.cpp66
-rw-r--r--src/imageSetScaleMode.cpp11
6 files changed, 93 insertions, 22 deletions
diff --git a/demo.cpp b/demo.cpp
index f335402..7e31b34 100644
--- a/demo.cpp
+++ b/demo.cpp
@@ -13,10 +13,10 @@ main_loop(FLD& fld, [[maybe_unused]] void *udata)
fld.drawRectangle({ 16, 32, 64, 32 });
fld.image("res/smile.bmp").draw({
- .p = {},
+ .p = { 128, 128 },
.sx = 1.5f,
.sy = 0.5f,
- .f = FLD::FLIP_X | FLD::FLIP_Y,
+ .f = FLD::FLIP_X | FLD::FLIP_Y | FLD::CENTER,
});
if (fld.drawEnd())
diff --git a/src/FLD.hpp b/src/FLD.hpp
index d4bf4bf..329cc72 100644
--- a/src/FLD.hpp
+++ b/src/FLD.hpp
@@ -3,6 +3,7 @@
#include <string>
#include <map>
#include <optional>
+#include <climits>
#define READONLY(T, X, V) private: T _##X = V; public: decltype(_##X) const& X = _##X
@@ -40,22 +41,24 @@ public:
const Point& p;
int ix = 0;
int iy = 0;
- int w = -1;
- int h = -1;
+ int w = INT_MIN;
+ int h = INT_MIN;
float r = 0.0f;
float sx = 1.0f;
float sy = 1.0f;
Uint f = NONE;
};
struct Image {
+ FLD *fld = nullptr;
std::string path = "";
bool valid = true;
SDL_Texture *ptr = nullptr;
int width = 0;
int height = 0;
- Error invalid() const;
+ [[nodiscard]] Error invalid() const;
Error draw(const DrawImageOpts& opts) const;
+ Error setScaleMode(SDL_ScaleMode scale_mode) const;
};
enum DrawFlag {
NONE = 0,
@@ -97,7 +100,7 @@ public:
Error drawLine(const Point& p0, const Point& p1) const;
Error drawRectangle(const Rectangle& rect, Uint flags=NONE) const;
- Image& image(const std::string& path);
+ [[nodiscard]] Image& image(const std::string& path);
private:
bool shouldQuit = false;
struct {
diff --git a/src/drawImage.cpp b/src/drawImage.cpp
deleted file mode 100644
index a7f8867..0000000
--- a/src/drawImage.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "FLD.hpp"
-
-FLD::Error
-FLD::Image::draw(const DrawImageOpts &opts) const
-{
- if (invalid())
- return -1;
-
- return 0;
-}
diff --git a/src/image.cpp b/src/image.cpp
index 177968a..5adaf6a 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -1,9 +1,9 @@
#include "FLD.hpp"
static FLD::Image&
-invalid_image()
+invalid_image(FLD *fld)
{
- static FLD::Image image = { .valid = false };
+ static FLD::Image image = { .fld = fld, .valid = false };
return image;
}
@@ -16,30 +16,31 @@ FLD::image(const std::string &path)
const auto surf = SDL_LoadBMP(path.c_str());
if (surf == nullptr) {
sdlError(path);
- return invalid_image();
+ return invalid_image(this);
}
const auto tex = SDL_CreateTextureFromSurface(_renderer, surf);
SDL_FreeSurface(surf);
if (tex == nullptr) {
sdlError(path);
- return invalid_image();
+ return invalid_image(this);
}
if (SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND) < 0) {
SDL_DestroyTexture(tex);
sdlError(path);
- return invalid_image();
+ return invalid_image(this);
}
int width, height;
if (SDL_QueryTexture(tex, nullptr, nullptr, &width, &height) < 0) {
SDL_DestroyTexture(tex);
sdlError(path);
- return invalid_image();
+ return invalid_image(this);
}
images[path] = {
+ .fld = this,
.path = path,
.ptr = tex,
.width = width,
diff --git a/src/imageDraw.cpp b/src/imageDraw.cpp
new file mode 100644
index 0000000..cd40c4a
--- /dev/null
+++ b/src/imageDraw.cpp
@@ -0,0 +1,66 @@
+#include "FLD.hpp"
+
+FLD::Error
+FLD::Image::draw(const DrawImageOpts &opts) const
+{
+ if (invalid())
+ return -1;
+
+ const bool center = opts.f & CENTER;
+ const bool flip_x = opts.f & FLIP_X;
+ const bool flip_y = opts.f & FLIP_Y;
+
+ const Uint8 r = fld->drawColor.r * 0xff;
+ const Uint8 g = fld->drawColor.g * 0xff;
+ const Uint8 b = fld->drawColor.b * 0xff;
+ const Uint8 a = fld->drawColor.a * 0xff;
+ if (SDL_SetTextureColorMod(ptr, r, g, b) < 0)
+ return fld->sdlError();
+ if (SDL_SetTextureAlphaMod(ptr, a) < 0)
+ return fld->sdlError();
+
+ auto scale_x = opts.sx;
+ auto simg_width = (opts.w == INT_MIN) ? width : opts.w;
+ if (simg_width < 0) {
+ simg_width *= -1;
+ scale_x *= -1;
+ }
+ if (simg_width + opts.ix > width)
+ simg_width = width - opts.ix;
+
+ auto scale_y = opts.sy;
+ auto simg_height = (opts.h == INT_MIN) ? height : opts.h;
+ if (simg_height < 0) {
+ simg_height *= -1;
+ scale_y *= -1;
+ }
+ if (simg_height + opts.iy > height)
+ simg_height = height - opts.iy;
+
+ int flip = 0;
+ flip |= SDL_FLIP_HORIZONTAL * ((scale_x < 0) ^ flip_x);
+ flip |= SDL_FLIP_VERTICAL * ((scale_y < 0) ^ flip_y);
+
+ const int w = simg_width * fabs(scale_x);
+ const int h = simg_height * fabs(scale_y);
+ const int x = opts.p.x - ((scale_x < 0) ? w : 0);
+ const int y = opts.p.y - ((scale_y < 0) ? h : 0);
+
+ const SDL_Rect src {
+ .x = opts.ix,
+ .y = opts.iy,
+ .w = simg_width,
+ .h = simg_height
+ };
+ const SDL_Rect dst {
+ .x = x - (center ? (int)(simg_width * scale_x / 2) : 0),
+ .y = y - (center ? (int)(simg_height * scale_y / 2) : 0),
+ .w = w,
+ .h = h
+ };
+
+ if (SDL_RenderCopyEx(fld->renderer, ptr, &src, &dst, opts.r * 360,
+ nullptr, static_cast<SDL_RendererFlip>(flip)) < 0)
+ return fld->sdlError();
+ return 0;
+}
diff --git a/src/imageSetScaleMode.cpp b/src/imageSetScaleMode.cpp
new file mode 100644
index 0000000..5b04c5f
--- /dev/null
+++ b/src/imageSetScaleMode.cpp
@@ -0,0 +1,11 @@
+#include "FLD.hpp"
+
+FLD::Error
+FLD::Image::setScaleMode(SDL_ScaleMode scale_mode) const
+{
+ if (invalid())
+ return -1;
+ if (SDL_SetTextureScaleMode(ptr, scale_mode) < 0)
+ return fld->sdlError();
+ return 0;
+}