diff options
author | Tom Smeding <tom.smeding@gmail.com> | 2020-04-12 17:55:40 +0200 |
---|---|---|
committer | Tom Smeding <tom.smeding@gmail.com> | 2020-04-12 17:55:40 +0200 |
commit | d163de65023223c730155959a905e96b7a52a97f (patch) | |
tree | 88c51da6276f083b3511838d9cbdc596dba46c7a /window.h | |
parent | a089056a95104576ab9832b01c67009f4e040243 (diff) |
More useful window
Diffstat (limited to 'window.h')
-rw-r--r-- | window.h | 71 |
1 files changed, 67 insertions, 4 deletions
@@ -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 ); +} |