Tatooine
upload.h
Go to the documentation of this file.
1#if TATOOINE_GL_AVAILABLE
2#ifndef TATOOINE_GPU_UPLOAD_H
3#define TATOOINE_GPU_UPLOAD_H
4//==============================================================================
5#include <tatooine/field.h>
8#include <tatooine/rank.h>
9//==============================================================================
10namespace tatooine::gpu {
11//==============================================================================
12template <typename GPUReal>
14 auto data = dynamic_multidim_array<GPUReal>{tex.width(), tex.height()};
15 tex.download_data(data.data());
16 return data;
17}
18// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19template <typename GPUReal>
22 tex.download_data(reinterpret_cast<GPUReal*>(data.data().data()));
23 return data;
24}
25// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26template <typename GPUReal>
29 tex.download_data(data.data());
30 return data;
31}
32// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33template <typename GPUReal>
36 tex.download_data(data.data());
37 return data;
38}
39//==============================================================================
40template <floating_point GPUReal = float, typename Tensor>
41auto upload_tex(std::vector<Tensor> const& data,
42 integral auto const... res) requires
43 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
44 using namespace gl;
45 std::vector<GPUReal> gpu_data;
46 for (auto const& d : data) {
47 if constexpr (std::is_floating_point_v<Tensor>) {
48 gpu_data.push_back(d);
49 } else {
50 for (size_t i = 0; i < Tensor::size(0); ++i) {
51 gpu_data.push_back(d(i));
52 }
53 }
54 }
55 if constexpr (rank<Tensor>() == 0) {
56 return texture<sizeof...(res), GPUReal, R>(gpu_data, res...);
57 } else if constexpr (rank<Tensor>() == 1) {
58 return texture<sizeof...(res), GPUReal, RG>(gpu_data, res...);
59 } else if constexpr (rank<Tensor>() == 2) {
60 return texture<sizeof...(res), GPUReal, RGB>(gpu_data, res...);
61 } else if constexpr (rank<Tensor>() == 3) {
62 return texture<sizeof...(res), GPUReal, RGBA>(gpu_data, res...);
63 }
64}
65//------------------------------------------------------------------------------
66template <size_t Dimensions, typename TexComps, floating_point GPUReal = float,
67 typename Tensor, size_t... Is>
69 std::index_sequence<Is...> /*seq*/) requires
70 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
71 return upload_tex<TexComps, GPUReal>(data.data(), data.size(Is)...);
72}
73// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74template <size_t Dimensions, typename TexComps, typename GPUReal = float,
75 typename Tensor>
77 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
78 static_assert(Dimensions >= 1 && Dimensions <= 3);
79 return upload_tex<Dimensions, TexComps, GPUReal>(
80 data, std::make_index_sequence<Dimensions>{});
81}
82//------------------------------------------------------------------------------
83template <typename GPUReal = float, typename Tensor>
85 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
86 using namespace gl;
87 if constexpr (rank<Tensor>() == 0) {
88 return upload_tex<1, R, GPUReal>(data);
89 } else if constexpr (rank<Tensor>() == 1) {
90 return upload_tex<1, RG, GPUReal>(data);
91 } else if constexpr (rank<Tensor>() == 2) {
92 return upload_tex<1, RGB, GPUReal>(data);
93 } else if constexpr (rank<Tensor>() == 3) {
94 return upload_tex<1, RGBA, GPUReal>(data);
95 }
96}
97//------------------------------------------------------------------------------
98template <typename GPUReal = float, typename Tensor>
100 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
101 using namespace gl;
102 if constexpr (rank<Tensor>() == 0) {
103 return upload_tex<2, R, GPUReal>(data);
104 } else if constexpr (rank<Tensor>() == 1) {
105 return upload_tex<2, RG, GPUReal>(data);
106 } else if constexpr (rank<Tensor>() == 2) {
107 return upload_tex<2, RGB, GPUReal>(data);
108 } else if constexpr (rank<Tensor>() == 3) {
109 return upload_tex<2, RGBA, GPUReal>(data);
110 }
111}
112//------------------------------------------------------------------------------
113template <typename GPUReal = float, typename Tensor>
115 std::is_floating_point_v<Tensor> || static_vec<Tensor> {
116 using namespace gl;
117 if constexpr (rank<Tensor>() == 0) {
118 return upload_tex<3, R, GPUReal>(data);
119 } else if constexpr (rank<Tensor>() == 1) {
120 return upload_tex<3, RG, GPUReal>(data);
121 } else if constexpr (rank<Tensor>() == 2) {
122 return upload_tex<3, RGB, GPUReal>(data);
123 } else if constexpr (rank<Tensor>() == 3) {
124 return upload_tex<3, RGBA, GPUReal>(data);
125 }
126}
127//==============================================================================
128template <typename GPUReal = float, floating_point Real,
129 floating_point_range XDomain, bool HasNonConstReference>
130auto upload(typed_grid_vertex_property_interface<rectilinear_grid<XDomain>, Real,
131 HasNonConstReference> const&
132 grid_vertex_property) {
133 using namespace gl;
134 std::vector<GPUReal> gpu_data;
135 gpu_data.reserve(grid_vertex_property.grid().vertices().size());
136 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
137 gpu_data.push_back(static_cast<GPUReal>(grid_vertex_property(is...)));
138 });
139
140 auto tex = texture<1, GPUReal, R>(gpu_data,
141 grid_vertex_property.grid().template size<0>());
142 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
143 return tex;
144}
145//------------------------------------------------------------------------------
146template <typename GPUReal = float, floating_point Real,
148 bool HasNonConstReference>
149auto upload(typed_grid_vertex_property_interface<rectilinear_grid<XDomain, YDomain>, Real,
150 HasNonConstReference> const&
151 grid_vertex_property) {
152 using namespace gl;
153 std::vector<GPUReal> gpu_data;
154 gpu_data.reserve(grid_vertex_property.grid().vertices().size());
155 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
156 gpu_data.push_back(static_cast<GPUReal>(grid_vertex_property(is...)));
157 });
158
159 auto tex = texture<2, GPUReal, R>(gpu_data,
160 grid_vertex_property.grid().template size<0>(),
161 grid_vertex_property.grid().template size<1>());
162 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
163 return tex;
164}
165//------------------------------------------------------------------------------
166template <typename GPUReal = float, floating_point Real,
168 floating_point_range ZDomain, bool HasNonConstReference>
169auto upload(typed_grid_vertex_property_interface<
170 rectilinear_grid<XDomain, YDomain, ZDomain>, Real, HasNonConstReference> const&
171 grid_vertex_property) {
172 using namespace gl;
173 std::vector<GPUReal> gpu_data;
174 gpu_data.reserve(grid_vertex_property.grid().vertices().size());
175 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
176 gpu_data.push_back(static_cast<GPUReal>(grid_vertex_property(is...)));
177 });
178
179 auto tex = texture<3, GPUReal, R>(gpu_data,
180 grid_vertex_property.grid().template size<0>(),
181 grid_vertex_property.grid().template size<1>(),
182 grid_vertex_property.grid().template size<2>());
183 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
184 return tex;
185}
186//==============================================================================
187template <typename GPUReal = float, floating_point Real,
188 floating_point_range XDomain, bool HasNonConstReference>
189auto upload(typed_grid_vertex_property_interface<rectilinear_grid<XDomain>, vec<Real, 2>,
190 HasNonConstReference> const&
191 grid_vertex_property) {
192 using namespace gl;
193 std::vector<GPUReal> gpu_data;
194 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 2);
195 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
196 auto const& v = grid_vertex_property(is...);
197 gpu_data.push_back(static_cast<GPUReal>(v(0)));
198 gpu_data.push_back(static_cast<GPUReal>(v(1)));
199 });
200
201 auto tex = texture<1, GPUReal, RG>(
202 gpu_data, grid_vertex_property.grid().template size<0>());
203 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
204 return tex;
205}
206//------------------------------------------------------------------------------
207template <typename GPUReal = float, floating_point Real,
209 bool HasNonConstReference>
211 typed_grid_vertex_property_interface<rectilinear_grid<XDomain, YDomain>, vec<Real, 2>,
212 HasNonConstReference> const& data) {
213 using namespace gl;
214 std::vector<GPUReal> gpu_data;
215 // gpu_data.reserve(data.grid().vertices().size() * 2);
216 data.grid().vertices().iterate_indices([&](auto const... is) {
217 auto const& v = data(is...);
218 gpu_data.push_back(static_cast<GPUReal>(v(0)));
219 gpu_data.push_back(static_cast<GPUReal>(v(1)));
220 });
221
222 auto tex = texture<2, GPUReal, RG>(gpu_data, data.grid().template size<0>(),
223 data.grid().template size<1>());
224 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
225 return tex;
226}
227//------------------------------------------------------------------------------
228template <typename GPUReal = float, floating_point Real,
230 floating_point_range ZDomain, bool HasNonConstReference>
231auto upload(typed_grid_vertex_property_interface<
233 HasNonConstReference> const& grid_vertex_property) {
234 using namespace gl;
235 std::vector<GPUReal> gpu_data;
236 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 2);
237 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
238 auto const& v = grid_vertex_property(is...);
239 gpu_data.push_back(static_cast<GPUReal>(v(0)));
240 gpu_data.push_back(static_cast<GPUReal>(v(1)));
241 });
242
243 auto tex = texture<3, GPUReal, RG>(
244 gpu_data, grid_vertex_property.grid().template size<0>(),
245 grid_vertex_property.grid().template size<1>(),
246 grid_vertex_property.grid().template size<2>());
247 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
248 return tex;
249}
250//==============================================================================
251template <typename GPUReal = float, floating_point Real,
252 floating_point_range XDomain, bool HasNonConstReference>
253auto upload(typed_grid_vertex_property_interface<rectilinear_grid<XDomain>, vec<Real, 3>,
254 HasNonConstReference> const&
255 grid_vertex_property) {
256 using namespace gl;
257 std::vector<GPUReal> gpu_data;
258 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 3);
259 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
260 auto const& v = grid_vertex_property(is...);
261 gpu_data.push_back(static_cast<GPUReal>(v(0)));
262 gpu_data.push_back(static_cast<GPUReal>(v(1)));
263 gpu_data.push_back(static_cast<GPUReal>(v(2)));
264 });
265
266 auto tex = texture<1, GPUReal, RGB>(
267 gpu_data, grid_vertex_property.grid().template size<0>());
268 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
269 return tex;
270}
271//------------------------------------------------------------------------------
272template <typename GPUReal = float, floating_point Real,
274 bool HasNonConstReference>
275auto upload(typed_grid_vertex_property_interface<
276 rectilinear_grid<XDomain, YDomain>, vec<Real, 3>, HasNonConstReference> const&
277 grid_vertex_property) {
278 using namespace gl;
279 std::vector<GPUReal> gpu_data;
280 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 3);
281 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
282 auto const& v = grid_vertex_property(is...);
283 gpu_data.push_back(static_cast<GPUReal>(v(0)));
284 gpu_data.push_back(static_cast<GPUReal>(v(1)));
285 gpu_data.push_back(static_cast<GPUReal>(v(2)));
286 });
287
288 auto tex = texture<2, GPUReal, RGB>(
289 gpu_data, grid_vertex_property.grid().template size<0>(),
290 grid_vertex_property.grid().template size<1>());
291 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
292 return tex;
293}
294//------------------------------------------------------------------------------
295template <typename GPUReal = float, floating_point Real,
297 floating_point_range ZDomain, bool HasNonConstReference>
298auto upload(typed_grid_vertex_property_interface<
300 HasNonConstReference> const& grid_vertex_property) {
301 using namespace gl;
302 std::vector<GPUReal> gpu_data;
303 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 3);
304 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
305 auto const& v = grid_vertex_property(is...);
306 gpu_data.push_back(static_cast<GPUReal>(v(0)));
307 gpu_data.push_back(static_cast<GPUReal>(v(1)));
308 gpu_data.push_back(static_cast<GPUReal>(v(2)));
309 });
310
311 auto tex = texture<3, GPUReal, RGB>(
312 gpu_data, grid_vertex_property.grid().template size<0>(),
313 grid_vertex_property.grid().template size<1>(),
314 grid_vertex_property.grid().template size<2>());
315 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
316 return tex;
317}
318//==============================================================================
319template <typename GPUReal = float, floating_point Real,
320 floating_point_range XDomain, bool HasNonConstReference>
321auto upload(typed_grid_vertex_property_interface<rectilinear_grid<XDomain>, vec<Real, 4>,
322 HasNonConstReference> const&
323 grid_vertex_property) {
324 using namespace gl;
325 std::vector<GPUReal> gpu_data;
326 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 4);
327 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
328 auto const& v = grid_vertex_property(is...);
329 gpu_data.push_back(static_cast<GPUReal>(v(0)));
330 gpu_data.push_back(static_cast<GPUReal>(v(1)));
331 gpu_data.push_back(static_cast<GPUReal>(v(2)));
332 gpu_data.push_back(static_cast<GPUReal>(v(3)));
333 });
334
335 auto tex = texture<1, GPUReal, RGBA>(
336 gpu_data, grid_vertex_property.grid().template size<0>());
337 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
338 return tex;
339}
340//------------------------------------------------------------------------------
341template <typename GPUReal = float, floating_point Real,
343 bool HasNonConstReference>
344auto upload(typed_grid_vertex_property_interface<
345 rectilinear_grid<XDomain, YDomain>, vec<Real, 4>, HasNonConstReference> const&
346 grid_vertex_property) {
347 using namespace gl;
348 std::vector<GPUReal> gpu_data;
349 gpu_data.reserve(grid_vertex_property.grid().vertices().size() * 4);
350 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
351 auto const& v = grid_vertex_property(is...);
352 gpu_data.push_back(static_cast<GPUReal>(v(0)));
353 gpu_data.push_back(static_cast<GPUReal>(v(1)));
354 gpu_data.push_back(static_cast<GPUReal>(v(2)));
355 gpu_data.push_back(static_cast<GPUReal>(v(3)));
356 });
357
358 auto tex = texture<2, GPUReal, RGBA>(
359 gpu_data, grid_vertex_property.grid().template size<0>(),
360 grid_vertex_property.grid().template size<1>());
361 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
362 return tex;
363}
364//------------------------------------------------------------------------------
365template <typename GPUReal = float, floating_point Real,
367 floating_point_range ZDomain, bool HasNonConstReference>
368auto upload(typed_grid_vertex_property_interface<
370 HasNonConstReference> const& grid_vertex_property) {
371 using namespace gl;
372 std::vector<GPUReal> gpu_data;
373 grid_vertex_property.reserve(gpu_data.grid().vertices().size() * 4);
374 grid_vertex_property.grid().vertices().iterate_indices([&](auto const... is) {
375 auto const& v = grid_vertex_property(is...);
376 gpu_data.push_back(static_cast<GPUReal>(v(0)));
377 gpu_data.push_back(static_cast<GPUReal>(v(1)));
378 gpu_data.push_back(static_cast<GPUReal>(v(2)));
379 gpu_data.push_back(static_cast<GPUReal>(v(3)));
380 });
381
382 auto tex = texture<3, GPUReal, RGBA>(
383 gpu_data, grid_vertex_property.grid().template size<0>(),
384 grid_vertex_property.grid().template size<1>(),
385 grid_vertex_property.grid().template size<2>());
386 tex.set_wrap_mode(gl::CLAMP_TO_EDGE);
387 return tex;
388}
389//==============================================================================
390} // namespace tatooine::gpu
391//==============================================================================
392#endif
393#endif
Definition: dynamic_multidim_array.h:18
constexpr auto data(std::size_t const i) -> auto &
Definition: dynamic_multidim_array.h:311
Definition: texture.h:61
auto width() const
Definition: texture.h:740
auto height() const
Definition: texture.h:742
auto download_data() const
Definition: texture.h:520
Definition: netcdf.h:348
Definition: rectilinear_grid.h:38
Definition: concepts.h:94
Definition: concepts.h:30
Definition: concepts.h:21
Definition: tensor_concepts.h:23
Definition: line_renderer.h:7
auto upload_tex3d(const dynamic_multidim_array< Tensor > &data)
Definition: upload.h:114
auto upload_tex1d(dynamic_multidim_array< Tensor > const &data)
Definition: upload.h:84
auto upload_tex2d(const dynamic_multidim_array< Tensor > &data)
Definition: upload.h:99
auto download(gl::texture< 2, GPUReal, gl::R > const &tex)
Definition: upload.h:13
auto upload(const parameterized_line< Real, N, Interpolator > &l)
Definition: line_renderer.h:10
auto upload_tex(std::vector< Tensor > const &data, integral auto const ... res)
Definition: upload.h:41
tensor< real_number, Dimensions... > Tensor
Definition: tensor.h:184
Definition: vec.h:12