Gamp v0.0.7-36-g24b1eb6
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GLArrayDataClient.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#ifndef GAMP_GLARRAYDATACLIENT_HPP_
13#define GAMP_GLARRAYDATACLIENT_HPP_
14
15#include <cmath>
16#include <memory>
17
18#include <jau/basic_types.hpp>
19#include <jau/float_types.hpp>
20#include <jau/int_types.hpp>
21#include <jau/type_info.hpp>
22
27
28namespace gamp::render::gl::data {
29 using namespace gamp::render::gl;
30
31 /** \addtogroup Gamp_GLData
32 *
33 * @{
34 */
35
36 template<typename Value_type>
38
39 template<typename Value_type>
40 using GLArrayDataClientRef = std::shared_ptr<GLArrayDataClient<Value_type>>;
41
44
45 /**
46 * Client data buffer for non VBO GLArrayData usage of given template-type Value_type.
47 *
48 * The GL data type is determined via template type glType<Value_type>().
49 */
50 template<typename Value_type>
51 class GLArrayDataClient : public GLArrayDataProxy<Value_type> {
52 public:
55 using typename proxy_t::buffer_t;
56 using typename proxy_t::buffer_ref;
57
59 typedef std::shared_ptr<client_t> client_ref;
60
61 /** Default growth factor using the golden ratio 1.618 */
62 inline static constexpr float DEFAULT_GROWTH_FACTOR = std::numbers::phi_v<float>;
63
64 /**
65 * Create a client side buffer object, using a custom GLSL array attribute name
66 * and starting with a new created Buffer object with initialElementCount size
67 *
68 * The GL data type is determined via template type glType<Value_type>().
69 * @param name The custom name for the GL attribute.
70 * @param compsPerElement The array component number
71 * @param normalized Whether the data shall be normalized
72 * @param initialElementCount
73 */
74 static client_ref createGLSL(const std::string& name, GLsizei compsPerElement,
75 bool normalized, size_t initialElementCount)
76 {
77 client_ref r = std::make_shared<GLArrayDataClient>(Private(),
78 name, compsPerElement,
79 normalized, /*stride=*/0, initialElementCount, DEFAULT_GROWTH_FACTOR,
80 /*isVertexAttribute=*/true, std::move(std::make_unique<impl::GLSLArrayHandler<value_type>>()),
81 /*vboName=*/0, /*vboOffset=*/0, /*vboUsage=*/0, /*vboTarget=*/0);
82 r->m_glArrayHandler->set(r);
83 return r;
84 }
85
86 /**
87 * Create a client side buffer object, using a custom GLSL array attribute name
88 * and starting with a given Buffer object incl it's stride.
89 *
90 * The GL data type is determined via template type glType<Value_type>().
91 * @param name The custom name for the GL attribute.
92 * @param compsPerElement The array component number
93 * @param normalized Whether the data shall be normalized
94 * @param stride
95 * @param buffer the user define data, taking ownership
96 */
97 static client_ref createGLSL(const std::string& name, GLsizei compsPerElement,
98 bool normalized, GLsizei stride, buffer_t&& buffer)
99 {
100 client_ref r = std::make_shared<GLArrayDataClient>(Private(),
101 name, compsPerElement,
102 normalized, stride, std::move(buffer), DEFAULT_GROWTH_FACTOR, 0 /* mappedElementCount */,
103 /*isVertexAttribute=*/true, std::move(std::make_unique<impl::GLSLArrayHandler<value_type>>()),
104 /*vboName=*/0, /*vboOffset=*/0, /*vboUsage=*/0, /*vboTarget=*/0);
105 r->m_glArrayHandler->set(r);
106 return r;
107 }
108
109 std::string_view className() const noexcept override { return "GLArrayDataClient"; }
110
111 const jau::type_info& classSignature() const noexcept override {
113 }
114
116
117 void associate(ShaderState& st, bool enable) override {
118 if( enable ) {
119 m_shaderState = &st;
120 } else {
121 m_shaderState = nullptr;
122 }
123 }
124
125 //
126 // Data read access
127 //
128
129 constexpr bool enabled() const noexcept { return m_bufferEnabled; }
130
131 /** Is the buffer written to the VBO ? */
132 constexpr bool isVBOWritten() const noexcept { return m_bufferWritten; }
133
134 //
135 // Data and GL state modification ..
136 //
137
138 /** Marks the buffer written to the VBO */
139 void setVBOWritten(bool written) noexcept {
140 m_bufferWritten = (0 == GLArrayData::m_mappedElemCount) ? written : true;
141 }
142
143 void destroy(GL& gl) override {
144 clear(gl);
146 }
147
148 /**
149 * Clears this buffer and resets states accordingly.
150 * <p>
151 * Implementation calls {@link #seal(GL&, bool) seal(gl, false)} and {@link #clear()},
152 * i.e. turns-off the GL& buffer and then clearing it.
153 * </p>
154 * <p>
155 * The position is set to zero, the limit is set to the capacity, and the mark is discarded.
156 * </p>
157 * <p>
158 * Invoke this method before using a sequence of get or put operations to fill this buffer.
159 * </p>
160 * <p>
161 * This method does not actually erase the data in the buffer and will most often be used when erasing the underlying memory is suitable.
162 * </p>
163 * @see #seal(GL&, bool)
164 * @see #clear()
165 */
166 void clear(GL& gl) {
167 seal(gl, false);
168 clear();
169 }
170
171 /**
172 * Convenience method calling {@link #seal(bool)} and {@link #enableBuffer(GL&, bool)}.
173 *
174 * @see #seal(bool)
175 * @see #enableBuffer(GL&, bool)
176 */
177 void seal(GL& gl, bool seal_) {
178 seal(seal_);
179 enableBuffer(gl, seal_);
180 }
181
182 /**
183 * Enables the buffer if <code>enable</code> is <code>true</code>,
184 * and transfers the data if required.
185 *
186 * In case {@link #isVBO() VBO is used}, it is bound accordingly for the data transfer and association,
187 * i.e. it issued {@link #bindBuffer(GL&, bool)}.
188 * The VBO buffer is unbound when the method returns.
189 *
190 * Disables the buffer if <code>enable</code> is <code>false</code>.
191 *
192 * The action will only be executed,
193 * if the internal enable state differs,
194 * or 'setEnableAlways' was called with 'true'.
195 *
196 * It is up to the user to enable/disable the array properly,
197 * ie in case of multiple data sets for the same vertex attribute (VA).
198 * Meaning in such case usage of one set while expecting another one
199 * to be used for the same VA implies decorating each usage with enable/disable.
200 *
201 * @see #setEnableAlways(bool)
202 */
203 void enableBuffer(GL& gl, bool enable) {
204 if( m_enableBufferAlways || m_bufferEnabled != enable ) {
205 if( enable ) {
206 checkSeal(true);
207 // init/generate VBO name if not done yet
208 init_vbo(gl);
209 }
210 m_glArrayHandler->enableState(gl, enable, m_shaderState);
211 m_bufferEnabled = enable;
212 }
213 }
214
215 /**
216 * if <code>bind</code> is true and the data uses {@link #isVBO() VBO},
217 * the latter will be bound and data written to the GPU if required.
218 * <p>
219 * If <code>bind</code> is false and the data uses {@link #isVBO() VBO},
220 * the latter will be unbound.
221 * </p>
222 * <p>
223 * This method is exposed to allow data VBO arrays, i.e. {@link GL&#GL&_ELEMENT_ARRAY_BUFFER},
224 * to be bounded and written while keeping the VBO bound. The latter is in contrast to {@link #enableBuffer(GL&, bool)},
225 * which leaves the VBO unbound, since it's not required for vertex attributes or pointers.
226 * </p>
227 *
228 * @param gl current GL& object
229 * @param bind true if VBO shall be bound and data written,
230 * otherwise clear VBO binding.
231 * @return true if data uses VBO and action was performed, otherwise false
232 */
233 bool bindBuffer(GL& gl, bool bind) {
234 if( bind ) {
235 checkSeal(true);
236 // init/generate VBO name if not done yet
237 init_vbo(gl);
238 }
239 return m_glArrayHandler->bindBuffer(gl, bind);
240 }
241
242 /**
243 * Affects the behavior of 'enableBuffer'.
244 *
245 * The default is 'false'
246 *
247 * This is useful when you mix up
248 * GLArrayData usage with conventional GL array calls
249 * or in case of a buggy GL& VBO implementation.
250 *
251 * @see #enableBuffer(GL&, bool)
252 */
253 void setEnableAlways(bool always) { m_enableBufferAlways = always; }
254
255 //
256 // Data modification ..
257 //
258
259 /**
260 * Clears this buffer and resets states accordingly.
261 * <p>
262 * The position is set to zero, the limit is set to the capacity, and the mark is discarded.
263 * </p>
264 * <p>
265 * Invoke this method before using a sequence of get or put operations to fill this buffer.
266 * </p>
267 * <p>
268 * This method does not actually erase the data in the buffer and will most often be used when erasing the underlying memory is suitable.
269 * </p>
270 * @see #clear(GL&)
271 */
272 void clear() {
273 m_buffer.clear();
274 proxy_t::m_sealed = false;
275 m_bufferEnabled = false;
276 m_bufferWritten = proxy_t::usesClientMem() ? false : true;
277 }
278
279 /**
280 * <p>If <i>seal</i> is true, it
281 * disables write operations to the buffer.
282 * Calls flip, ie limit:=position and position:=0.</p>
283 *
284 * <p>If <i>seal</i> is false, it
285 * enable write operations continuing
286 * at the buffer position, where you left off at seal(true),
287 * ie position:=limit and limit:=capacity.</p>
288 *
289 * @see #seal(bool)
290 * @see #sealed()
291 */
292 void seal(bool seal) {
293 if( proxy_t::sealed() == seal ) return;
295 m_bufferWritten = proxy_t::usesClientMem() ? false : true;
296 if( seal ) {
297 m_buffer.flip();
298 } else {
299 m_buffer.setPosition(m_buffer.limit());
300 m_buffer.setLimit(m_buffer.size());
301 }
302 }
303
304 /**
305 * Rewinds this buffer. The position is set to zero and the mark is discarded.
306 * <p>
307 * Invoke this method before a sequence of put or get operations.
308 * </p>
309 */
310 void rewind() {
311 m_buffer.rewind();
312 }
313
314 public:
315 template<typename T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>, bool> = true>
317 if( sizeof(Value_type) > sizeof(T) ) {
318 throw jau::IllegalArgumentError("Buffer `"+toString()+"` incompatible with type `"+jau::static_ctti<T>().name()+"`", E_FILE_LINE);
319 }
320 return static_cast<T>( m_buffer.get() );
321 }
322
323 template<typename... Targs,
324 std::enable_if_t< jau::is_all_same_v<Targs...> &&
325 sizeof(value_type) >= sizeof(jau::first_type<Targs...>) &&
326 ( std::is_integral_v<jau::first_type<Targs...>> ||
327 std::is_floating_point_v<jau::first_type<Targs...>> ), bool> = true>
328 constexpr_cxx20 client_t& putN(const Targs&...args) {
329 if( !proxy_t::sealed() ) {
330 growIfNeeded(sizeof...(args));
331 m_buffer.putN(jau::Bool::False, args...);
332 }
333 return *this;
334 }
335
337 if( !proxy_t::sealed() ) {
338 growIfNeeded(1);
339 m_buffer.put(v);
340 }
341 return *this;
342 }
343 constexpr_cxx20 client_t& puti32(const int32_t v) {
344 return put(static_cast<value_type>(v));
345 }
346 constexpr_cxx20 client_t& putu32(const uint32_t v) {
347 return put(static_cast<value_type>(v));
348 }
349 constexpr_cxx20 client_t& putf(const float v) {
350 return put(static_cast<value_type>(v));
351 }
352 constexpr_cxx20 client_t& put2f(const float x, const float y) {
353 return putN(x, y);
354 }
355 constexpr_cxx20 client_t& put3f(const float x, const float y, const float z) {
356 return putN(x, y, z);
357 }
358 constexpr_cxx20 client_t& put4f(const float x, const float y, const float z, const float w) {
359 return putN(x, y, z, w);
360 }
362 return putN(v.x, v.y);
363 }
365 return putN(v.x, v.y, v.z);
366 }
368 return putN(v.x, v.y, v.z, v.w);
369 }
370
371 std::string toString() const noexcept override { return toString(false); }
372 std::string toString(bool withData) const noexcept override {
373 std::string r("GLArrayDataWrapper[");
374 r.append(proxy_t::m_name)
375 .append(", location ").append(std::to_string(proxy_t::m_location))
376 .append(", isVertexAttribute ").append(std::to_string(proxy_t::m_isVertexAttr))
377 .append(", usesShaderState ").append(std::to_string(nullptr!=m_shaderState))
378 .append(", dataType ").append(jau::to_hexstring(proxy_t::m_compType))
379 .append(", compsPerElem ").append(std::to_string(proxy_t::compsPerElem()))
380 .append(", stride ").append(std::to_string(proxy_t::m_strideB)).append("b ").append(std::to_string(proxy_t::m_strideL)).append("c")
381 .append(", mappedElements ").append(std::to_string(proxy_t::m_mappedElemCount))
382 .append(", ").append(proxy_t::elemStatsToString())
383 .append(", enabled ").append(std::to_string(m_bufferEnabled))
384 .append(", written ").append(std::to_string(m_bufferWritten));
385 if( withData ) {
386 r.append(", buffer ").append(proxy_t::usesClientMem()?m_buffer.toString():"nil");
387 }
388 r.append(", alive ").append(std::to_string(proxy_t::m_alive)).append("]");
389 return r;
390 }
391
392 /**
393 * Returning element-count from given componentCount, rounding up to componentsPerElement.
394 */
395 constexpr GLsizei compsToElemCount(GLsizei componentCount) const noexcept {
396 return (componentCount + proxy_t::compsPerElem() - 1) / proxy_t::compsPerElem();
397 }
398
399 /**
400 * Increase the capacity of the buffer if necessary to add given spareComponents components.
401 * <p>
402 * Buffer will not change if remaining free slots, capacity less position, satisfy spareComponents components.
403 * </p>
404 * @param spareComponents number of components to add if necessary.
405 * @return true if buffer size has changed, i.e. grown. Otherwise false.
406 */
407 bool growIfNeeded(glmemsize_t spareComponents) {
408 if( m_buffer.size() == 0 || m_buffer.remaining() < spareComponents ) {
409 const glmemsize_t has_comps = m_buffer.size();
410 const GLsizei required_elems = compsToElemCount(has_comps + spareComponents);
411 const GLsizei grown_elems = compsToElemCount(glmemsize_t(std::round(has_comps * m_growthFactor)));
412 return reserve( std::max(grown_elems, required_elems) );
413 }
414 return false;
415 }
416
417 /**
418 * Increase the capacity of the buffer to given elementCount element size,
419 * i.e. elementCount * componentsPerElement components.
420 *
421 * Buffer will not change if given elementCount is lower or equal current capacity.
422 *
423 * @param elementCount number of elements to hold.
424 * @return true if buffer size has changed, i.e. grown. Otherwise false.
425 */
426 bool reserve(GLsizei elementCount) {
428 throw RenderException("Invalid state: " + toString(), E_FILE_LINE);
429 }
430 // add the stride delta
431 elementCount += (elementCount / proxy_t::compsPerElem()) * (proxy_t::m_strideL - proxy_t::compsPerElem());
432
433 const glmemsize_t osize = m_buffer.size();
434 const glmemsize_t nsize = elementCount * proxy_t::compsPerElem();
435 if( nsize <= osize ) {
436 return false;
437 }
438 m_buffer.resize(nsize);
439 if( DEBUG_MODE ) {
440 jau::PLAIN_PRINT(true, "*** Size: Reserve: comps: %zd, %zd / %zd -> %zd / %zd; %s",
441 proxy_t::compsPerElem(), (osize / proxy_t::compsPerElem()), osize,
442 (nsize / proxy_t::compsPerElem()), nsize, m_buffer.toString().c_str());
443 }
444 return true;
445 }
446
447 /**
448 * Returns this buffer's growth factor.
449 * <p>
450 * Default is {@link #DEFAULT_GROWTH_FACTOR}, i.e. the golden ratio 1.618.
451 * </p>
452 * @see #setGrowthFactor(float)
453 * @see #DEFAULT_GROWTH_FACTOR
454 */
455 constexpr float growthFactor() const noexcept { return m_growthFactor; }
456
457 /**
458 * Sets a new growth factor for this buffer.
459 * <p>
460 * Default is {@link #DEFAULT_GROWTH_FACTOR}, i.e. the golden ratio 1.618.
461 * </p>
462 * @param v new growth factor, which will be clipped to a minimum of 1, i.e. 0% minimum growth.
463 * @see #getGrowthFactor()
464 * @see #DEFAULT_GROWTH_FACTOR
465 */
466 void setGrowthFactor(float v) noexcept {
467 m_growthFactor = std::max(1.0f, v);
468 }
469
470 // non public matters
471
472 protected:
473 void checkSeal(bool test) {
474 if( !proxy_t::m_alive ) {
475 throw RenderException("Invalid state: " + toString(), E_FILE_LINE);
476 }
477 if( proxy_t::sealed() != test ) {
478 if( test ) {
479 throw RenderException("Not Sealed yet, seal first:\n\t" + toString(), E_FILE_LINE);
480 } else {
481 throw RenderException("Already Sealed, can't modify VBO:\n\t" + toString(), E_FILE_LINE);
482 }
483 }
484 }
485
486 struct Private{ explicit Private() = default; };
487
488 /** Private client-mem ctor w/ passing custom buffer */
489 GLArrayDataClient(Private, const std::string& name, GLsizei componentsPerElement,
490 bool normalized, GLsizei stride, buffer_t&& data, float growthFactor,
492 GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
493 : proxy_t(typename proxy_t::Private(),
494 name, componentsPerElement,
497 m_buffer( std::move(data) ),
498 m_glArrayHandler(std::move(glArrayHandler)),
501 m_shaderState(nullptr), m_isValidated(false)
502 {
503 proxy_t::m_sealed = false;
504 }
505
506 /** Private client-mem ctor w/o passing custom buffer */
507 GLArrayDataClient(Private, const std::string& name, GLsizei componentsPerElement,
508 bool normalized, GLsizei stride, GLsizei initialElementCount, float growthFactor,
510 GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
511 : proxy_t(typename proxy_t::Private(),
512 name, componentsPerElement,
515 m_buffer(nullptr, initialElementCount),
516 m_glArrayHandler(std::move(glArrayHandler)),
519 m_shaderState(nullptr), m_isValidated(false)
520 {
521 proxy_t::m_sealed = false;
522 }
523
524 /// using memory mapped elements
526 const std::string& name, GLsizei componentsPerElement,
527 bool normalized, GLsizei stride, GLsizei mappedElementCount,
529 GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
530 : proxy_t(typename proxy_t::Private(),
531 name, componentsPerElement,
532 normalized, stride, mappedElementCount,
534 m_buffer(),
535 m_glArrayHandler(std::move(glArrayHandler)),
538 m_shaderState(nullptr), m_isValidated(false)
539 {
540 proxy_t::m_sealed = false;
541 }
542
543 virtual void init_vbo(const GL& gl) {
544 if( !m_isValidated ) {
545 m_isValidated = true;
547 }
548 }
549
552
558
559 private:
560 bool m_isValidated = false;
561 static constexpr bool DEBUG_MODE = false;
562 };
563
564 /**@}*/
565
566} // namespace gamp::render::gl::data
567
569 template<typename Value_type>
571 if( !m_ad || !m_ad->isVBO() ) {
572 return false;
573 }
574 if( bind ) {
575 // always bind and refresh the VBO mgr,
576 // in case more than one gl*Pointer objects are in use
577 m_ad->glBindBuffer(gl, true);
578 if( !m_ad->isVBOWritten() ) {
579 if( m_ad->usesClientMem() ) {
580 m_ad->glBufferData(gl);
581 }
582 m_ad->setVBOWritten(true);
583 }
584 } else {
585 m_ad->glBindBuffer(gl, false);
586 }
587 return true;
588 }
589}
590
591#endif /* GAMP_GLARRAYDATACLIENT_HPP_ */
592
#define E_FILE_LINE
Client data buffer for non VBO GLArrayData usage of given template-type Value_type.
std::string_view className() const noexcept override
Returns class name of implementing class.
constexpr bool enabled() const noexcept
GLArrayDataClient(Private, const std::string &name, GLsizei componentsPerElement, bool normalized, GLsizei stride, GLsizei initialElementCount, float growthFactor, bool isVertexAttribute, impl::GLArrayHandlerPtr< value_type > &&glArrayHandler, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
Private client-mem ctor w/o passing custom buffer.
const GLArrayDataClientRef< value_type > shared()
constexpr_cxx20 client_t & put2f(const float x, const float y)
constexpr_cxx20 client_t & put4f(const float x, const float y, const float z, const float w)
constexpr_cxx20 client_t & put2f(const jau::math::Vec2f &v)
static client_ref createGLSL(const std::string &name, GLsizei compsPerElement, bool normalized, size_t initialElementCount)
Create a client side buffer object, using a custom GLSL array attribute name and starting with a new ...
constexpr float growthFactor() const noexcept
Returns this buffer's growth factor.
impl::GLArrayHandlerPtr< value_type > m_glArrayHandler
constexpr_cxx20 client_t & putf(const float v)
GLArrayDataClient(Private, const std::string &name, GLsizei componentsPerElement, bool normalized, GLsizei stride, GLsizei mappedElementCount, bool isVertexAttribute, impl::GLArrayHandlerPtr< value_type > &&glArrayHandler, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
using memory mapped elements
constexpr_cxx20 client_t & putN(const Targs &...args)
bool bindBuffer(GL &gl, bool bind)
if bind is true and the data uses VBO, the latter will be bound and data written to the GPU if requir...
void seal(GL &gl, bool seal_)
Convenience method calling seal(bool) and enableBuffer(GL&, bool).
void enableBuffer(GL &gl, bool enable)
Enables the buffer if enable is true, and transfers the data if required.
void clear()
Clears this buffer and resets states accordingly.
void clear(GL &gl)
Clears this buffer and resets states accordingly.
void setVBOWritten(bool written) noexcept
Marks the buffer written to the VBO.
void setGrowthFactor(float v) noexcept
Sets a new growth factor for this buffer.
void setEnableAlways(bool always)
Affects the behavior of 'enableBuffer'.
void associate(ShaderState &st, bool enable) override
Implementation and type dependent object association.
constexpr bool isVBOWritten() const noexcept
Is the buffer written to the VBO ?
const jau::type_info & classSignature() const noexcept override
Returns type signature of implementing class.
GLArrayDataClient(Private, const std::string &name, GLsizei componentsPerElement, bool normalized, GLsizei stride, buffer_t &&data, float growthFactor, bool isVertexAttribute, impl::GLArrayHandlerPtr< value_type > &&glArrayHandler, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
Private client-mem ctor w/ passing custom buffer.
constexpr GLsizei compsToElemCount(GLsizei componentCount) const noexcept
Returning element-count from given componentCount, rounding up to componentsPerElement.
bool growIfNeeded(glmemsize_t spareComponents)
Increase the capacity of the buffer if necessary to add given spareComponents components.
constexpr_cxx20 client_t & put3f(const jau::math::Vec3f &v)
std::string toString() const noexcept override
constexpr_cxx20 client_t & puti32(const int32_t v)
jau::darray< value_type, glmemsize_t > buffer_t
constexpr_cxx20 client_t & putu32(const uint32_t v)
constexpr_cxx20 client_t & put3f(const float x, const float y, const float z)
bool reserve(GLsizei elementCount)
Increase the capacity of the buffer to given elementCount element size, i.e.
constexpr_cxx20 client_t & put(const value_type v)
constexpr_cxx20 client_t & put4f(const jau::math::Vec4f &v)
std::string toString(bool withData) const noexcept override
static client_ref createGLSL(const std::string &name, GLsizei compsPerElement, bool normalized, GLsizei stride, buffer_t &&buffer)
Create a client side buffer object, using a custom GLSL array attribute name and starting with a give...
std::string elemStatsToString() const noexcept override
GLArrayDataProxy(Private, const std::string &name, GLsizei componentsPerElement, bool normalized, GLsizei stride, buffer_t &buffer, bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
jau::darray< value_type, glmemsize_t > buffer_t
const void * data() const noexcept override
Returns client-data pointer at current position if usesClientMem(), otherwise nullptr.
constexpr bool sealed() const noexcept
Returns true if data has been sealed (flipped to read), otherwise false (writing mode).
virtual void validate(const GL &gl) const
Validates this instance's parameter.
constexpr uintptr_t vboOffset() const noexcept
The VBO buffer offset if isVBO()
constexpr GLsizei compsPerElem() const noexcept
The number of components per element.
constexpr GLuint vboName() const noexcept
The VBO name or 0 if not a VBO.
constexpr bool isVertexAttribute() const noexcept
Returns true if this data set is intended for a GLSL vertex shader attribute, otherwise false,...
GLsizei m_strideB
stride in bytes; strideB >= compsPerElement * bytesPerComp
constexpr GLenum vboUsage() const noexcept
The VBO usage or 0 if not a VBO.
GLsizei stride() const noexcept
constexpr bool normalized() const noexcept
True, if GL shall normalize fixed point data while converting them into float.
GLsizei m_strideL
stride in logical components
std::shared_ptr< ChildT > shared_from_base()
constexpr GLenum vboTarget() const noexcept
The VBO target or 0 if not a VBO.
bool bindBuffer(GL &gl, bool bind)
if bind is true and the data uses VBO, the latter will be bound and data written to the GPU if requir...
GLArrayDataClientRef< Value_type > m_ad
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
value_type x
Definition vec2f.hpp:63
value_type y
Definition vec2f.hpp:64
value_type x
Definition vec3f.hpp:69
value_type y
Definition vec3f.hpp:70
value_type z
Definition vec3f.hpp:71
value_type w
Definition vec4f.hpp:72
value_type x
Definition vec4f.hpp:69
value_type y
Definition vec4f.hpp:70
value_type z
Definition vec4f.hpp:71
Generic type information using either Runtime type information (RTTI) or Compile time type informatio...
consteval_cxx20 std::string_view name() noexcept
std::tuple_element_t< 0, std::tuple< Ts... > > first_type
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
constexpr bool is_all_same_v
const jau::type_info & static_ctti() noexcept
Returns a static global reference of make_ctti<T>(true) w/ identity instance.
GLsizeiptr glmemsize_t
Compatible with ssize_t.
Definition GLBuffers.hpp:26
std::shared_ptr< GLArrayDataClient< Value_type > > GLArrayDataClientRef
GLArrayDataClientRef< float > GLFloatArrayDataClientRef
GLArrayDataClient< float > GLFloatArrayDataClient
std::unique_ptr< GLArrayHandler< Value_type > > GLArrayHandlerPtr
constexpr GLenum glType() noexcept
Definition GLTypes.hpp:46
Vector4F< float > Vec4f
Definition vec4f.hpp:375
Vector2F< float > Vec2f
Definition vec2f.hpp:416
Vector3F< float > Vec3f
Definition vec3f.hpp:436
std::string to_hexstring(value_type const &v, const bool skipLeading0x=false) noexcept
Produce a lower-case hexadecimal string representation with leading 0x in MSB of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition debug.cpp:258
STL namespace.
uint8_t Value_type