Loading...
Searching...
No Matches
ArrayToBuffer.hpp
1#pragma once
2
3#include <ossia/detail/pod_vector.hpp>
4
5#include <boost/container/vector.hpp>
6
7#include <halp/controls.hpp>
8#include <halp/geometry.hpp>
9#include <halp/meta.hpp>
10#include <halp/texture.hpp>
11
12#include <algorithm>
13
14#if (!defined(__linux__))
15#define SCORE_LIBC_HAS_FLOAT16 1
16#elif (defined(__linux__) && defined(__GLIBC__))
17#if __GLIBC_PREREQ(2, 40)
18#define SCORE_LIBC_HAS_FLOAT16 1
19#endif
20#endif
21
22// when you enter the least obvious syntax competition and your opponent is clang builtins
23#if defined(__is_identifier)
24#if (!__is_identifier(_Float16))
25#define SCORE_COMPILER_HAS_FLOAT16 1
26#endif
27#endif
28
29namespace Threedim
30{
32{
33 using uninitialized_bytes = boost::container::vector<unsigned char>;
34 unsigned char* bytes;
35 int width;
36 int height;
37 enum texture_format : uint8_t
38 {
39 RGBA8,
40 BGRA8,
41 R8,
42 RG8,
43 R16,
44 RG16,
45 RED_OR_ALPHA8,
46
47 RGBA16F,
48 RGBA32F,
49 R16F,
50 R32F,
51
52 R8UI,
53 R32UI,
54 RG32UI,
55 RGBA32UI,
56 } format
57 = RGBA8;
58 bool changed;
59
60 static constexpr int component_size(texture_format format) noexcept
61 {
62 switch(format)
63 {
64 case RGBA8:
65 case BGRA8:
66 return 1;
67 case R8:
68 return 1;
69 case RG8:
70 return 1;
71 case R16:
72 return 2;
73 case RG16:
74 return 2;
75 case RED_OR_ALPHA8:
76 return 1;
77 case RGBA16F:
78 return 2;
79 case RGBA32F:
80 return 4;
81 case R16F:
82 return 2;
83 case R32F:
84 return 4;
85 case R8UI:
86 return 1;
87 case R32UI:
88 return 4;
89 case RG32UI:
90 return 4;
91 case RGBA32UI:
92 return 4;
93 default:
94 return 1;
95 }
96 }
97 static constexpr int components(texture_format format) noexcept
98 {
99 switch(format)
100 {
101 case RGBA8:
102 case BGRA8:
103 return 4;
104 case R8:
105 return 1;
106 case RG8:
107 return 2;
108 case R16:
109 return 1;
110 case RG16:
111 return 2;
112 case RED_OR_ALPHA8:
113 return 1;
114 case RGBA16F:
115 return 4;
116 case RGBA32F:
117 return 4;
118 case R16F:
119 return 1;
120 case R32F:
121 return 1;
122 case R8UI:
123 return 1;
124 case R32UI:
125 return 1;
126 case RG32UI:
127 return 2;
128 case RGBA32UI:
129 return 4;
130 default:
131 return 1;
132 }
133 }
134
135 int bytes_per_pixel() const noexcept
136 {
137 return component_size(format) * components(format);
138 }
139 auto bytesize() const noexcept { return bytes_per_pixel() * width * height; }
140 auto component_size() const noexcept { return bytes_per_pixel() * width * height; }
141 /* FIXME the allocation should not be managed by the plug-in */
142 auto allocate(int width, int height)
143 {
144 using namespace boost::container;
145 return uninitialized_bytes(bytesize(), default_init);
146 }
147
148 void update(unsigned char* data, int w, int h) noexcept
149 {
150 bytes = data;
151 width = w;
152 height = h;
153 changed = true;
154 }
155};
157{
158public:
159 halp_meta(name, "Array to texture")
160 halp_meta(category, "Visuals/Textures")
161 halp_meta(c_name, "array_to_texture")
162 halp_meta(manual_url, "https://ossia.io/score-docs/processes/array-to-texture.html")
163 halp_meta(uuid, "bb5dc513-3430-4671-8c74-2bba78e53709")
164
165 struct ins
166 {
167 struct : halp::val_port<"Input", std::vector<float>>
168 {
169 void update(ArrayToTexture& self) { self.recreate(); }
170 } in;
171 struct : halp::xy_spinboxes_i32<"Size">
172 {
173 void update(ArrayToTexture& self) { self.recreate(); }
174 } size;
175 struct : halp::enum_t<custom_texture::texture_format, "Format">
176 {
177 void update(ArrayToTexture& self) { self.recreate(); }
178 } format;
179 } inputs;
180
181 struct
182 {
183 halp::texture_output<"Output", custom_texture> main;
184 } outputs;
185
186 void recreate()
187 {
188 const auto format = inputs.format;
189 const auto sz = inputs.size.value;
190 outputs.main.texture.format = format;
191 outputs.main.create(sz.x, sz.y);
192 std::size_t to_copy = sz.x * sz.y * outputs.main.texture.components(format);
193 const auto& value = inputs.in.value;
194 to_copy = std::min(to_copy, value.size());
195
196 auto* out = outputs.main.texture.bytes;
197 using enum custom_texture::texture_format;
198 switch(format)
199 {
200 case RGBA8:
201 case BGRA8:
202 case R8:
203 case RG8:
204 case RED_OR_ALPHA8:
205 case R8UI:
206 std::copy_n(value.data(), to_copy, (uint8_t*)out);
207 break;
208
209 case R16:
210 case RG16:
211 std::copy_n(value.data(), to_copy, (uint16_t*)out);
212 break;
213
214 case R32UI:
215 case RG32UI:
216 case RGBA32UI:
217 std::copy_n(value.data(), to_copy, (uint32_t*)out);
218 break;
219
220 case R32F:
221 case RGBA32F:
222 std::copy_n(value.data(), to_copy, (float*)out);
223 break;
224
225 case R16F:
226 case RGBA16F:
227
228#if (SCORE_LIBC_HAS_FLOAT16 && SCORE_COMPILER_HAS_FLOAT16)
229 std::copy_n(value.data(), to_copy, (_Float16*)out);
230#endif
231 break;
232
233 default:
234 break;
235 }
236 outputs.main.upload();
237 }
238};
239
240}
Definition ArrayToBuffer.hpp:157
Definition ArrayToBuffer.hpp:166
Definition ArrayToBuffer.hpp:32