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
12class FrameBuffer {
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;
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;
59 Mode mode;
60 std::vector<char> v = {}, flip_tmp = {};
61 std::size_t prefix_size, suffix_size;
62 uvec2 m_size = {};
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
132inline void FrameBuffer::write_ascii(
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;
148 assert(i < this->pixels().size());
149 this->pixels()[i] = lum[ci];
150}
151
152inline void FrameBuffer::write_colored(
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;
162 assert(i < this->pixels().size());
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(const T &v)
Definition: math.h:275
void resize_and_clear(uvec2 s)
Changes the size and clears the content according to the mode.
std::size_t prefix_size
Definition: frame_buffer.h:61
std::span< char > prefix(void)
void flip(void)
Inverts the Y coord.
static constexpr std::size_t prefix_size_from_flags(Flag f)
Definition: frame_buffer.h:100
std::vector< char > v
Definition: frame_buffer.h:60
static constexpr std::size_t prefix_size_from_flags(Flag f)
std::size_t suffix_size
Definition: frame_buffer.h:61
Mode mode
Definition: frame_buffer.h:59
std::span< char > pixels(void)
std::size_t pixel_size(void) const
Flags< Flag > flags
Definition: frame_buffer.h:58
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)
FrameBuffer(Flag f, Mode m)
void write_ascii(std::size_t x, std::size_t y, Texture::texel4 color)
Write pixel at {x, y} with color, ASCII output.
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.
std::vector< char > flip_tmp
Definition: frame_buffer.h:60
std::size_t dedup(void)
Eliminates redundant information, possibly reducing the size.
vec3_base< u8 > texel3
Definition: texture.h:20
vec4_base< u8 > texel4
Definition: texture.h:21
function DEMO text end
Definition: demo0.lua:6
for i
Definition: font.lua:5
r
Definition: gamma.lua:7
c
Definition: gamma.lua:11
assert
Definition: debug.lua:3
n
Definition: dump_lights.lua:5
ps
Definition: configure.lua:4
z
Definition: input.lua:25
m
Definition: input.lua:23
function f()) end
v[1]
Definition: math.lua:19
w
Definition: strict.lua:12
std::chrono::seconds s
Definition: timing.cpp:6
auto size(const Colliders &c)
Definition: lua_collision.cpp:29
Definition: const.h:6
Definition: audio.cpp:7
constexpr const R * begin(const T< R > &v)
Definition: vec.h:207
constexpr auto to_underlying(T t)
Definition: utils.h:138
consteval auto to_array(const char *s)
Definition: ranges.h:80
vec4_base< float > vec4
Definition: vec4.h:128
constexpr bool is_sequence(R &&r, Proj proj={})
Definition: ranges.h:119
std::uint8_t u8
Definition: def.h:12
Wrapper for an unsigned integral representing flags.
Definition: flags.h:18
TerminalMode
Definition: graphics.h:163
TerminalFlag
Definition: graphics.h:156
static constexpr auto pos
Definition: os.h:24
static constexpr auto clear
Definition: os.h:23
static constexpr auto bg_color_24bit
Definition: const.h:25
static constexpr auto reset_color
Definition: const.h:24
Definition: frame_buffer.h:39
static constexpr auto CMD
Definition: frame_buffer.h:46
char m
Definition: frame_buffer.h:53
std::array< char, 3 > b
Definition: frame_buffer.h:52
std::array< char, 3 > r
Definition: frame_buffer.h:48
char semicolon0
Definition: frame_buffer.h:49
std::array< char, 3 > g
Definition: frame_buffer.h:50
ColoredPixel(Texture::texel3 color)
Constructs an opaque pixel with a given color.
static bool cmp_rgb(const ColoredPixel &lhs, const ColoredPixel &rhs)
Equality comparison for the RGB portion of the data.
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.
char semicolon1
Definition: frame_buffer.h:51
std::array< char, CMD.size()> cmd
Definition: frame_buffer.h:47
Definition: vec3.h:12
Definition: vec4.h:12