Gamp v0.0.8
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GraphRegion.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_GRAPH_REGION_HPP_
13#define GAMP_GRAPH_REGION_HPP_
14
15#include <cstdio>
16#include <cmath>
17#include <gamp/graph/Graph.hpp>
21#include <memory>
22#include <string>
23#include <string_view>
24#include <vector>
25
26#include <jau/basic_types.hpp>
27#include <jau/cpp_lang_util.hpp>
28#include <jau/darray.hpp>
29#include <jau/debug.hpp>
30#include <jau/float_math.hpp>
31#include <jau/float_types.hpp>
32#include <jau/fraction_type.hpp>
33#include <jau/io/file_util.hpp>
35#include <jau/math/vec3f.hpp>
36#include <jau/math/vec4f.hpp>
37#include <jau/math/vec4f.hpp>
42
43#include <gamp/Gamp.hpp>
48
50
51using namespace jau::math;
52using namespace jau::math::util;
53using namespace jau::math::geom;
54
55using namespace gamp;
56using namespace gamp::wt;
57using namespace gamp::wt::event;
58
59using namespace gamp::graph;
60using namespace gamp::render::gl::glsl;
61using namespace gamp::render::gl::data;
62
64 bool m_isTwoPass:1 = false;
65 bool m_pass1:1 = true;
66 bool m_hasFrustumClipping:1 = false;
67 bool m_hasNormalChannel:1 = false;
68 bool m_hasLight0:1 = true;
69 bool m_hasColorChannel:1 = false;
70 bool m_hasColorTexture:1 = false;
71 bool m_hasDiscard:1 = true;
72};
73
74class GraphRenderer {
75 public:
76 private:
77 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
78 constexpr static jau::math::Vec3f lightPos = jau::math::Vec3f(2.0f, 2.0f, 5.0f);
79 GraphRendererProps m_props;
80 ShaderState& m_st;
81 PMVMat4f& m_pmvMat;
82 GLUniformVec3f m_light0Pos;
83 GLUniformVec4f m_staticColor;
84 bool m_initialized;
85
86 public:
87 constexpr bool usesNormal() const noexcept { return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
88 constexpr GLsizei arrayCompsPerElement() const noexcept { return usesNormal()? 3*3 : 2*3; }
89
90 static constexpr std::string_view GLSL_PARAM_COMMENT_START = "\n// Gamp Graph Parameter Start\n";
91 static constexpr std::string_view GLSL_PARAM_COMMENT_END = "// Gamp Graph Parameter End\n\n";
92 static constexpr std::string_view GLSL_USE_COLOR_CHANNEL = "#define USE_COLOR_CHANNEL 1\n";
93 static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL = "#define USE_NORMAL_CHANNEL 1\n";
94 static constexpr std::string_view GLSL_USE_LIGHT0 = "#define USE_LIGHT0 1\n";
95 static constexpr std::string_view GLSL_USE_COLOR_TEXTURE = "#define USE_COLOR_TEXTURE 1\n";
96 static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING = "#define USE_FRUSTUM_CLIPPING 1\n";
97 static constexpr std::string_view GLSL_USE_DISCARD = "#define USE_DISCARD 1\n";
98 static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT = "#define SAMPLE_COUNT ";
99 static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT = "const float sample_count = ";
100 static constexpr std::string_view GLSL_MAIN_BEGIN = "void main (void)\n{\n";
101 static constexpr std::string_view gcuTexture2D = "gcuTexture2D";
102 static constexpr std::string_view colTexLookupFuncName = "texture2D";
103 static constexpr std::string_view shader_basename = "curverenderer01";
104 static constexpr std::string_view source_dir = "impl/graph/glsl";
105 static constexpr std::string_view bin_dir = "impl/graph/glsl/bin";
106
107 public:
109 : m_st(st),
110 m_pmvMat(pmvMat),
111 m_light0Pos("gcu_Light0Pos", lightPos),
112 m_staticColor("gcu_StaticColor", Vec4f(0, 0, 0, 1)),
113 m_initialized(false)
114 {
115 m_st.manage(m_light0Pos);
116 m_st.manage(m_staticColor);
117 }
118
119 constexpr bool initialized() const noexcept { return m_initialized; }
120
121 bool init(GL& gl, const jau::fraction_timespec& when) {
123 // ShaderState::VERBOSE_STATE = true;
124
125 std::string vertexShaderName, fragmentShaderName;
126 vertexShaderName.append(shader_basename);
127 if( m_props.m_isTwoPass ) {
128 vertexShaderName.append("-pass").append(m_props.m_pass1 ? "1":"2");
129 } else {
130 vertexShaderName.append("-single");
131 }
132 fragmentShaderName.append(shader_basename).append("-segment-head");
133
134 ShaderCodeSRef rsVp = ShaderCode::create(gl, GL_VERTEX_SHADER, source_dir, bin_dir, vertexShaderName);
135 ShaderCodeSRef rsFp = ShaderCode::create(gl, GL_FRAGMENT_SHADER, source_dir, bin_dir, fragmentShaderName);
136 if( !rsVp || !rsFp ) {
137 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
138 return false;
139 }
140 {
141 size_t posVp = rsVp->defaultShaderCustomization(gl);
142 size_t posFp = rsFp->defaultShaderCustomization(gl);
143 if( posVp == std::string::npos || posFp == std::string::npos ) {
144 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
145 return false;
146 }
147
148 // GLSL append from here on
149 posFp = -1;
150
151 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_START);
152 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_START);
153
154 // if( !gl.getContext().hasRendererQuirk(GLRendererQuirks.GLSLBuggyDiscard) ) {
155 if( m_props.m_hasDiscard ) {
156 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_DISCARD);
157 }
158
159 if( m_props.m_hasFrustumClipping ) {
160 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_FRUSTUM_CLIPPING);
161 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_FRUSTUM_CLIPPING);
162 }
163
164 if( usesNormal() ) {
165 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_NORMAL_CHANNEL);
166 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_NORMAL_CHANNEL);
167 }
168 if( m_props.m_hasLight0 ) {
169 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_LIGHT0);
170 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_LIGHT0);
171 }
172 if( m_props.m_hasColorChannel ) {
173 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_COLOR_CHANNEL);
174 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_CHANNEL);
175 }
176 if( m_props.m_hasColorTexture ) {
178 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_TEXTURE);
179 }
180 /*if( !pass1 ) {
181 posFp = rsFp->insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+sms.sampleCount+"\n");
182 posFp = rsFp->insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+sms.sampleCount+".0;\n");
183 } */
184
185 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_END);
186 if( posVp == std::string::npos ) {
187 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
188 return false;
189 }
190
191 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_END);
192
193 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/constants.glsl"));
194 if( posFp == std::string::npos ) {
195 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
196 return false;
197 }
198 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/uniforms.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 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/varyings.glsl"));
204 if( posFp == std::string::npos ) {
205 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
206 return false;
207 }
208 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
209 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/functions.glsl"));
210 if( posFp == std::string::npos ) {
211 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
212 return false;
213 }
214 }
215 /*if( hasColorTexture ) {
216 posFp = rsFp->insertShaderSource(0, posFp, "uniform "+colorTexSeq.getTextureSampler2DType()+" "+UniformNames.gcu_ColorTexUnit+";\n");
217 posFp = rsFp->insertShaderSource(0, posFp, colorTexSeq.getTextureLookupFragmentShaderImpl());
218 }*/
219
220 posFp = rsFp->insertShaderSource(0, posFp, GLSL_MAIN_BEGIN);
221
222 std::string passS = m_props.m_pass1 ? "-pass1-" : "-pass2-";
223 std::string shaderSegment = string_t(source_dir).append("/").append(shader_basename).append(passS).append("curve_simple").append(".glsl"); // sms.tech+sms.sub+".glsl";
225 jau_PLAIN_PRINT(true, "RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
226 }
227 posFp = rsFp->insertShaderSourceFile(0, posFp, shaderSegment);
228 if( posFp == std::string::npos ) {
229 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
230 return false;
231 }
232 posFp = rsFp->insertShaderSource(0, posFp, "}\n");
233 if( posFp == std::string::npos ) {
234 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
235 return false;
236 }
237
238 if( m_props.m_hasColorTexture ) {
239 rsFp->replaceInShaderSource(std::string(gcuTexture2D), std::string(colTexLookupFuncName));
240 }
241
242 }
244 if( !sp0->add(gl, rsVp, true) || !sp0->add(gl, rsFp, true) ) {
245 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
246 sp0->destroy(gl);
247 return false;
248 }
249 m_st.attachShaderProgram(gl, sp0, true);
250
251 m_st.send(gl, m_light0Pos);
252 m_st.send(gl, m_staticColor);
253
254 m_initialized = sp0->inUse();
255 if( !m_initialized ) {
256 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
257 m_st.destroy(gl);
258 }
259 return m_initialized;
260 }
261
262 void destroy(GL& gl) {
263 m_st.destroyShaderProgram(gl);
264 }
265
266 void useProgram(GL& gl, bool on) {
267 m_st.useProgram(gl, on);
268 }
269
271 m_st.send(gl, m_staticColor);
272 }
273 void updateAll(GL& gl) {
274 m_st.send(gl, m_staticColor);
275 }
276 PMVMat4f& pmv() noexcept { return m_pmvMat; }
277 const PMVMat4f& pmv() const noexcept { return m_pmvMat; }
278 const Vec4f& color() const noexcept { return m_staticColor.vec4f(); }
279 void setColor(const Vec4f& c) noexcept { m_staticColor.vec4f()=c; }
280 ShaderState& st() noexcept { return m_st; }
281 const ShaderState& st() const noexcept { return m_st; }
282};
283
284class GraphRegion {
285 public:
287 private:
288 GraphRenderer& m_renderer;
289 bool m_initialized;
292 int m_num_vertices, m_num_indices;
293
294 public:
296 : m_renderer(renderer),
297 m_initialized(m_renderer.initialized()),
298 m_array(GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
299 m_indices(GLUIntArrayDataServer::createData(3, 256, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER)),
300 m_num_vertices(0), m_num_indices(0)
301 {
302 m_array->addGLSLSubArray("gca_Vertex", 3, GL_ARRAY_BUFFER);
303 m_array->addGLSLSubArray("gca_CurveParam", 3, GL_ARRAY_BUFFER);
304 if( m_renderer.usesNormal() ) {
305 m_array->addGLSLSubArray("gca_Normal", 3, GL_ARRAY_BUFFER);
306 }
307 m_renderer.st().manage(m_array);
308 // m_st.manage(m_indices);
309 }
310
311 constexpr bool initialized() const noexcept { return m_initialized; }
312
313 void destroy(GL& gl) {
314 m_renderer.st().destroyAllData(gl);
315 // m_array->destroy(gl); // owned by m_st
316 m_indices->destroy(gl);
317 m_num_vertices = 0;
318 m_num_indices = 0;
319 }
320
321 void seal(GL& gl, bool seal_) {
322 if( !m_initialized ) {
323 return;
324 }
325 m_array->seal(gl, seal_);
326 m_indices->seal(gl, seal_);
327 m_array->enableBuffer(gl, false);
328 m_indices->enableBuffer(gl, false);
329 }
330
331 private:
332 void pushVertex(const Vertex& v, const Vec3f& normal) {
333 // jau::PLAIN_PRINT(true, "pushVertex.0[%d]: v %s]", m_num_vertices, v.toString().c_str());
334 m_array->put3f(v.coord());
335 m_array->put3f(v.texCoord());
336 if( m_renderer.usesNormal() ) {
337 m_array->put3f(normal);
338 }
339 ++m_num_vertices;
340 }
341 void pushIndices(uint32_t i, uint32_t j, uint32_t k) {
342 // jau::PLAIN_PRINT(true, "pushIndices.0[%d]: %u, %u, %u]", m_num_indices, i, j, k);
343 m_indices->putN(i, j, k);
344 m_num_indices += 3;
345 }
346 void pushNewVerticesIdx(const Vertex& vertIn1, const Vertex& vertIn2, const Vertex& vertIn3, const Vec3f& normal) {
347 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
348 pushVertex(vertIn1, normal);
349 pushVertex(vertIn2, normal);
350 pushVertex(vertIn3, normal);
351 }
352
353 public:
355 if( !m_initialized ) {
356 return;
357 }
358 if( Graph::DEBUG_MODE ) {
359 jau_PLAIN_PRINT(true, "add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
360 jau_PLAIN_PRINT(true, "add.0 array: %s", m_array->toString().c_str());
361 jau_PLAIN_PRINT(true, "add.0 indices: %s", m_indices->toString().c_str());
362 }
363 const TriangleRefList& trisIn = shape.getTriangles();
364 const VertexList& vertsIn = shape.getVertices();
365 if( Graph::DEBUG_MODE ) {
366 jau_PLAIN_PRINT(true, "add.0 triangles %u, vertices %u", trisIn.size(), vertsIn.size());
367 }
368 {
369 glmemsize_t verticeCount = (glmemsize_t)vertsIn.size() + shape.addedVertexCount();
370 glmemsize_t indexCount = (glmemsize_t)trisIn.size() * 3;
371 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
372 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
373 }
374 uint32_t idxOffset = m_num_vertices;
375 if( vertsIn.size() >= 3 ) {
376 //
377 // Processing Vertices
378 //
379 for(const Vertex& v : vertsIn) {
380 pushVertex(v, shape.normal());
381 }
382 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() / sizeof(uint32_t);
383 OutlineShape::size_type trisIn_sz = trisIn.size();
384 for(OutlineShape::size_type i=0; i < trisIn_sz; ++i) {
385 const TriangleRef& triIn = trisIn[i];
386 // triEx.addVertexIndicesOffset(idxOffset);
387 // triangles.add( triEx );
388 Triangle::trivert_t& triInVertices = triIn->vertices();
389 uint32_t tv0Idx = triInVertices[0].id();
390 if ( max_index - idxOffset > tv0Idx ) {
391 // valid 'known' idx - move by offset
392 pushIndices(tv0Idx+idxOffset,
393 triInVertices[1].id()+idxOffset,
394 triInVertices[2].id()+idxOffset);
395 } else {
396 // FIXME: If exceeding max_indices, we would need to generate a new buffer w/ indices
397 pushNewVerticesIdx(triInVertices[0], triInVertices[1], triInVertices[2], shape.normal());
398 }
399 }
400 }
401 if( Graph::DEBUG_MODE ) {
402 jau_PLAIN_PRINT(true, "add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
403 jau_PLAIN_PRINT(true, "add.x array: %s", m_array->toString().c_str());
404 jau_PLAIN_PRINT(true, "add.x indices: %s", m_indices->toString().c_str());
405 }
406 }
407
408 void draw(GL &gl) {
409 if( !m_initialized ) {
410 return;
411 }
412 m_renderer.useProgram(gl, true);
413
414 m_array->enableBuffer(gl, true);
415 m_indices->bindBuffer(gl, true); // keeps VBO binding
416
417 ::glEnable(GL_BLEND);
418 ::glBlendEquation(GL_FUNC_ADD); // default
419 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
420
421 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT, nullptr);
422
423 m_indices->bindBuffer(gl, false);
424 m_array->enableBuffer(gl, false);
425 // m_renderer.useProgram(gl, false);
426 }
427};
428
429class Shape;
430typedef std::shared_ptr<Shape> ShapeRef;
431
432class Shape {
433 private:
434 std::vector<OutlineShape> m_oshapes;
435
436 Vec3f m_position;
437 Quat4f m_rotation;
438 Vec3f m_rotPivot;
439 Vec3f m_scale = Vec3f(1, 1, 1);
440 float m_zOffset = 0.0f;
441 Vec4f m_color = Vec4f(0, 0, 0, 1);
442 GraphRenderer& m_renderer;
443 GraphRegion m_region;
444
445 Mat4f iMat;
446 Mat4f tmpMat;
447 bool iMatIdent = true;
448 bool iMatDirty = false;
449
450 float m_velo = 0; // m/s
451
452 struct Private{ explicit Private() = default; };
453
454 public:
455 Shape(Private, GraphRenderer &renderer)
456 : m_renderer(renderer), m_region(m_renderer)
457 {
458 std::cerr << "XXX ctor.x " << m_renderer.st() << "\n";
459 }
460
462 return std::make_shared<Shape>(Private(), renderer);
463 }
464
465 void destroy(GL& gl) {
466 m_region.destroy(gl);
467 }
468
469 constexpr const Vec3f& position() const noexcept { return m_position; }
470 constexpr Vec3f& position() noexcept { iMatDirty=true; return m_position; }
471 constexpr void set_position(Vec3f new_pos) noexcept { m_position = new_pos; }
472
473 constexpr const float& zOffset() const noexcept { return m_zOffset; }
474 constexpr float& zOffset() noexcept { iMatDirty=true; return m_zOffset; }
475
476 constexpr const Quat4f& rotation() const noexcept { return m_rotation; }
477 constexpr Quat4f& rotation() noexcept { iMatDirty=true; return m_rotation; }
478
479 constexpr const Vec3f& rotationPivot() const noexcept { return m_rotPivot; }
480 constexpr Vec3f& rotationPivot() noexcept { iMatDirty=true; return m_rotPivot; }
481
482 constexpr const Vec3f& scale() const noexcept { return m_scale; }
483 constexpr Vec3f& scale() noexcept { iMatDirty=true; return m_scale; }
484
485 constexpr const std::vector<OutlineShape>& outlineShapes() const noexcept { return m_oshapes; }
486 constexpr std::vector<OutlineShape>& outlineShapes() noexcept { return m_oshapes; }
487
488 const Vec4f& color() const noexcept { return m_color; }
489 void setColor(const Vec4f& c) noexcept { m_color = c; }
490
491 void update(GL& gl) {
492 for(OutlineShape& o : m_oshapes){
493 m_region.addOutlineShape(o);
494 }
495 m_region.seal(gl, true);
496 }
497
498 void draw(GL &gl) {
499 PMVMat4f& pmv = m_renderer.pmv();
500 pmv.pushMv();
501 applyMatToMv(pmv);
502
503 m_renderer.setColor(m_color);
504 m_renderer.updateAll(gl); // PMV + Color
505
506 m_region.draw(gl);
507 pmv.popMv();
508 }
509
510 /// Game ..
511 void tick(float dt) {
512 if( !jau::is_zero(m_velo) ) {
513 iMatDirty = true;
514 m_rotation.rotateByAngleZ( M_PI_2);
515 Vec3f dir = m_rotation.rotateVector(Vec3f(1, 0, 0));
516 m_rotation.rotateByAngleZ(-M_PI_2);
517 Vec3f d_p = dir * m_velo * dt;
518
519 m_position += d_p;
520 }
521 }
522 float& velo() noexcept { return m_velo; }
523
524 private:
525 /**
526 * Applies the internal {@link Matrix4f} to the given {@link PMVMatrix4f#getMv() modelview matrix},
527 * i.e. {@code pmv.mulMv( getMat() )}.
528 * <p>
529 * Calls {@link #updateMat()} if dirty.
530 * </p>
531 * In case {@link #isMatIdentity()} is {@code true}, implementation is a no-operation.
532 * </p>
533 * @param pmv the matrix
534 * @see #isMatIdentity()
535 * @see #updateMat()
536 * @see #getMat()
537 * @see PMVMatrix4f#mulMv(Matrix4f)
538 */
539 void applyMatToMv(PMVMat4f& pmvMat) noexcept {
540 if( iMatDirty ) {
541 updateMat();
542 }
543 if( !iMatIdent ) {
544 pmvMat.mulMv(iMat);
545 }
546 }
547 void updateMat() noexcept {
548 bool hasPos = !m_position.is_zero();
549 bool hasScale = m_scale != Vec3f::one;
550 bool hasRotate = !m_rotation.isIdentity();
551 bool hasRotPivot = false; // null != rotPivot;
552 for(OutlineShape& o : m_oshapes){
553 const Vec3f& ctr = o.bounds().center();
554 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
555
556 if( sameScaleRotatePivot ) {
557 iMatIdent = false;
558 iMat.setToTranslation(m_position); // identity + translate, scaled
559 // Scale shape from its center position and rotate around its center
560 iMat.translate(Vec3f(ctr).mul(m_scale)); // add-back center, scaled
561 iMat.rotate(m_rotation);
562 iMat.scale(m_scale);
563 iMat.translate(-ctr); // move to center
564 } else if( hasRotate || hasScale ) {
565 iMatIdent = false;
566 iMat.setToTranslation(m_position); // identity + translate, scaled
567 if( hasRotate ) {
568 if( hasRotPivot ) {
569 // Rotate shape around its scaled pivot
570 iMat.translate(Vec3f(m_rotPivot).mul(m_scale)); // pivot back from rot-pivot, scaled
571 iMat.rotate(m_rotation);
572 iMat.translate(Vec3f(-m_rotPivot).mul(m_scale)); // pivot to rot-pivot, scaled
573 } else {
574 // Rotate shape around its scaled center
575 iMat.translate(Vec3f(ctr).mul(m_scale)); // pivot back from center-pivot, scaled
576 iMat.rotate(m_rotation);
577 iMat.translate(Vec3f(-ctr).mul(m_scale)); // pivot to center-pivot, scaled
578 }
579 }
580 if( hasScale ) {
581 // Scale shape from its center position
582 iMat.translate(Vec3f(ctr).mul(m_scale)); // add-back center, scaled
583 iMat.scale(m_scale);
584 iMat.translate(Vec3f(-ctr).mul(m_scale)); // move to center
585 }
586 } else if( hasPos ) {
587 iMatIdent = false;
588 iMat.setToTranslation(m_position); // identity + translate, scaled
589
590 } else {
591 iMatIdent = true;
592 iMat.loadIdentity();
593 }
594 iMatDirty = false;
595 }
596 }
597};
598
599#endif // GAMP_GRAPH_REGION_HPP_
std::shared_ptr< Shape > ShapeRef
void destroy(GL &gl)
constexpr bool initialized() const noexcept
void draw(GL &gl)
void addOutlineShape(OutlineShape &shape)
GraphRegion(GraphRenderer &renderer)
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void seal(GL &gl, bool seal_)
void destroy(GL &gl)
static constexpr std::string_view GLSL_USE_LIGHT0
ShaderState & st() noexcept
bool init(GL &gl, const jau::fraction_timespec &when)
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_USE_DISCARD
const PMVMat4f & pmv() const noexcept
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view source_dir
static constexpr std::string_view GLSL_PARAM_COMMENT_END
constexpr GLsizei arrayCompsPerElement() const noexcept
const Vec4f & color() const noexcept
constexpr bool initialized() const noexcept
static constexpr std::string_view shader_basename
static constexpr std::string_view bin_dir
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view GLSL_MAIN_BEGIN
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
constexpr bool usesNormal() const noexcept
const ShaderState & st() const noexcept
void updateAll(GL &gl)
void updateColor(GL &gl)
PMVMat4f & pmv() noexcept
static constexpr std::string_view colTexLookupFuncName
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_PARAM_COMMENT_START
GraphRenderer(PMVMat4f &pmvMat, ShaderState &st)
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
void setColor(const Vec4f &c) noexcept
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
void tick(float dt)
Game ..
Shape(Private, GraphRenderer &renderer)
constexpr Vec3f & position() noexcept
constexpr std::vector< OutlineShape > & outlineShapes() noexcept
void draw(GL &gl)
void update(GL &gl)
float & velo() noexcept
constexpr const std::vector< OutlineShape > & outlineShapes() const noexcept
constexpr const Quat4f & rotation() const noexcept
constexpr void set_position(Vec3f new_pos) noexcept
void destroy(GL &gl)
constexpr const Vec3f & rotationPivot() const noexcept
constexpr float & zOffset() noexcept
constexpr const Vec3f & position() const noexcept
constexpr Vec3f & scale() noexcept
constexpr Vec3f & rotationPivot() noexcept
static ShapeRef createShared(GraphRenderer &renderer)
const Vec4f & color() const noexcept
constexpr const Vec3f & scale() const noexcept
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.
constexpr const Vec3f & normal() const noexcept
Normal vector, optionally used by tesselator to add (interleaved) normals.
const TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
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
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 ShaderCodeSRef create(GLenum type, size_t count, const source_list_t &sources)
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.
static ShaderProgramSRef create() noexcept
void destroy(GL &gl) noexcept
Detaches all shader codes and deletes the program.
bool add(const ShaderCodeSRef &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 ...
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:1116
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
#define jau_PLAIN_PRINT(printPrefix, fmt,...)
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition debug.hpp:171
std::shared_ptr< Shape > ShapeRef
#define E_FILE_LINE
constexpr bool is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
GLArrayDataServer< float > GLFloatArrayDataServer
GLArrayDataServerSRef< float > GLFloatArrayDataServerSRef
GLsizeiptr glmemsize_t
Compatible with ssize_t.
Definition GLBuffers.hpp:26
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
GLArrayDataServerSRef< uint32_t > GLUIntArrayDataServerSRef
std::shared_ptr< ShaderCode > ShaderCodeSRef
std::shared_ptr< ShaderProgram > ShaderProgramSRef
jau::darray< Vertex, uint32_t > VertexList
std::shared_ptr< Triangle > TriangleRef
jau::darray< TriangleRef, uint32_t > TriangleRefList
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
Vector3F< float > Vec3f
Definition vec3f.hpp:422
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
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
Definition PTS.hpp:24
ssize_t fprintf_td(const uint64_t elapsed_ms, FILE *stream, std::string_view format, const Args &...args) noexcept
Convenient secure fprintf() invocation, prepending the given elapsed_ms timestamp and using jau:forma...
Definition debug.hpp:188
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.