Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GraphShapes01.cpp
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#include <cstdio>
13#include <cmath>
14#include <gamp/graph/Graph.hpp>
17#include <memory>
18#include <string>
19#include <string_view>
20#include <utility>
21#include <vector>
22
23#include <jau/basic_types.hpp>
24#include <jau/cpp_lang_util.hpp>
25#include <jau/darray.hpp>
26#include <jau/debug.hpp>
27#include <jau/float_math.hpp>
28#include <jau/float_types.hpp>
29#include <jau/fraction_type.hpp>
30#include <jau/io/file_util.hpp>
32#include <jau/math/vec3f.hpp>
33#include <jau/math/vec4f.hpp>
34#include <jau/math/vec4f.hpp>
39
40#include <gamp/Gamp.hpp>
45
47
50
52
53using namespace jau::math;
54using namespace jau::math::util;
55using namespace jau::math::geom;
56
57using namespace gamp;
58using namespace gamp::wt;
59using namespace gamp::wt::event;
60
61using namespace gamp::graph;
62using namespace gamp::render::gl::glsl;
63using namespace gamp::render::gl::data;
64
66 public:
68 bool m_isTwoPass = false;
69 bool m_pass1 = true;
71 bool m_hasNormalChannel = false;
72 bool m_hasLight0 = true;
73 bool m_hasColorChannel = false;
74 bool m_hasColorTexture = false;
75 bool m_hasDiscard = true;
76 };
77 private:
78 GraphRendererProps m_props;
79 ShaderState& m_st;
80 bool m_initialized;
81
82 public:
83 constexpr bool usesNormal() const noexcept { return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
84 constexpr GLsizei arrayCompsPerElement() const noexcept { return usesNormal()? 3*3 : 2*3; }
85
86 static constexpr std::string_view GLSL_PARAM_COMMENT_START = "\n// Gamp Graph Parameter Start\n";
87 static constexpr std::string_view GLSL_PARAM_COMMENT_END = "// Gamp Graph Parameter End\n\n";
88 static constexpr std::string_view GLSL_USE_COLOR_CHANNEL = "#define USE_COLOR_CHANNEL 1\n";
89 static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL = "#define USE_NORMAL_CHANNEL 1\n";
90 static constexpr std::string_view GLSL_USE_LIGHT0 = "#define USE_LIGHT0 1\n";
91 static constexpr std::string_view GLSL_USE_COLOR_TEXTURE = "#define USE_COLOR_TEXTURE 1\n";
92 static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING = "#define USE_FRUSTUM_CLIPPING 1\n";
93 static constexpr std::string_view GLSL_USE_DISCARD = "#define USE_DISCARD 1\n";
94 static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT = "#define SAMPLE_COUNT ";
95 static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT = "const float sample_count = ";
96 static constexpr std::string_view GLSL_MAIN_BEGIN = "void main (void)\n{\n";
97 static constexpr std::string_view gcuTexture2D = "gcuTexture2D";
98 static constexpr std::string_view colTexLookupFuncName = "texture2D";
99 static constexpr std::string_view shader_basename = "curverenderer01";
100 static constexpr std::string_view source_dir = "impl/graph/glsl";
101 static constexpr std::string_view bin_dir = "impl/graph/glsl/bin";
102
103 public:
105 : m_st(st),
106 m_initialized(false)
107 { }
108
109 constexpr bool initialized() const noexcept { return m_initialized; }
110
111 bool init(GL& gl, const jau::fraction_timespec& when) {
113
114 std::string vertexShaderName, fragmentShaderName;
115 vertexShaderName.append(shader_basename);
116 if( m_props.m_isTwoPass ) {
117 vertexShaderName.append("-pass").append(m_props.m_pass1 ? "1":"2");
118 } else {
119 vertexShaderName.append("-single");
120 }
121 fragmentShaderName.append(shader_basename).append("-segment-head");
122
123 ShaderCodeRef rsVp = ShaderCode::create(gl, GL_VERTEX_SHADER, source_dir, bin_dir, vertexShaderName);
124 ShaderCodeRef rsFp = ShaderCode::create(gl, GL_FRAGMENT_SHADER, source_dir, bin_dir, fragmentShaderName);
125 if( !rsVp || !rsFp ) {
126 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
127 return false;
128 }
129 {
130 size_t posVp = rsVp->defaultShaderCustomization(gl);
131 size_t posFp = rsFp->defaultShaderCustomization(gl);
132 if( posVp == std::string::npos || posFp == std::string::npos ) {
133 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
134 return false;
135 }
136
137 // GLSL append from here on
138 posFp = -1;
139
140 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_START);
141 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_START);
142
143 // if( !gl.getContext().hasRendererQuirk(GLRendererQuirks.GLSLBuggyDiscard) ) {
144 if( m_props.m_hasDiscard ) {
145 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_DISCARD);
146 }
147
148 if( m_props.m_hasFrustumClipping ) {
149 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_FRUSTUM_CLIPPING);
150 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_FRUSTUM_CLIPPING);
151 }
152
153 if( usesNormal() ) {
154 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_NORMAL_CHANNEL);
155 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_NORMAL_CHANNEL);
156 }
157 if( m_props.m_hasLight0 ) {
158 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_LIGHT0);
159 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_LIGHT0);
160 }
161 if( m_props.m_hasColorChannel ) {
162 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_COLOR_CHANNEL);
163 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_CHANNEL);
164 }
165 if( m_props.m_hasColorTexture ) {
167 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_TEXTURE);
168 }
169 /*if( !pass1 ) {
170 posFp = rsFp->insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+sms.sampleCount+"\n");
171 posFp = rsFp->insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+sms.sampleCount+".0;\n");
172 } */
173
174 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_END);
175 if( posVp == std::string::npos ) {
176 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
177 return false;
178 }
179
180 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_END);
181
182 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/constants.glsl"));
183 if( posFp == std::string::npos ) {
184 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
185 return false;
186 }
187 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/uniforms.glsl"));
188 if( posFp == std::string::npos ) {
189 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
190 return false;
191 }
192 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/varyings.glsl"));
193 if( posFp == std::string::npos ) {
194 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
195 return false;
196 }
197 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
198 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/functions.glsl"));
199 if( posFp == std::string::npos ) {
200 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
201 return false;
202 }
203 }
204 /*if( hasColorTexture ) {
205 posFp = rsFp->insertShaderSource(0, posFp, "uniform "+colorTexSeq.getTextureSampler2DType()+" "+UniformNames.gcu_ColorTexUnit+";\n");
206 posFp = rsFp->insertShaderSource(0, posFp, colorTexSeq.getTextureLookupFragmentShaderImpl());
207 }*/
208
209 posFp = rsFp->insertShaderSource(0, posFp, GLSL_MAIN_BEGIN);
210
211 std::string passS = m_props.m_pass1 ? "-pass1-" : "-pass2-";
212 std::string shaderSegment = string_t(source_dir).append("/").append(shader_basename).append(passS).append("curve_simple").append(".glsl"); // sms.tech+sms.sub+".glsl";
214 jau::PLAIN_PRINT(true, "RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
215 }
216 posFp = rsFp->insertShaderSourceFile(0, posFp, shaderSegment);
217 if( posFp == std::string::npos ) {
218 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
219 return false;
220 }
221 posFp = rsFp->insertShaderSource(0, posFp, "}\n");
222 if( posFp == std::string::npos ) {
223 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
224 return false;
225 }
226
227 if( m_props.m_hasColorTexture ) {
228 rsFp->replaceInShaderSource(std::string(gcuTexture2D), std::string(colTexLookupFuncName));
229 }
230
231 }
233 if( !sp0->add(gl, rsVp, true) || !sp0->add(gl, rsFp, true) ) {
234 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
235 sp0->destroy(gl);
236 return false;
237 }
238 m_st.attachShaderProgram(gl, sp0, true);
239
240 m_st.pushAllUniforms(gl);
241
242 m_initialized = sp0->inUse();
243 if( !m_initialized ) {
244 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
245 m_st.destroy(gl);
246 }
247 return m_initialized;
248 }
249
250 void useProgram(GL& gl, bool on) {
251 m_st.useProgram(gl, on);
252 }
253
254};
255
257 public:
259 private:
260 GraphRenderer& m_renderer;
261 ShaderState& m_st;
262 bool m_initialized;
264 GLUIntArrayDataServerRef m_indices;
265 int m_num_vertices, m_num_indices;
266
267 public:
269 : m_renderer(renderer), m_st(st),
270 m_initialized(m_renderer.initialized()),
271 m_array(GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
272 m_indices(GLUIntArrayDataServer::createData(3, 256, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER)),
273 m_num_vertices(0), m_num_indices(0)
274 {
275 m_array->addGLSLSubArray("gca_Vertex", 3, GL_ARRAY_BUFFER);
276 m_array->addGLSLSubArray("gca_CurveParam", 3, GL_ARRAY_BUFFER);
277 if( m_renderer.usesNormal() ) {
278 m_array->addGLSLSubArray("gca_Normal", 3, GL_ARRAY_BUFFER);
279 }
280 m_st.ownAttribute(m_array, true);
281 // m_st.ownAttribute(m_indices, true);
282 }
283
284 constexpr bool initialized() const noexcept { return m_initialized; }
285
286 void seal(GL& gl, bool seal_) {
287 if( !m_initialized ) {
288 return;
289 }
290 m_array->seal(gl, seal_);
291 m_indices->seal(gl, seal_);
292 m_array->enableBuffer(gl, false);
293 m_indices->enableBuffer(gl, false);
294 }
295
296 void pushVertex(const Vertex& v, const Vec3f& normal) {
297 // jau::PLAIN_PRINT(true, "pushVertex.0[%d]: v %s]", m_num_vertices, v.toString().c_str());
298 m_array->put3f(v.coord());
299 m_array->put3f(v.texCoord());
300 if( m_renderer.usesNormal() ) {
301 m_array->put3f(normal);
302 }
303 ++m_num_vertices;
304 }
305 void pushIndices(uint32_t i, uint32_t j, uint32_t k) {
306 // jau::PLAIN_PRINT(true, "pushIndices.0[%d]: %u, %u, %u]", m_num_indices, i, j, k);
307 m_indices->putN(i, j, k);
308 m_num_indices += 3;
309 }
310 void pushNewVerticesIdx(const Vertex& vertIn1, const Vertex& vertIn2, const Vertex& vertIn3, const Vec3f& normal) {
311 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
312 pushVertex(vertIn1, normal);
313 pushVertex(vertIn2, normal);
314 pushVertex(vertIn3, normal);
315 }
316
318 if( Graph::DEBUG_MODE ) {
319 jau::PLAIN_PRINT(true, "add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
320 jau::PLAIN_PRINT(true, "add.0 array: %s", m_array->toString().c_str());
321 jau::PLAIN_PRINT(true, "add.0 indices: %s", m_indices->toString().c_str());
322 }
323 const TriangleRefList& trisIn = shape.getTriangles();
324 const VertexList& vertsIn = shape.getVertices();
325 if( Graph::DEBUG_MODE ) {
326 jau::PLAIN_PRINT(true, "add.0 triangles %u, vertices %u", trisIn.size(), vertsIn.size());
327 }
328 {
329 glmemsize_t verticeCount = (glmemsize_t)vertsIn.size() + shape.addedVertexCount();
330 glmemsize_t indexCount = (glmemsize_t)trisIn.size() * 3;
331 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
332 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
333 }
334 uint32_t idxOffset = m_num_vertices;
335 if( vertsIn.size() >= 3 ) {
336 //
337 // Processing Vertices
338 //
339 for(const Vertex& v : vertsIn) {
340 pushVertex(v, shape.normal());
341 }
342 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() / sizeof(uint32_t);
343 OutlineShape::size_type trisIn_sz = trisIn.size();
344 for(OutlineShape::size_type i=0; i < trisIn_sz; ++i) {
345 const TriangleRef& triIn = trisIn[i];
346 // triEx.addVertexIndicesOffset(idxOffset);
347 // triangles.add( triEx );
348 Triangle::trivert_t& triInVertices = triIn->vertices();
349 uint32_t tv0Idx = triInVertices[0].id();
350 if ( max_index - idxOffset > tv0Idx ) {
351 // valid 'known' idx - move by offset
352 pushIndices(tv0Idx+idxOffset,
353 triInVertices[1].id()+idxOffset,
354 triInVertices[2].id()+idxOffset);
355 } else {
356 // FIXME: If exceeding max_indices, we would need to generate a new buffer w/ indices
357 pushNewVerticesIdx(triInVertices[0], triInVertices[1], triInVertices[2], shape.normal());
358 }
359 }
360 }
361 if( Graph::DEBUG_MODE ) {
362 jau::PLAIN_PRINT(true, "add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
363 jau::PLAIN_PRINT(true, "add.x array: %s", m_array->toString().c_str());
364 jau::PLAIN_PRINT(true, "add.x indices: %s", m_indices->toString().c_str());
365 }
366 }
367
368 void draw(GL &gl) {
369 if( !m_initialized ) {
370 return;
371 }
372 m_renderer.useProgram(gl, true);
373
374 m_array->enableBuffer(gl, true);
375 m_indices->bindBuffer(gl, true); // keeps VBO binding
376
377 ::glEnable(GL_BLEND);
378 ::glBlendEquation(GL_FUNC_ADD); // default
379 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
380
381 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT, nullptr);
382
383
384 m_indices->bindBuffer(gl, false);
385 m_array->enableBuffer(gl, false);
386 // m_renderer.useProgram(gl, false);
387 }
388};
389
390class Shape;
391typedef std::shared_ptr<Shape> ShapeRef;
392
393class Shape {
394 private:
395 ShaderState& m_st;
396 GLUniformSyncPMVMat4fRef m_pmvMatUni;
397 OutlineShape m_oshape;
398
399 Vec3f m_position;
400 Quat4f m_rotation;
401 Vec3f m_rotPivot;
402 Vec3f m_scale = Vec3f(1, 1, 1);
403 float m_zOffset;
404 GraphRenderer& m_renderer;
405 GraphRegion m_region;
406 GLUniformVec4fRef m_uColor;
407
408 Mat4f iMat;
409 Mat4f tmpMat;
410 bool iMatIdent = true;
411 bool iMatDirty = false;
412
413 struct Private{ explicit Private() = default; };
414
415 public:
416 Shape(Private, ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer& renderer)
417 : m_st(st), m_pmvMatUni(std::move(pmvMatU)), m_oshape(3, 16),
418 m_renderer(renderer), m_region(m_renderer, m_st)
419 {
420 m_uColor = GLUniformVec4f::create("gcu_StaticColor", Vec4f(0, 0, 0, 1));
421 m_st.ownUniform(m_uColor, true);
422 }
423
425 return std::make_shared<Shape>(Private(), st, std::move(pmvMatU), renderer);
426 }
427
428 constexpr const Vec3f& position() const noexcept { return m_position; }
429 constexpr Vec3f& position() noexcept { iMatDirty=true; return m_position; }
430
431 constexpr const float& zOffset() const noexcept { return m_zOffset; }
432 constexpr float& zOffset() noexcept { iMatDirty=true; return m_zOffset; }
433
434 constexpr const Quat4f& rotation() const noexcept { return m_rotation; }
435 constexpr Quat4f& rotation() noexcept { iMatDirty=true; return m_rotation; }
436
437 constexpr const Vec3f& rotationPivot() const noexcept { return m_rotPivot; }
438 constexpr Vec3f& rotationPivot() noexcept { iMatDirty=true; return m_rotPivot; }
439
440 constexpr const Vec3f& scale() const noexcept { return m_scale; }
441 constexpr Vec3f& scale() noexcept { iMatDirty=true; return m_scale; }
442
443 constexpr const OutlineShape& outlines() const noexcept { return m_oshape; }
444 constexpr OutlineShape& outlines() noexcept { return m_oshape; }
445
446 const Vec4f& color() const noexcept { return m_uColor->vec4f(); }
447 void setColor(const Vec4f& c) noexcept { m_uColor->vec4f()=c; }
448
449 void update(GL& gl) {
450 m_region.addOutlineShape(m_oshape);
451 m_region.seal(gl, true);
452 }
453
454 void draw(GL &gl) {
455 PMVMat4f& pmv = m_pmvMatUni->pmv();
456 pmv.pushMv();
457 applyMatToMv(pmv);
458 m_st.pushUniform(gl, m_pmvMatUni); // automatic sync + update of Mvi + Mvit
459
460 m_st.pushUniform(gl, m_uColor);
461 m_region.draw(gl);
462 pmv.popMv();
463 }
464
465 private:
466 /**
467 * Applies the internal {@link Matrix4f} to the given {@link PMVMatrix4f#getMv() modelview matrix},
468 * i.e. {@code pmv.mulMv( getMat() )}.
469 * <p>
470 * Calls {@link #updateMat()} if dirty.
471 * </p>
472 * In case {@link #isMatIdentity()} is {@code true}, implementation is a no-operation.
473 * </p>
474 * @param pmv the matrix
475 * @see #isMatIdentity()
476 * @see #updateMat()
477 * @see #getMat()
478 * @see PMVMatrix4f#mulMv(Matrix4f)
479 */
480 void applyMatToMv(PMVMat4f& pmvMat) noexcept {
481 if( iMatDirty ) {
482 updateMat();
483 }
484 if( !iMatIdent ) {
485 pmvMat.mulMv(iMat);
486 }
487 }
488 void updateMat() noexcept {
489 bool hasPos = !m_position.is_zero();
490 bool hasScale = m_scale != Vec3f::one;
491 bool hasRotate = !m_rotation.isIdentity();
492 bool hasRotPivot = false; // null != rotPivot;
493 const Vec3f& ctr = m_oshape.bounds().center();
494 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
495
496 if( sameScaleRotatePivot ) {
497 iMatIdent = false;
498 iMat.setToTranslation(m_position); // identity + translate, scaled
499 // Scale shape from its center position and rotate around its center
500 iMat.translate(Vec3f(ctr).mul(m_scale)); // add-back center, scaled
501 iMat.rotate(m_rotation);
502 iMat.scale(m_scale);
503 iMat.translate(-ctr); // move to center
504 } else if( hasRotate || hasScale ) {
505 iMatIdent = false;
506 iMat.setToTranslation(m_position); // identity + translate, scaled
507 if( hasRotate ) {
508 if( hasRotPivot ) {
509 // Rotate shape around its scaled pivot
510 iMat.translate(Vec3f(m_rotPivot).mul(m_scale)); // pivot back from rot-pivot, scaled
511 iMat.rotate(m_rotation);
512 iMat.translate(Vec3f(-m_rotPivot).mul(m_scale)); // pivot to rot-pivot, scaled
513 } else {
514 // Rotate shape around its scaled center
515 iMat.translate(Vec3f(ctr).mul(m_scale)); // pivot back from center-pivot, scaled
516 iMat.rotate(m_rotation);
517 iMat.translate(Vec3f(-ctr).mul(m_scale)); // pivot to center-pivot, scaled
518 }
519 }
520 if( hasScale ) {
521 // Scale shape from its center position
522 iMat.translate(Vec3f(ctr).mul(m_scale)); // add-back center, scaled
523 iMat.scale(m_scale);
524 iMat.translate(Vec3f(-ctr).mul(m_scale)); // move to center
525 }
526 } else if( hasPos ) {
527 iMatIdent = false;
528 iMat.setToTranslation(m_position); // identity + translate, scaled
529
530 } else {
531 iMatIdent = true;
532 iMat.loadIdentity();
533 }
534 iMatDirty = false;
535 }
536};
537
539 private:
540 constexpr static float zNear= 1.0f;
541 constexpr static float zFar =100.0f;
542 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
543
544 ShaderState m_st;
545 Recti m_viewport;
546 bool m_initialized;
547 bool m_animating = true;
548 bool m_oneframe = false;
550 GLUniformSyncPMVMat4fRef m_pmvMatUni;
551 GraphRenderer m_renderer;
552 std::vector<ShapeRef> m_shapes;
553 const jau::math::Vec3f lightPos = jau::math::Vec3f(0.0f, 5.0f, 10.0f);
554
555 public:
558 m_initialized(false),
559 m_pmvMatUni(GLUniformSyncPMVMat4f::create("gcu_PMVMatrix", mat_req)), // P, Mv, Mvi and Mvit
560 m_renderer(m_st)
561 {
562 }
563
564 Recti& viewport() noexcept { return m_viewport; }
565 const Recti& viewport() const noexcept { return m_viewport; }
566
567 PMVMat4f& pmv() noexcept { return m_pmvMatUni->pmv(); }
568 const PMVMat4f& pmv() const noexcept { return m_pmvMatUni->pmv(); }
569 bool animating() const noexcept { return m_animating; }
570 bool& animating() noexcept { return m_animating; }
571 void setOneFrame() noexcept { m_animating=false; m_oneframe=true; }
572
573 bool init(const WindowRef& win, const jau::fraction_timespec& when) override {
574 jau::fprintf_td(when.to_ms(), stdout, "RL::init: %s\n", toString().c_str());
575 m_tlast = when;
576
577 GL& gl = GL::downcast(win->renderContext());
578
579 // setup mgl_PMVMatrix
580 PMVMat4f& pmv = m_pmvMatUni->pmv();
581 pmv.getP().loadIdentity();
582 pmv.getMv().loadIdentity();
583 m_st.ownUniform(m_pmvMatUni, true);
584
585 if( !m_renderer.init(gl, when) ) {
586 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
587 win->dispose(when);
588 return false;
589 }
590
591 GLUniformVec3fRef lightU = GLUniformVec3f::create("gcu_Light0Pos", lightPos);
592 m_st.ownUniform(lightU, true);
593 m_st.pushAllUniforms(gl);
594
595 const float lineWidth = 1/2.5f;
596 const float dz = 0.005f;
597 if( true ) {
598 // Cross / Plus
599 const float width = 1.5f;
600 const float height = 1.5f;
601
602 float lwh = lineWidth/2.0f;
603
604 float twh = width/2.0f;
605 float thh = height/2.0f;
606
607 float ctrX = 0, ctrY = 0, ctrZ = dz;
608 ShapeRef frontShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
609 m_shapes.push_back(frontShape);
610 OutlineShape& oshape = frontShape->outlines();
611 // CCW
612 oshape.moveTo(ctrX-lwh, ctrY+thh, ctrZ); // vert: left-top
613 oshape.lineTo(ctrX-lwh, ctrY+lwh, ctrZ);
614 oshape.lineTo(ctrX-twh, ctrY+lwh, ctrZ); // horz: left-top
615 oshape.lineTo(ctrX-twh, ctrY-lwh, ctrZ); // horz: left-bottom
616 oshape.lineTo(ctrX-lwh, ctrY-lwh, ctrZ);
617 oshape.lineTo(ctrX-lwh, ctrY-thh, ctrZ); // vert: left-bottom
618 oshape.lineTo(ctrX+lwh, ctrY-thh, ctrZ); // vert: right-bottom
619 oshape.lineTo(ctrX+lwh, ctrY-lwh, ctrZ);
620 oshape.lineTo(ctrX+twh, ctrY-lwh, ctrZ); // horz: right-bottom
621 oshape.lineTo(ctrX+twh, ctrY+lwh, ctrZ); // horz: right-top
622 oshape.lineTo(ctrX+lwh, ctrY+lwh, ctrZ);
623 oshape.lineTo(ctrX+lwh, ctrY+thh, ctrZ); // vert: right-top
624 oshape.lineTo(ctrX-lwh, ctrY+thh, ctrZ); // vert: left-top
625 oshape.closePath();
626 // shape1->seal(gl, true);
627 frontShape->update(gl);
628 frontShape->setColor(Vec4f(0.5f, 0.05f, 0.05f, 1));
629 frontShape->position().x = -2.0f;
630
631 ShapeRef backShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
632 m_shapes.push_back(backShape);
633 backShape->outlines() = oshape.flipFace(); // -dz);
634 backShape->outlines().clearCache();
635 backShape->update(gl);
636 backShape->setColor(Vec4f(0.2f, 0.5f, 0.2f, 1));
637 backShape->position().x = -2.0f;
638 }
639 if( true) {
640 ShapeRef frontShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
641 m_shapes.push_back(frontShape);
642 OutlineShape& oshape = frontShape->outlines();
643 // Outer boundary-shapes are required as Winding::CCW (is CCW)
644 oshape.moveTo(0.0f,-10.0f, 0);
645 oshape.lineTo(15.0f,-10.0f, 0);
646 oshape.quadTo(10.0f,5.0f,0, 15.0f,10.0f,0);
647 oshape.cubicTo(6.0f,15.0f,0, 5.0f,8.0f,0, 0.0f,10.0f,0);
648 oshape.closePath();
649 // Inner hole-shapes should be Winding::CW (is CCW and will be fixed to CW below)
650 oshape.moveTo(5.0f,-5.0f,0);
651 oshape.quadTo(10.0f,-5.0f,0, 10.0f,0.0f,0);
652 oshape.quadTo(5.0f,0.0f,0, 5.0f,-5.0f,0);
653 oshape.closePath();
654 {
655 const Winding w10 = oshape.outlines()[0].getWinding();
656 const Winding w11 = oshape.outlines()[1].getWinding();
657 oshape.outlines()[0].setWinding(Winding::CCW);
658 oshape.outlines()[1].setWinding(Winding::CW);
659 jau::PLAIN_PRINT(true, "Special.frontShape.10.winding_area: %s -> %s",
660 to_string(w10).c_str(), to_string(oshape.outlines()[0].getWinding()).c_str());
661 jau::PLAIN_PRINT(true, "Special.frontShape.11.winding_area: %s -> %s",
662 to_string(w11).c_str(), to_string(oshape.outlines()[1].getWinding()).c_str());
663 }
664
665 frontShape->update(gl);
666 frontShape->setColor(Vec4f(0.4f, 0.4f, 0.1f, 1));
667 frontShape->position().x = -1.0f;
668 frontShape->scale().x *= 0.1f;
669 frontShape->scale().y *= 0.1f;
670
671 ShapeRef backShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
672 m_shapes.push_back(backShape);
673 backShape->outlines() = oshape.flipFace(-dz); // winding preserved and is correct
674 backShape->outlines().clearCache();
675 backShape->update(gl);
676 backShape->setColor(Vec4f(0.2f, 0.2f, 0.5f, 1));
677 backShape->position().x = -1.0f;
678 backShape->scale().x *= 0.1f;
679 backShape->scale().y *= 0.1f;
680 jau::PLAIN_PRINT(true, "Special.backShape.10.winding_area: %s",
681 to_string(backShape->outlines().outlines()[0].getWinding()).c_str());
682 jau::PLAIN_PRINT(true, "Special.backShape.11.winding_area: %s",
683 to_string(backShape->outlines().outlines()[1].getWinding()).c_str());
684 }
685 if ( true ) {
686 ShapeRef frontShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
687 m_shapes.push_back(frontShape);
688 OutlineShape& oshape = frontShape->outlines();
690 frontShape->update(gl);
691 frontShape->setColor(Vec4f(0.05f, 0.05f, 0.5f, 1));
692 frontShape->position().x = 1.5f;
693 frontShape->position().y = -1.0f;
694 frontShape->scale().x *= 2.0f;
695 frontShape->scale().y *= 2.0f;
696
697 ShapeRef backShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
698 m_shapes.push_back(backShape);
699 backShape->outlines() = oshape.flipFace(-dz);
700 backShape->outlines().clearCache();
701 backShape->update(gl);
702 backShape->setColor(Vec4f(0.4f, 0.4f, 0.1f, 1));
703 backShape->position().x = 1.5f;
704 backShape->position().y = -1.0f;
705 backShape->scale().x *= 2.0f;
706 backShape->scale().y *= 2.0f;
707 }
708 if ( true ) {
709 ShapeRef frontShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
710 m_shapes.push_back(frontShape);
711 OutlineShape& oshape = frontShape->outlines();
713 frontShape->update(gl);
714 frontShape->setColor(Vec4f(0.05f, 0.5f, 0.05f, 1));
715 frontShape->position().x = 1.5f;
716 frontShape->position().y = 0.5f;
717 frontShape->scale().x *= 2.0f;
718 frontShape->scale().y *= 2.0f;
719
720 ShapeRef backShape = Shape::create(m_st, m_pmvMatUni, m_renderer);
721 m_shapes.push_back(backShape);
722 backShape->outlines() = oshape.flipFace(-dz);
723 backShape->outlines().clearCache();
724 backShape->update(gl);
725 backShape->setColor(Vec4f(0.5f, 0.1f, 0.1f, 1));
726 backShape->position().x = 1.5f;
727 backShape->position().y = 0.5f;
728 backShape->scale().x *= 2.0f;
729 backShape->scale().y *= 2.0f;
730 }
731
732 ::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
733 ::glEnable(GL_DEPTH_TEST);
734 // ::glEnable(GL_CULL_FACE);
735 ::glDisable(GL_CULL_FACE);
736
737 m_initialized = true;
738 if( !m_initialized ) {
739 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
740 m_st.destroy(gl);
741 win->dispose(when);
742 }
743 return m_initialized;
744 }
745
746 void dispose(const WindowRef& win, const jau::fraction_timespec& when) override {
747 jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", toString().c_str());
748 m_st.destroy(GL::downcast(win->renderContext()));
749 m_initialized = false;
750 }
751
752 void reshape(const WindowRef& win, const jau::math::Recti& viewport, const jau::fraction_timespec& when) override {
753 GL& gl = GL::downcast(win->renderContext());
754 jau::fprintf_td(when.to_ms(), stdout, "RL::reshape: %s\n", toString().c_str());
755 m_viewport = viewport;
756
757 PMVMat4f& pmv = m_pmvMatUni->pmv();
758 pmv.getP().loadIdentity();
759 const float aspect = 1.0f;
760 const float fovy_deg=45.0f;
761 const float aspect2 = ( (float) m_viewport.width() / (float) m_viewport.height() ) / aspect;
762 pmv.perspectiveP(jau::adeg_to_rad(fovy_deg), aspect2, zNear, zFar);
763 m_st.useProgram(gl, true);
764 m_st.pushUniform(gl, m_pmvMatUni); // automatic sync + update of Mvi + Mvit
765 // m_st.useProgram(gl, false);
766 }
767
768 void display(const WindowRef& win, const jau::fraction_timespec& when) override {
769 // jau::fprintf_td(when.to_ms(), stdout, "RL::display: %s, %s\n", toString().c_str(), win->toString().c_str());
770 if( !m_initialized ) {
771 return;
772 }
773 GL& gl = GL::downcast(win->renderContext());
774 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
775
776 m_st.useProgram(gl, true);
777 PMVMat4f& pmv = m_pmvMatUni->pmv();
778 pmv.getMv().loadIdentity();
779 pmv.translateMv(0, 0, -5);
780
781 for(const ShapeRef& s : m_shapes) {
782 if( animating() || m_oneframe ) {
783 constexpr double angle_per_sec = 30;
784 const float rad = (float) ( (when - m_tlast).to_double() * angle_per_sec );
785 s->rotation().rotateByAngleY(jau::adeg_to_rad( rad ));
786 }
787 s->draw(gl);
788 }
789
790 m_oneframe = false;
791 // m_st.useProgram(gl, false);
792
793 m_tlast = when;
794 }
795
796 std::string toStringImpl() const noexcept override { return "GraphShapes01"; }
797};
798
799class Example : public GraphShapes01 {
800 private:
801 class MyKeyListener : public KeyListener {
802 private:
803 GraphShapes01& m_parent;
804 public:
805 MyKeyListener(GraphShapes01& p) : m_parent(p) {}
806
807 void keyPressed(KeyEvent& e, const KeyboardTracker& kt) override {
808 jau::fprintf_td(e.when().to_ms(), stdout, "KeyPressed: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
809 if( e.keySym() == VKeyCode::VK_ESCAPE ) {
810 WindowRef win = e.source().lock();
811 if( win ) {
812 win->dispose(e.when());
813 }
814 } else if( e.keySym() == VKeyCode::VK_PAUSE || e.keySym() == VKeyCode::VK_P ) {
815 m_parent.animating() = !m_parent.animating();
816 } else if( e.keySym() == VKeyCode::VK_PERIOD ) {
817 m_parent.setOneFrame();
818 } else if( e.keySym() == VKeyCode::VK_W ) {
819 WindowRef win = e.source().lock();
820 jau::fprintf_td(e.when().to_ms(), stdout, "Source: %s\n", win ? win->toString().c_str() : "null");
821 }
822 }
823 void keyReleased(KeyEvent& e, const KeyboardTracker& kt) override {
824 jau::fprintf_td(e.when().to_ms(), stdout, "KeyRelease: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
825 }
826 };
827 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
828 MyKeyListenerRef m_kl;
829
830 public:
832 : GraphShapes01(),
833 m_kl(std::make_shared<MyKeyListener>(*this)) { }
834
835 bool init(const WindowRef& win, const jau::fraction_timespec& when) override {
836 if( !GraphShapes01::init(win, when) ) {
837 return false;
838 }
839 win->addKeyListener(m_kl);
840 return true;
841 }
842 void dispose(const WindowRef& win, const jau::fraction_timespec& when) override {
843 win->removeKeyListener(m_kl);
844 GraphShapes01::dispose(win, when);
845 }
846};
847
848int main(int argc, char *argv[]) // NOLINT(bugprone-exception-escape)
849{
850 return launch("GraphShapes01.cpp",
852 .contextFlags=gamp::render::RenderContextFlags::verbose}, // | gamp::render::RenderContextFlags::debug},
853 std::make_shared<Example>(), argc, argv);
854}
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerRef &demo, int argc, char *argv[])
int main(int argc, char *argv[])
std::shared_ptr< Shape > ShapeRef
std::shared_ptr< Shape > ShapeRef
#define E_FILE_LINE
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
constexpr bool initialized() const noexcept
void draw(GL &gl)
void addOutlineShape(OutlineShape &shape)
void pushVertex(const Vertex &v, const Vec3f &normal)
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void pushNewVerticesIdx(const Vertex &vertIn1, const Vertex &vertIn2, const Vertex &vertIn3, const Vec3f &normal)
GraphRegion(GraphRenderer &renderer, ShaderState &st)
void pushIndices(uint32_t i, uint32_t j, uint32_t k)
void seal(GL &gl, bool seal_)
static constexpr std::string_view GLSL_USE_LIGHT0
bool init(GL &gl, const jau::fraction_timespec &when)
static constexpr std::string_view GLSL_MAIN_BEGIN
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view GLSL_PARAM_COMMENT_START
static constexpr std::string_view GLSL_USE_DISCARD
static constexpr std::string_view colTexLookupFuncName
static constexpr std::string_view bin_dir
static constexpr std::string_view GLSL_PARAM_COMMENT_END
constexpr GLsizei arrayCompsPerElement() const noexcept
constexpr bool initialized() const noexcept
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
constexpr bool usesNormal() const noexcept
static constexpr std::string_view source_dir
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
GraphRenderer(ShaderState &st)
static constexpr std::string_view shader_basename
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
void setOneFrame() noexcept
bool animating() const noexcept
std::string toStringImpl() const noexcept override
void reshape(const WindowRef &win, const jau::math::Recti &viewport, const jau::fraction_timespec &when) override
Called by the drawable during the first repaint after the component has been resized.
const PMVMat4f & pmv() const noexcept
void display(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
PMVMat4f & pmv() noexcept
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
bool & animating() noexcept
Recti & viewport() noexcept
const Recti & viewport() const noexcept
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
constexpr Vec3f & position() noexcept
void draw(GL &gl)
void update(GL &gl)
constexpr OutlineShape & outlines() noexcept
constexpr const Quat4f & rotation() const noexcept
static ShapeRef create(ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr const Vec3f & rotationPivot() const noexcept
constexpr float & zOffset() noexcept
constexpr const Vec3f & position() const noexcept
constexpr Vec3f & scale() noexcept
constexpr Vec3f & rotationPivot() noexcept
const Vec4f & color() const noexcept
constexpr const Vec3f & scale() const noexcept
constexpr const OutlineShape & outlines() const noexcept
Shape(Private, ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr Quat4f & rotation() noexcept
static bool DEBUG_MODE
Definition Graph.hpp:24
A Generic shape objects which is defined by a list of Outlines.
constexpr size_type addedVertexCount() const noexcept
Return the number of newly added vertices during getTriangles(VerticesState) while transforming the o...
const VertexList & getVertices()
Return list of concatenated vertices associated with all Outlines of this object.
void clearCache() noexcept
Clears cached triangulated data, i.e.
void cubicTo(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
const OutlineList & outlines() const noexcept
void quadTo(float x1, float y1, float z1, float x2, float y2, float z2)
Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
constexpr const Vec3f & normal() const noexcept
Normal vector, optionally used by tesselator to add (interleaved) normals.
void moveTo(float x, float y, float z)
Start a new position for the next line segment at given point x/y (P1).
void closePath()
Closes the current sub-path segment by drawing a straight line back to the coordinates of the last mo...
const TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
OutlineShape flipFace(float zoffset=0) const
Returns a copy of this instance with normal() and all outlines() vertices()'s z-axis sign-flipped,...
void lineTo(float x, float y, float z)
Add a line segment, intersecting the last point and the given point x/y (P1).
std::array< Vertex, 3 > trivert_t
constexpr const trivert_t & vertices() const noexcept
Returns array of 3 vertices, denominating the triangle.
constexpr const Vec3f & texCoord() const noexcept
Definition PrimTypes.hpp:96
constexpr const Vec3f & coord() const noexcept
Definition PrimTypes.hpp:93
static GLContext & downcast(RenderContext *rc)
Downcast dereferenced given RenderContext* to GLContext&, throws exception if signature doesn't match...
Specifies the OpenGL profile.
Definition GLContext.hpp:42
static constexpr std::string_view GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition GLContext.hpp:65
static std::shared_ptr< GLUniformVec3f > create(stringview_t name, const jau::math::Vec3f &v)
static std::shared_ptr< GLUniformVec4f > create(stringview_t name, const jau::math::Vec4f &v)
size_t replaceInShaderSource(const string_t &oldName, const string_t &newName) noexcept
Replaces oldName with newName in all shader sources.
size_t defaultShaderCustomization(const GL &gl, bool preludeVersion=true, bool addDefaultPrecision=true, bool addDefaultDefines=true)
Default customization of this shader source code.
static ShaderCodeRef create(GLenum type, size_t count, const source_list_t &sources) noexcept
size_t insertShaderSourceFile(size_t shaderIdx, size_t position, const string_t &path) noexcept
Adds shader source located in path, either relative to the location or absolute as-is at position in ...
size_t insertShaderSource(size_t shaderIdx, stringview_t tag, size_t fromIndex, stringview_t data) noexcept
Adds data after the line containing tag.
void destroy(GL &gl) noexcept
Detaches all shader codes and deletes the program.
static ShaderProgramRef create() noexcept
bool add(const ShaderCodeRef &shaderCode) noexcept
Adds a new shader to this program.
constexpr bool inUse() const noexcept
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
constexpr RenderListener(Private) noexcept
Private ctor for shared_ptr<RenderListener> instance method w/o public ctor.
Definition Window.hpp:60
std::string toString() const noexcept
Definition Window.hpp:112
const gamp::render::RenderContext * renderContext() const noexcept
Definition Surface.hpp:129
size_t removeKeyListener(const KeyListenerRef &l)
Definition Window.hpp:311
void dispose(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:355
std::string toString() const noexcept
Definition gamp_wt.cpp:145
void addKeyListener(const KeyListenerRef &l)
Definition Window.hpp:310
std::string toString() const noexcept
Definition KeyEvent.hpp:855
constexpr VKeyCode keySym() const noexcept
Returns the virtual key symbol reflecting the current keyboard layout.
Definition KeyEvent.hpp:798
virtual const PressedKeyCodes & pressedKeyCodes() const noexcept=0
constexpr const WindowWeakPtr & source() const noexcept
Definition Event.hpp:85
constexpr const jau::fraction_timespec & when() const noexcept
Definition Event.hpp:84
size_type count() const noexcept
Definition bitfield.hpp:359
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
Definition darray.hpp:154
constexpr size_type size() const noexcept
Like std::vector::size().
Definition darray.hpp:1115
value_type x
Definition vec3f.hpp:66
value_type y
Definition vec3f.hpp:67
static constexpr const value_type one
Definition vec3f.hpp:64
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
Definition pmvmat4.hpp:795
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
Definition pmvmat4.hpp:813
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
GLArrayDataServer< float > GLFloatArrayDataServer
GLsizeiptr glmemsize_t
Compatible with ssize_t.
Definition GLBuffers.hpp:26
std::shared_ptr< GLUniformSyncPMVMat4f > GLUniformSyncPMVMat4fRef
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
GLArrayDataServerRef< uint32_t > GLUIntArrayDataServerRef
std::shared_ptr< GLUniformVec3f > GLUniformVec3fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
jau::darray< Vertex, uint32_t > VertexList
std::shared_ptr< Triangle > TriangleRef
jau::darray< TriangleRef, uint32_t > TriangleRefList
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowRef
Definition Event.hpp:36
Matrix4< float > Mat4f
Definition mat4f.hpp:1968
Vector4F< float > Vec4f
Definition vec4f.hpp:360
PMVData
PMVMatrix4 derived matrices and values.
Definition pmvmat4.hpp:57
Quaternion< float > Quat4f
RectI< int > Recti
Definition recti.hpp:146
Vector3F< float > Vec3f
Definition vec3f.hpp:422
std::string to_string(const math_error_t v) noexcept
Returns std::string representation of math_error_t.
PMVMatrix4< float > PMVMat4f
Definition pmvmat4.hpp:1463
@ inv_mv
Bit value for inverse modelview matrix (Mvi), updated via update().
Definition pmvmat4.hpp:60
@ inv_proj
Bit value for inverse projection matrix (Pi), updated via update().
Definition pmvmat4.hpp:64
@ inv_tps_mv
Bit value for inverse transposed modelview matrix (Mvit), updated via update().
Definition pmvmat4.hpp:62
@ CCW
Counter-Clockwise.
Definition geom.hpp:39
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
Definition PTS.hpp:24
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition debug.cpp:264
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
Definition debug.cpp:276
STL namespace.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
constexpr uint64_t to_ms() const noexcept
Returns time in milliseconds.