nngn
Loading...
Searching...
No Matches
frame_buffer.h
Go to the documentation of this file.
1#ifndef NNGN_GRAPHICS_TERMINAL_FRAME_BUFFER_H
2#define NNGN_GRAPHICS_TERMINAL_FRAME_BUFFER_H
3
4#include "graphics/graphics.h"
5#include "os/os.h"
6#include "utils/ranges.h"
7
8#include "texture.h"
9
10namespace nngn::term {
11
13public:
19 uvec2 size(void) const { return this->m_size; }
21 std::span<char> span(void) { return this->v; }
22 std::span<char> prefix(void);
23 std::span<char> pixels(void);
24 std::span<char> suffix(void);
28 void write_ascii(std::size_t x, std::size_t y, Texture::texel4 color);
30 void write_colored(std::size_t x, std::size_t y, Texture::texel4 color);
32 void flip(void);
37 std::size_t dedup(void);
38private:
39 struct ColoredPixel {
41 ColoredPixel(void) = default;
43 explicit ColoredPixel(Texture::texel3 color);
45 static bool cmp_rgb(const ColoredPixel &lhs, const ColoredPixel &rhs);
46 static constexpr auto CMD = ANSIEscapeCode::bg_color_24bit;
47 std::array<char, CMD.size()> cmd = nngn::to_array<CMD.size()>(CMD);
48 std::array<char, 3> r = nngn::to_array("000");
49 char semicolon0 = ';';
50 std::array<char, 3> g = nngn::to_array("000");
51 char semicolon1 = ';';
52 std::array<char, 3> b = nngn::to_array("000");
53 char m = 'm', space = ' ';
54 };
55 static_assert(std::has_unique_object_representations_v<ColoredPixel>);
56 static constexpr std::size_t prefix_size_from_flags(Flag f);
57 std::size_t pixel_size(void) const;
60 std::vector<char> v = {}, flip_tmp = {};
63};
64
66 constexpr auto f = [](std::span<char> s, u8 x) {
67 using namespace std::string_view_literals;
68 static_assert(nngn::is_sequence("0123456789"sv));
69 constexpr auto z = static_cast<unsigned>('0');
70 const auto i = static_cast<unsigned>(x);
71 s[2] = static_cast<char>(z + i % 10);
72 s[1] = static_cast<char>(z + i / 10 % 10);
73 s[0] = static_cast<char>(z + i / 100 % 10);
74 };
75 f(this->r, color[0]);
76 f(this->g, color[1]);
77 f(this->b, color[2]);
78}
79
81 const ColoredPixel &lhs, const ColoredPixel &rhs)
82{
83 constexpr auto off0 = offsetof(ColoredPixel, r);
84 constexpr auto off1 = offsetof(ColoredPixel, m);
85 static_assert(off0 < off1);
86 constexpr auto n = off1 - off0;
87 return std::memcmp(lhs.r.data(), rhs.r.data(), n) == 0;
88}
89
91 flags{f},
92 mode{m},
95 nngn::Flags<Flag>{f}.is_set(Flag::RESET_COLOR)
96 ? sizeof(ANSIEscapeCode::reset_color) : 0
97 }
98{}
99
100inline constexpr std::size_t FrameBuffer::prefix_size_from_flags(Flag f) {
101 const auto u = to_underlying(f);
102 std::size_t ret = 0;
103 if(u & to_underlying(Flag::CLEAR))
104 ret += sizeof(VT100EscapeCode::clear);
105 if(u & to_underlying(Flag::REPOSITION))
106 ret += sizeof(VT100EscapeCode::pos);
107 return ret;
108}
109
110inline std::size_t FrameBuffer::pixel_size(void) const {
111 switch(this->mode) {
112 case Mode::COLORED:
113 return sizeof(ColoredPixel);
114 case Mode::ASCII:
115 default:
116 return 1;
117 }
118}
119
120inline std::span<char> FrameBuffer::prefix(void) {
121 return std::span{this->v}.subspan(0, this->prefix_size);
122}
123
124inline std::span<char> FrameBuffer::pixels(void) {
125 return {end(this->prefix()), begin(this->suffix())};
126}
127
128inline std::span<char> FrameBuffer::suffix(void) {
129 return std::span{this->v}.subspan(this->v.size() - this->suffix_size);
130}
131
133 std::size_t x, std::size_t y, Texture::texel4 color)
134{
135 using namespace std::string_view_literals;
136 constexpr auto lum =
137 " `^\",:;Il!i~+_-?][}{1)(|\\/"
138 "tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"sv;
139 constexpr auto max = static_cast<float>(lum.size() - 1);
140 const auto fc = static_cast<vec4>(color) / 255.0f;
141 const auto c = nngn::Math::avg(fc.xyz()) * fc[3];
142 assert(0 <= c && c <= 1);
143 const auto ci = static_cast<std::size_t>(c * max);
144 if(!ci)
145 return;
146 const auto w = static_cast<std::size_t>(this->m_size.x);
147 const auto i = w * y + x;
149 this->pixels()[i] = lum[ci];
150}
151
153 std::size_t x, std::size_t y, Texture::texel4 color)
154{
155 // TODO blend
156 if(!color[3])
157 return;
158 const auto fc = static_cast<vec4>(color);
159 const auto rgb = static_cast<Texture::texel3>(fc.xyz() * (fc[3] / 255.0f));
160 const auto w = static_cast<std::size_t>(this->m_size.x);
161 const auto i = w * y + x;
163 const auto px = ColoredPixel{rgb};
164 const auto ps = nngn::byte_cast<ColoredPixel>(this->pixels());
165 std::memcpy(&ps[i], &px, sizeof(px));
166}
167
168}
169
170#endif
static constexpr vector_type< T > avg(T v)
Definition math.h:285
Definition frame_buffer.h:12
void resize_and_clear(uvec2 s)
Changes the size and clears the content according to the mode.
Definition frame_buffer.cpp:52
std::size_t prefix_size
Definition frame_buffer.h:61
std::span< char > prefix(void)
Definition frame_buffer.h:120
void flip(void)
Inverts the Y coord.
Definition frame_buffer.cpp:74
static constexpr std::size_t prefix_size_from_flags(Flag f)
Definition frame_buffer.h:100
std::size_t suffix_size
Definition frame_buffer.h:61
Mode mode
Definition frame_buffer.h:59
Flags< Flag > flags
Definition frame_buffer.h:58
std::vector< char > flip_tmp
Definition frame_buffer.h:60
std::span< char > pixels(void)
Definition frame_buffer.h:124
std::size_t pixel_size(void) const
Definition frame_buffer.h:110
std::vector< char > v
Definition frame_buffer.h:60
uvec2 size(void) const
Size of the frame buffer in pixels.
Definition frame_buffer.h:19
std::span< char > span(void)
Pointer to the content.
Definition frame_buffer.h:21
std::span< char > suffix(void)
Definition frame_buffer.h:128
FrameBuffer(Flag f, Mode m)
Definition frame_buffer.h:90
void write_ascii(std::size_t x, std::size_t y, Texture::texel4 color)
Write pixel at {x, y} with color, ASCII output.
Definition frame_buffer.h:132
uvec2 m_size
Definition frame_buffer.h:62
void write_colored(std::size_t x, std::size_t y, Texture::texel4 color)
Write pixel at {x, y} with color, colored output.
Definition frame_buffer.h:152
std::size_t dedup(void)
Eliminates redundant information, possibly reducing the size.
Definition frame_buffer.cpp:88
vec4_base< u8 > texel4
Definition texture.h:21
assert
Definition debug.lua:3
function DEMO text end
Definition demo0.lua:6
for i
Definition font.lua:5
local n
Definition dump_lights.lua:5
local c
Definition gamma.lua:11
local r
Definition gamma.lua:7
local ps
Definition configure.lua:4
Definition const.h:6
Definition audio.cpp:7
constexpr const R * begin(const T< R > &v)
Definition vec.h:207
constexpr To byte_cast(From p)
reinterpret_cast restricted to conversions from/to char/uchar.
Definition utils.h:121
constexpr auto to_underlying(T t)
Definition utils.h:138
consteval auto to_array(const char *s)
Definition ranges.h:80
std::uint8_t u8
Definition def.h:12
constexpr bool is_sequence(R &&r, Proj proj={})
Definition ranges.h:119
local m
Definition input.lua:28
local function f()) end
local w
Definition strict.lua:12
Wrapper for a small unsigned integral representing flags.
Definition flags.h:18
constexpr bool is_set(AT a) const
Definition flags.h:45
TerminalMode
Definition graphics.h:163
TerminalFlag
Definition graphics.h:156
static constexpr auto bg_color_24bit
Definition const.h:25
static constexpr auto reset_color
Definition const.h:24
Definition frame_buffer.h:39
std::array< char, 3 > r
Definition frame_buffer.h:48
char m
Definition frame_buffer.h:53
std::array< char, 3 > g
Definition frame_buffer.h:50
char semicolon0
Definition frame_buffer.h:49
std::array< char, CMD.size()> cmd
Definition frame_buffer.h:47
static bool cmp_rgb(const ColoredPixel &lhs, const ColoredPixel &rhs)
Equality comparison for the RGB portion of the data.
Definition frame_buffer.h:80
char space
Definition frame_buffer.h:53
ColoredPixel(void)=default
Constructs a black pixel.
std::array< char, 3 > b
Definition frame_buffer.h:52
static constexpr auto CMD
Definition frame_buffer.h:46
char semicolon1
Definition frame_buffer.h:51
static constexpr auto clear
Definition const.h:12
static constexpr auto pos
Definition const.h:13
T x
Definition vec2.h:12
Definition vec3.h:12
Definition vec4.h:12
std::chrono::seconds s
Definition timing.cpp:6