summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-04-12 17:55:40 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-04-12 17:55:40 +0200
commitd163de65023223c730155959a905e96b7a52a97f (patch)
tree88c51da6276f083b3511838d9cbdc596dba46c7a
parenta089056a95104576ab9832b01c67009f4e040243 (diff)
More useful window
-rw-r--r--window.h71
1 files changed, 67 insertions, 4 deletions
diff --git a/window.h b/window.h
index 3ecfe57..d9ac9d9 100644
--- a/window.h
+++ b/window.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include <array>
#include <functional>
#include <stdexcept>
#include <SDL.h>
@@ -21,7 +22,7 @@ public:
inline Opts() = default;
inline Opts& fullscreen(bool f) { _fullscreen = f; return *this; }
- inline Opts& resizeable(bool r) { _resizable = r; return *this; }
+ inline Opts& resizable(bool r) { _resizable = r; return *this; }
inline bool fullscreen() const { return _fullscreen; }
inline bool resizable() const { return _resizable; }
@@ -40,8 +41,27 @@ public:
inline ~Window();
+ class Buffer {
+ public:
+ using Clr = std::array<uint8_t, 3>;
+
+ inline Buffer(int width, int height, std::vector<uint8_t> &arr);
+
+ inline std::vector<uint8_t>& raw() { return arr; }
+ inline int width() { return wid; }
+ inline int height() { return hei; }
+
+ inline void clear(Clr clr);
+ inline void plot(int x, int y, Clr clr, float alpha = 1.0);
+ inline void plotf(float x, float y, Clr clr, float alpha = 1.0);
+
+ private:
+ int wid, hei;
+ std::vector<uint8_t> &arr;
+ };
+
/// The draw buffer will be of size 3 * width * height; row-major order, RGB pixels.
- using DrawHandler = std::function<void(std::vector<uint8_t> &drawbuf, int width, int height)>;
+ using DrawHandler = std::function<void(Buffer &buffer)>;
/// Return true to stop the event loop.
using EventHandler = std::function<bool(const SDL_Event&)>;
@@ -67,7 +87,7 @@ inline Window::Window(const std::string &title, int wid_sugg, int hei_sugg, Opts
}
Uint32 flags = 0;
- if (opts.fullscreen()) flags |= SDL_WINDOW_FULLSCREEN;
+ if (opts.fullscreen()) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
if (opts.resizable()) flags |= SDL_WINDOW_RESIZABLE;
win = SDL_CreateWindow(
@@ -121,6 +141,49 @@ inline void Window::event_loop(EventHandler eventfunc, DrawHandler drawfunc) {
);
}
- drawfunc(drawbuf, width, height);
+ {
+ Buffer buffer{width, height, drawbuf};
+ drawfunc(buffer);
+ }
+
+ SDL_Surface *winsurf = SDL_GetWindowSurface(win);
+ if (SDL_MUSTLOCK(winsurf)) SDL_LockSurface(winsurf);
+ SDL_BlitSurface(surface, nullptr, winsurf, nullptr);
+ if (SDL_MUSTLOCK(winsurf)) SDL_UnlockSurface(winsurf);
+
+ SDL_UpdateWindowSurface(win);
+ }
+}
+
+inline Window::Buffer::Buffer(int width, int height, std::vector<uint8_t> &arr)
+ : wid{width}, hei{height}, arr{arr}
+{}
+
+inline void Window::Buffer::clear(Clr clr) {
+ if (clr[0] == clr[1] && clr[1] == clr[2]) {
+ memset(arr.data(), clr[0], 3 * wid * hei);
+ } else {
+ for (int i = 0; i < wid * hei; i++) {
+ for (int j = 0; j < 3; j++) {
+ arr[3 * i + j] = clr[j];
+ }
+ }
+ }
+}
+
+inline void Window::Buffer::plot(int x, int y, Clr clr, float alpha) {
+ for (int i = 0; i < 3; i++) {
+ uint8_t &orig = arr[3 * (wid * y + x) + i];
+ orig = alpha * clr[i] + (1 - alpha) * orig;
}
}
+
+inline void Window::Buffer::plotf(float x, float y, Clr clr, float alpha) {
+ const int x0 = x, y0 = y;
+ const float xal = (x - x0) * alpha;
+ const float yal = (y - y0) * alpha;
+ plot(x0 , y0 , clr, (1 - xal) * (1 - yal));
+ plot(x0 + 1, y0 , clr, xal * (1 - yal));
+ plot(x0 , y0 + 1, clr, (1 - xal) * yal );
+ plot(x0 + 1, y0 + 1, clr, xal * yal );
+}