Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GearsES2.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_DEMOS_GEARSES02_HPP_
13#define GAMP_DEMOS_GEARSES02_HPP_
14
15#include <cmath>
16#include <cstdio>
17#include <memory>
18#include <numbers>
19
20#include <gamp/GampTypes.hpp>
29
30#include <jau/basic_types.hpp>
31#include <jau/debug.hpp>
32#include <jau/float_math.hpp>
33#include <jau/functional.hpp>
34#include <jau/math/mat4f.hpp>
35#include <jau/math/vec2f.hpp>
36#include <jau/math/vec3f.hpp>
39
40using namespace jau::math;
41using namespace jau::math::util;
42
43using namespace gamp::wt;
44using namespace gamp::wt::event;
45using namespace gamp::render::gl::glsl;
46using namespace gamp::render::gl::data;
47
48class GearsObjectES2;
49typedef jau::function<bool(const PointerEvent& e, const WindowRef& win, GearsObjectES2& shape)> PointerShapeAction;
50
51/**
52 * GearsObjectES2
53 * @author Brian Paul (converted to C++ and added pixel-lightning by Sven Gothel)
54 */
56 public:
57 constexpr static jau::math::Vec4f red = jau::math::Vec4f(0.8f, 0.1f, 0.0f, 0.7f);
58 constexpr static jau::math::Vec4f green = jau::math::Vec4f(0.0f, 0.8f, 0.2f, 0.7f);
59 constexpr static jau::math::Vec4f blue = jau::math::Vec4f(0.2f, 0.2f, 1.0f, 0.7f);
60
61 private:
62 int m_name;
63 ShaderState& m_st;
64 GLUniformSyncPMVMat4fRef m_pmvMatUni;
65 GLUniformVec4fRef m_colorUniform;
66 jau::math::Vec4f m_gearColor;
68 bool m_useMappedBuffers;
69 bool m_picked;
70 jau::math::geom::AABBox3f m_objbox, m_viewbox;
71 jau::math::Mat4f m_PMvi;
72
73 GLFloatArrayDataServerRef m_frontFace;
74 GLFloatArrayDataServerRef m_frontSide;
77 GLFloatArrayDataServerRef m_outwardFace;
78 GLFloatArrayDataServerRef m_insideRadiusCyl;
79
80 private:
81 GLFloatArrayDataServerRef createInterleaved(bool useMappedBuffers, GLsizei compsPerElem, bool normalized, GLsizei initialSize, GLenum vboUsage) {
82 if( useMappedBuffers ) {
83 return GLFloatArrayDataServer::createGLSLInterleavedMapped(compsPerElem, normalized, initialSize, vboUsage);
84 } else {
85 return GLFloatArrayDataServer::createGLSLInterleaved(compsPerElem, normalized, initialSize, vboUsage);
86 }
87 }
88
89 void addInterleavedVertexAndNormalArrays(GLFloatArrayDataServerRef& array, GLsizei compsPerElem) {
90 array->addGLSLSubArray("gca_Vertex", compsPerElem, GL_ARRAY_BUFFER);
91 array->addGLSLSubArray("gca_Normal", compsPerElem, GL_ARRAY_BUFFER);
92 }
93
94 void vert(GLFloatArrayDataServerRef& array, float x, float y, float z, const jau::math::Vec3f& n) {
95 array->put3f(x, y, z);
96 array->put3f(n);
97 m_objbox.resize(x, y, z);
98 }
99
100 static void sincos(float x, float sin[], int sinIdx, float cos[], int cosIdx) {
101 sin[sinIdx] = std::sin(x);
102 cos[cosIdx] = std::cos(x);
103 }
104
105 void initGL(GL& gl, GLFloatArrayDataServerRef& array) {
106 array->enableBuffer(gl, true);
107 array->enableBuffer(gl, false);
108 }
109
110 void associate(ShaderState& st) {
111 m_frontFace->associate(st, true);
112 m_frontSide->associate(st, true);
113 m_backFace->associate(st, true);
114 m_backSide->associate(st, true);
115 m_outwardFace->associate(st, true);
116 m_insideRadiusCyl->associate(st, true);
117 }
118
119 void draw(GL& gl, GLFloatArrayDataServerRef& array, int mode) {
120 if( 0 < array->vboName() ) {
121 array->enableBuffer(gl, true);
122 ::glDrawArrays(mode, 0, array->elemCount());
123 array->enableBuffer(gl, false);
124 }
125 }
126
127 public:
129 float inner_radius, float outer_radius,
130 float width,
131 GLsizei teeth,
132 float tooth_depth,
134 GLUniformSyncPMVMat4fRef &pmvMatUni, GLUniformVec4fRef colorUniform)
135 : m_name(name), m_st(st), m_pmvMatUni(pmvMatUni),
136 m_colorUniform(std::move(colorUniform)), m_gearColor(gearColor), m_tx(tx),
137 m_useMappedBuffers(false), m_picked(false), m_objbox(), m_viewbox(), m_PMvi() {
138 const float dz = width * 0.5f;
139 float u, v, len;
140 float s[5];
141 float c[5];
142 jau::math::Vec3f normal;
143 // const int tris_per_tooth = 32;
144
145 const float r0 = inner_radius;
146 const float r1 = outer_radius - tooth_depth / 2.0f;
147 const float r2 = outer_radius + tooth_depth / 2.0f;
148
149 const float da = 2.0f * std::numbers::pi_v<float> / float(teeth) / 4.0f;
150
151 s[4] = 0; // sin(0f)
152 c[4] = 1; // cos(0f)
153
154 const GLenum vboUsage = GL_STATIC_DRAW;
155
156 m_frontFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * teeth + 2, vboUsage);
157 addInterleavedVertexAndNormalArrays(m_frontFace, 3);
158 m_backFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * teeth + 2, vboUsage);
159 addInterleavedVertexAndNormalArrays(m_backFace, 3);
160 m_frontSide = createInterleaved(m_useMappedBuffers, 6, false, 6 * teeth, vboUsage);
161 addInterleavedVertexAndNormalArrays(m_frontSide, 3);
162 m_backSide = createInterleaved(m_useMappedBuffers, 6, false, 6 * teeth, vboUsage);
163 addInterleavedVertexAndNormalArrays(m_backSide, 3);
164 m_outwardFace = createInterleaved(m_useMappedBuffers, 6, false, 4 * 4 * teeth + 2, vboUsage);
165 addInterleavedVertexAndNormalArrays(m_outwardFace, 3);
166 m_insideRadiusCyl = createInterleaved(m_useMappedBuffers, 6, false, 2 * teeth + 2, vboUsage);
167 addInterleavedVertexAndNormalArrays(m_insideRadiusCyl, 3);
168
169 for( GLsizei i = 0; i < teeth; i++ ) {
170 const float angle = float(i) * 2.0f * std::numbers::pi_v<float> / float(teeth);
171 sincos(angle + da * 0.0f, s, 0, c, 0);
172 sincos(angle + da * 1.0f, s, 1, c, 1);
173 sincos(angle + da * 2.0f, s, 2, c, 2);
174 sincos(angle + da * 3.0f, s, 3, c, 3);
175
176 /* front */
177 normal = jau::math::Vec3f(0, 0, 1);
178
179 /* front face - GL.GL_TRIANGLE_STRIP */
180 vert(m_frontFace, r0 * c[0], r0 * s[0], dz, normal);
181 vert(m_frontFace, r1 * c[0], r1 * s[0], dz, normal);
182 vert(m_frontFace, r0 * c[0], r0 * s[0], dz, normal);
183 vert(m_frontFace, r1 * c[3], r1 * s[3], dz, normal);
184
185 /* front sides of teeth - GL.GL_TRIANGLES */
186 vert(m_frontSide, r1 * c[0], r1 * s[0], dz, normal);
187 vert(m_frontSide, r2 * c[1], r2 * s[1], dz, normal);
188 vert(m_frontSide, r2 * c[2], r2 * s[2], dz, normal);
189 vert(m_frontSide, r1 * c[0], r1 * s[0], dz, normal);
190 vert(m_frontSide, r2 * c[2], r2 * s[2], dz, normal);
191 vert(m_frontSide, r1 * c[3], r1 * s[3], dz, normal);
192
193 /* back */
194 normal = jau::math::Vec3f(0, 0, -1);
195
196 /* back face - GL.GL_TRIANGLE_STRIP */
197 vert(m_backFace, r1 * c[0], r1 * s[0], -dz, normal);
198 vert(m_backFace, r0 * c[0], r0 * s[0], -dz, normal);
199 vert(m_backFace, r1 * c[3], r1 * s[3], -dz, normal);
200 vert(m_backFace, r0 * c[0], r0 * s[0], -dz, normal);
201
202 /* back sides of teeth - GL.GL_TRIANGLES*/
203 vert(m_backSide, r1 * c[3], r1 * s[3], -dz, normal);
204 vert(m_backSide, r2 * c[2], r2 * s[2], -dz, normal);
205 vert(m_backSide, r2 * c[1], r2 * s[1], -dz, normal);
206 vert(m_backSide, r1 * c[3], r1 * s[3], -dz, normal);
207 vert(m_backSide, r2 * c[1], r2 * s[1], -dz, normal);
208 vert(m_backSide, r1 * c[0], r1 * s[0], -dz, normal);
209
210 /* outward faces of teeth */
211 u = r2 * c[1] - r1 * c[0];
212 v = r2 * s[1] - r1 * s[0];
213 len = std::sqrt(u * u + v * v);
214 u /= len;
215 v /= len;
216 normal = jau::math::Vec3f(v, -u, 0);
217
218 vert(m_outwardFace, r1 * c[0], r1 * s[0], dz, normal);
219 vert(m_outwardFace, r1 * c[0], r1 * s[0], -dz, normal);
220 vert(m_outwardFace, r2 * c[1], r2 * s[1], dz, normal);
221 vert(m_outwardFace, r2 * c[1], r2 * s[1], -dz, normal);
222
223 normal[0] = c[0];
224 normal[1] = s[0];
225 vert(m_outwardFace, r2 * c[1], r2 * s[1], dz, normal);
226 vert(m_outwardFace, r2 * c[1], r2 * s[1], -dz, normal);
227 vert(m_outwardFace, r2 * c[2], r2 * s[2], dz, normal);
228 vert(m_outwardFace, r2 * c[2], r2 * s[2], -dz, normal);
229
230 normal[0] = (r1 * s[3] - r2 * s[2]);
231 normal[1] = (r1 * c[3] - r2 * c[2]) * -1.0f;
232 vert(m_outwardFace, r2 * c[2], r2 * s[2], dz, normal);
233 vert(m_outwardFace, r2 * c[2], r2 * s[2], -dz, normal);
234 vert(m_outwardFace, r1 * c[3], r1 * s[3], dz, normal);
235 vert(m_outwardFace, r1 * c[3], r1 * s[3], -dz, normal);
236
237 normal[0] = c[0];
238 normal[1] = s[0];
239 vert(m_outwardFace, r1 * c[3], r1 * s[3], dz, normal);
240 vert(m_outwardFace, r1 * c[3], r1 * s[3], -dz, normal);
241 vert(m_outwardFace, r1 * c[0], r1 * s[0], dz, normal);
242 vert(m_outwardFace, r1 * c[0], r1 * s[0], -dz, normal);
243
244 /* inside radius cylinder */
245 normal[0] = c[0] * -1.0f;
246 normal[1] = s[0] * -1.0f;
247 normal[2] = 0.0f;
248 vert(m_insideRadiusCyl, r0 * c[0], r0 * s[0], -dz, normal);
249 vert(m_insideRadiusCyl, r0 * c[0], r0 * s[0], dz, normal);
250 }
251 /* finish front face */
252 normal[0] = 0.0f;
253 normal[1] = 0.0f;
254 normal[2] = 1.0f;
255 vert(m_frontFace, r0 * c[4], r0 * s[4], dz, normal);
256 vert(m_frontFace, r1 * c[4], r1 * s[4], dz, normal);
257 m_frontFace->seal(true);
258
259 /* finish back face */
260 normal[2] = -1.0f;
261 vert(m_backFace, r1 * c[4], r1 * s[4], -dz, normal);
262 vert(m_backFace, r0 * c[4], r0 * s[4], -dz, normal);
263 m_backFace->seal(true);
264
265 m_backSide->seal(true);
266 m_frontSide->seal(true);
267
268 /* finish outward face */
269 sincos(da * 1.0f, s, 1, c, 1);
270 u = r2 * c[1] - r1 * c[4];
271 v = r2 * s[1] - r1 * s[4];
272 len = std::sqrt(u * u + v * v);
273 u /= len;
274 v /= len;
275 normal[0] = v;
276 normal[1] = -u;
277 normal[2] = 0.0f;
278 vert(m_outwardFace, r1 * c[4], r1 * s[4], dz, normal);
279 vert(m_outwardFace, r1 * c[4], r1 * s[4], -dz, normal);
280 m_outwardFace->seal(true);
281
282 /* finish inside radius cylinder */
283 normal[0] = c[4] * -1.0f;
284 normal[1] = s[4] * -1.0f;
285 normal[2] = 0.0f;
286 vert(m_insideRadiusCyl, r0 * c[4], r0 * s[4], -dz, normal);
287 vert(m_insideRadiusCyl, r0 * c[4], r0 * s[4], dz, normal);
288 m_insideRadiusCyl->seal(true);
289
290 associate(m_st);
291 }
292
293 void initGL(GL& gl) {
294 /** Init VBO and data .. */
295 initGL(gl, m_frontFace);
296 initGL(gl, m_frontSide);
297 initGL(gl, m_backFace);
298 initGL(gl, m_backSide);
299 initGL(gl, m_outwardFace);
300 initGL(gl, m_insideRadiusCyl);
301 }
302 void dispose(GL& gl) {
303 // could be already destroyed by shared configuration
304 if( m_frontFace ) {
305 m_frontFace->destroy(gl);
306 }
307 if( m_frontSide ) {
308 m_frontSide->destroy(gl);
309 }
310 if( m_backFace ) {
311 m_backFace->destroy(gl);
312 }
313 if( m_backSide ) {
314 m_backSide->destroy(gl);
315 }
316 if( m_outwardFace ) {
317 m_outwardFace->destroy(gl);
318 }
319 if( m_insideRadiusCyl ) {
320 m_insideRadiusCyl->destroy(gl);
321 }
322 m_frontFace = nullptr;
323 m_frontSide = nullptr;
324 m_backFace = nullptr;
325 m_backSide = nullptr;
326 m_outwardFace = nullptr;
327 m_insideRadiusCyl = nullptr;
328 }
329
330 void draw(GL& gl, float ang_rad) {
331 PMVMat4f& pmv = m_pmvMatUni->pmv();
332 pmv.pushMv();
333 pmv.translateMv(m_tx);
334 m_objbox.transform(pmv.getMv(), m_viewbox); // view-box for findPick
335 pmv.rotateMv(ang_rad, 0.0f, 0.0f, 1.0f);
336 m_st.pushUniform(gl, m_pmvMatUni); // automatic sync + update of Mvi + Mvit
337
338 if( m_picked ) {
339 const float gray = ( m_gearColor.x + m_gearColor.y + m_gearColor.z ) / 3.0f;
340 m_colorUniform->vec4f() = jau::math::Vec4f(gray, gray, gray, m_gearColor.w);
341 } else {
342 m_colorUniform->vec4f() = m_gearColor;
343 }
344 m_st.pushUniform(gl, m_colorUniform);
345
346 draw(gl, m_frontFace, GL_TRIANGLE_STRIP);
347 draw(gl, m_frontSide, GL_TRIANGLES);
348 draw(gl, m_backFace, GL_TRIANGLE_STRIP);
349 draw(gl, m_backSide, GL_TRIANGLES);
350 draw(gl, m_outwardFace, GL_TRIANGLE_STRIP);
351 draw(gl, m_insideRadiusCyl, GL_TRIANGLE_STRIP);
352
353 m_PMvi = pmv.getPMvi();
354 pmv.popMv();
355 }
356 bool dispatchAction(const PointerShapeAction& action, const PointerEvent& e, const WindowRef& win) {
357 PMVMat4f& pmv = m_pmvMatUni->pmv();
358 pmv.pushMv();
359 pmv.translateMv(m_tx);
360
361 const bool done = action(e, win, *this);
362
363 pmv.popMv();
364 return done;
365 }
366
367 bool& picked() noexcept { return m_picked; }
368 const jau::math::geom::AABBox3f& objBounds() const noexcept { return m_objbox; }
369 const jau::math::geom::AABBox3f& viewBounds() const noexcept { return m_viewbox; }
370 const jau::math::Mat4f& matPMvi() const noexcept { return m_PMvi; }
371 constexpr int name() const noexcept { return m_name; }
372 std::string toString() const noexcept { return std::string("GearsObjES2[").append(std::to_string(m_name).append(", view ").append(m_viewbox.toString())).append("]"); }
373};
374
375/**
376 * GearsES2
377 * @author Brian Paul (converted to C++ and added pixel-lightning by Sven Gothel)
378 */
379class GearsES2 : public RenderListener {
380 private:
381 constexpr static jau::math::Vec3f lightPos = jau::math::Vec3f(5.0f, 5.0f, 10.0f);
382 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
383
384 ShaderState m_st;
385 GLUniformSyncPMVMat4fRef m_pmvMatUni;
386 GLUniformVec4fRef m_colorUni;
387 jau::math::Vec4f m_gear1Color, m_gear2Color, m_gear3Color;
388 GearsObjectES2 m_gear1, m_gear2, m_gear3;
389
390 jau::math::Recti m_viewport;
392 Vec3f m_pan;
393 /// in angle degrees
394 float m_teethAngle = 0.0f;
395 int m_swapInterval = 1;
396
397 bool m_flipVerticalInGLOrientation = false;
398 bool m_doRotate = true;
399 jau::math::Vec4f m_clearColor = jau::math::Vec4f(0.0f);
400 bool m_clearBuffers = true;
401 bool m_initialized = false;
402
403 float m_zNear = 5.0f;
404 float m_zFar = 10000.0f;
405 float m_zViewDist = 40.0f;
406
407 public:
410 m_st(),
411 m_pmvMatUni(GLUniformSyncPMVMat4f::create("gcu_PMVMatrix", mat_req)), // P, Mv, Mvi and Mvit
412 m_colorUni(GLUniformVec4f::create("gcu_StaticColor", GearsObjectES2::red)),
413 m_gear1Color(GearsObjectES2::red),
414 m_gear2Color(GearsObjectES2::green),
415 m_gear3Color(GearsObjectES2::blue),
416 m_gear1(1, m_st, m_gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, Vec3f( -3.0f, -2.0f, 0.0f), m_pmvMatUni, m_colorUni),
417 m_gear2(2, m_st, m_gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, Vec3f( 3.1f, -2.0f, 0.0f), m_pmvMatUni, m_colorUni),
418 m_gear3(3, m_st, m_gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, Vec3f( -3.1f, 4.2f, 0.0f), m_pmvMatUni, m_colorUni)
419 { }
420
421 constexpr bool doRotate() const noexcept { return m_doRotate; }
422 constexpr void setDoRotate(bool rotate) noexcept { m_doRotate = rotate; }
423 constexpr void setClearBuffers(bool v) noexcept { m_clearBuffers = v; }
424 constexpr void setFlipVerticalInGLOrientation(bool v) noexcept { m_flipVerticalInGLOrientation = v; }
425 PMVMat4f& pmvMatrix() noexcept { return m_pmvMatUni->pmv(); }
426 const PMVMat4f& pmvMatrix() const noexcept { return m_pmvMatUni->pmv(); }
427 constexpr const jau::math::Recti& viewport() const noexcept { return m_viewport; }
428 constexpr Vec3f& pan() noexcept { return m_pan; }
429 constexpr jau::math::Vec3f& rotEuler() noexcept { return m_rotEuler; }
430
431 void setClearColor(const jau::math::Vec4f& clearColor) noexcept {
432 m_clearColor = clearColor;
433 }
434
435 void setGearsColors(const jau::math::Vec4f& gear1Color, const jau::math::Vec4f& gear2Color, const jau::math::Vec4f& gear3Color) noexcept {
436 m_gear1Color = gear1Color;
437 m_gear2Color = gear2Color;
438 m_gear3Color = gear3Color;
439 }
440 constexpr const jau::math::Vec3f& rotEuler() const noexcept { return m_rotEuler; }
441
442 void setZ(float zNear, float zFar, float zViewDist) {
443 m_zNear = zNear;
444 m_zFar = zFar;
445 m_zViewDist = zViewDist;
446 }
447
448 bool init(const WindowRef& win, const jau::fraction_timespec& when) override {
449 jau::fprintf_td(when.to_ms(), stdout, "RL::init: %s\n", toString().c_str());
450 GL& gl = GL::downcast(win->renderContext());
451
452 // m_st.setVerbose(true);
453 ShaderCodeRef vp0 = ShaderCode::create(gl, GL_VERTEX_SHADER, "demos/glsl",
454 "demos/glsl/bin", "SingleLight0");
455 ShaderCodeRef fp0 = ShaderCode::create(gl, GL_FRAGMENT_SHADER, "demos/glsl",
456 "demos/glsl/bin", "SingleLight0");
457 if( !vp0 || !fp0 ) {
458 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
459 win->dispose(when);
460 return false;
461 }
465 if( !sp0->add(gl, vp0, true) || !sp0->add(gl, fp0, true) ) {
466 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
467 sp0->destroy(gl);
468 win->dispose(when);
469 return false;
470 }
471 m_st.attachShaderProgram(gl, sp0, true);
472
473 m_gear1.initGL(gl);
474 m_gear2.initGL(gl);
475 m_gear3.initGL(gl);
476
477 // st.attachObject("pmvMatrix", pmvMatrix);
478 m_st.ownUniform(m_pmvMatUni, true);
479
480 GLUniformVec3fRef lightU = GLUniformVec3f::create("gcu_Light0Pos", lightPos);
481 m_st.ownUniform(lightU, true);
482
483 m_st.ownUniform(m_colorUni, true);
484 m_st.pushAllUniforms(gl);
485
486 if( m_clearBuffers ) {
487 ::glClearColor(m_clearColor.x, m_clearColor.y, m_clearColor.z, m_clearColor.w);
488 }
489 m_initialized = sp0->inUse();
490 m_st.useProgram(gl, false);
491
492 if( !m_initialized ) {
493 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
494 m_st.destroy(gl);
495 win->dispose(when);
496 }
497 return m_initialized;
498 }
499
500 void dispose(const WindowRef& win, const jau::fraction_timespec& when) override {
501 jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", toString().c_str());
502 jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", win->toString().c_str());
503 GL& gl = GL::downcast(win->renderContext());
504 m_st.useProgram(gl, false);
505 m_gear1.dispose(gl);
506 m_gear2.dispose(gl);
507 m_gear3.dispose(gl);
508 m_st.destroy(gl);
509 m_initialized = false;
510 }
511
512 void reshape(const WindowRef& win, const jau::math::Recti& viewport, const jau::fraction_timespec& when) override {
513 jau::fprintf_td(when.to_ms(), stdout, "RL::reshape: %s\n\t%s\n", toString().c_str(), m_pmvMatUni->pmv().toString().c_str());
514 if( !m_initialized ) { return; }
515 m_viewport = viewport;
516 reshapeImpl(win, viewport, float(viewport.width()), float(viewport.height()), when);
517 }
518
519 void reshapeImpl(const WindowRef& win, const jau::math::Recti& viewport, float imageWidth, float imageHeight, const jau::fraction_timespec& when) {
520 const bool msaa = false; // gl.getContext().getGLDrawable().getChosenGLCapabilities().getSampleBuffers();
521 jau::fprintf_td(when.to_ms(), stdout, "GearsES2.reshape %s of %fx%f, swapInterval %d, msaa %d, tileRendererInUse %d\n",
522 viewport.toString().c_str(), imageWidth, imageHeight, m_swapInterval, msaa, false);
523 GL& gl = GL::downcast(win->renderContext());
524 // compute projection parameters 'normal'
525 float left, right, bottom, top;
526 if( imageHeight > imageWidth ) {
527 const float a = imageHeight / imageWidth;
528 left = -1.0f;
529 right = 1.0f;
530 bottom = -a;
531 top = a;
532 } else {
533 const float a = imageWidth / imageHeight;
534 left = -a;
535 right = a;
536 bottom = -1.0f;
537 top = 1.0f;
538 }
539 const float w = right - left;
540 const float h = top - bottom;
541
542 // compute projection parameters 'tiled'
543 const float l = left + float(viewport.x()) * w / imageWidth;
544 const float r = l + float(viewport.width()) * w / imageWidth;
545 const float b = bottom + float(viewport.y()) * h / imageHeight;
546 const float t = b + float(viewport.height()) * h / imageHeight;
547 {
548 const float _w = r - l;
549 const float _h = t - b;
550 jau::fprintf_td(when.to_ms(), stdout, ">> GearsES2 angle %f, [l %f, r %f, b %f, t %f] %fx%f -> [l %f, r %f, b %f, t %f] %fx%f, v-flip %d",
551 m_teethAngle, left, right, bottom, top, w, h, l, r, b, t, _w, _h, m_flipVerticalInGLOrientation);
552 }
553
554 PMVMat4f& pmv = m_pmvMatUni->pmv();
555 pmv.loadPIdentity();
556 if( m_flipVerticalInGLOrientation && win->isBLOriented() ) {
557 pmv.scaleP(1.0f, -1.0f, 1.0f);
558 }
559 pmv.frustumP(l, r, b, t, m_zNear, m_zFar);
560
561 pmv.loadMvIdentity();
562 pmv.translateMv(0.0f, 0.0f, -m_zViewDist);
563
564 m_st.useProgram(gl, true);
565 m_st.pushUniform(gl, m_pmvMatUni);
566 m_st.useProgram(gl, false);
567 }
568
569 static constexpr float getTeethRotation(int name, float adeg) noexcept {
570 switch(name) {
571 case 1: return jau::adeg_to_rad( 1.0f * adeg - 0.0f);
572 case 2: return jau::adeg_to_rad(-2.0f * adeg - 9.0f);
573 default: return jau::adeg_to_rad(-2.0f * adeg - 25.0f);
574 }
575 }
576
577 void display(const WindowRef& win, const jau::fraction_timespec&) override {
578 if( !m_initialized ) { return; }
579
580 // Turn the gears' teeth
581 if( m_doRotate ) {
582 m_teethAngle += 0.5f;
583 }
584 GL& gl = GL::downcast(win->renderContext());
585 // bool m_hasFocus = win->hasFocus();
586
587 if( m_clearBuffers ) {
588 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
589 }
590
591 setGLStates(win, true);
592
593 m_st.useProgram(gl, true);
594 PMVMat4f& pmv = m_pmvMatUni->pmv();
595 pmv.pushMv();
596 pmv.translateMv(m_pan);
597 pmv.rotateMv(m_rotEuler.x, 1.0f, 0.0f, 0.0f);
598 pmv.rotateMv(m_rotEuler.y, 0.0f, 1.0f, 0.0f);
599 pmv.rotateMv(m_rotEuler.z, 0.0f, 0.0f, 1.0f);
600
601 m_gear1.draw(gl, getTeethRotation(1, m_teethAngle));
602 m_gear2.draw(gl, getTeethRotation(2, m_teethAngle));
603 m_gear3.draw(gl, getTeethRotation(3, m_teethAngle));
604 pmv.popMv();
605 m_st.useProgram(gl, false);
606
607 setGLStates(win, false);
608 }
609
610 /// Fast loop through all shapes using PointerShapeAction w/o matrix traversal using view-coordinates
611 GearsObjectES2* findPick(const PointerShapeAction& action, const PointerEvent& e, const WindowRef& win) {
612 // Sort gears in z-axis descending order
613 std::array<GearsObjectES2*, 3> gears{ &m_gear1, &m_gear2, &m_gear3 };
614 struct ZDescending {
615 bool operator()(GearsObjectES2* a, GearsObjectES2* b) const {
616 return a->viewBounds().high().z > b->viewBounds().high().z;
617 }
618 } zDescending;
619 std::sort(gears.begin(), gears.end(), zDescending); // NOLINT(modernize-use-ranges)
620
621 // We do not perform teeth-object rotation in object space for PointerEventAction!
622 GearsObjectES2* res = nullptr;
623 for(size_t i=0; !res && i<gears.size(); ++i) {
624 if( action(e, win, *gears[i]) ) {
625 res = gears[i];
626 }
627 }
628 return res;
629 }
630 /// Dispatch PointerShapeAction to given shape w/ matrix traversal
631 bool dispatchForShape(GearsObjectES2& shape, const PointerShapeAction& action, const PointerEvent& e, const WindowRef& win) {
632 PMVMat4f& pmv = m_pmvMatUni->pmv();
633 pmv.pushMv();
634 pmv.translateMv(m_pan);
635 pmv.rotateMv(m_rotEuler.x, 1.0f, 0.0f, 0.0f);
636 pmv.rotateMv(m_rotEuler.y, 0.0f, 1.0f, 0.0f);
637 pmv.rotateMv(m_rotEuler.z, 0.0f, 0.0f, 1.0f);
638
639 const bool res = shape.dispatchAction(action, e, win);
640
641 pmv.popMv();
642 return res;
643 }
644
645 private:
646 void setGLStates(const WindowRef& win, bool enable) {
647 // Culling only possible if we do not flip the projection matrix
648 const bool useCullFace = !(m_flipVerticalInGLOrientation && win->isBLOriented());
649 if( enable ) {
650 ::glEnable(GL_DEPTH_TEST);
651 if( useCullFace ) {
652 ::glEnable(GL_CULL_FACE);
653 }
654 } else {
655 ::glDisable(GL_DEPTH_TEST);
656 if( useCullFace ) {
657 ::glDisable(GL_CULL_FACE);
658 }
659 }
660 }
661
662 public:
663 std::string toStringImpl() const noexcept override {
664 std::string r("GearsES2[isInit ");
665 r.append(std::to_string(m_initialized).append(", usesShared ").append(std::to_string(false)))
666 .append(", 1 ")
667 .append(m_gear1.toString())
668 .append(", 2 ")
669 .append(m_gear2.toString())
670 .append(", 3 ")
671 .append(m_gear3.toString())
672 .append("]");
673 return r;
674 }
675};
676
677#endif // GAMP_DEMO_GEARSES02_HPP_
jau::function< bool(const PointerEvent &e, const WindowRef &win, GearsObjectES2 &shape)> PointerShapeAction
Definition GearsES2.hpp:49
#define E_FILE_LINE
void setZ(float zNear, float zFar, float zViewDist)
Definition GearsES2.hpp:442
constexpr void setClearBuffers(bool v) noexcept
Definition GearsES2.hpp:423
constexpr Vec3f & pan() noexcept
Definition GearsES2.hpp:428
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
Definition GearsES2.hpp:448
constexpr bool doRotate() const noexcept
Definition GearsES2.hpp:421
constexpr void setDoRotate(bool rotate) noexcept
Definition GearsES2.hpp:422
constexpr const jau::math::Vec3f & rotEuler() const noexcept
Definition GearsES2.hpp:440
constexpr void setFlipVerticalInGLOrientation(bool v) noexcept
Definition GearsES2.hpp:424
const PMVMat4f & pmvMatrix() const noexcept
Definition GearsES2.hpp:426
GearsObjectES2 * findPick(const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Fast loop through all shapes using PointerShapeAction w/o matrix traversal using view-coordinates.
Definition GearsES2.hpp:611
constexpr jau::math::Vec3f & rotEuler() noexcept
Definition GearsES2.hpp:429
std::string toStringImpl() const noexcept override
Definition GearsES2.hpp:663
static constexpr float getTeethRotation(int name, float adeg) noexcept
Definition GearsES2.hpp:569
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.
Definition GearsES2.hpp:512
constexpr const jau::math::Recti & viewport() const noexcept
Definition GearsES2.hpp:427
void reshapeImpl(const WindowRef &win, const jau::math::Recti &viewport, float imageWidth, float imageHeight, const jau::fraction_timespec &when)
Definition GearsES2.hpp:519
bool dispatchForShape(GearsObjectES2 &shape, const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Dispatch PointerShapeAction to given shape w/ matrix traversal.
Definition GearsES2.hpp:631
void setClearColor(const jau::math::Vec4f &clearColor) noexcept
Definition GearsES2.hpp:431
void display(const WindowRef &win, const jau::fraction_timespec &) override
Called by the drawable to initiate rendering by the client.
Definition GearsES2.hpp:577
void setGearsColors(const jau::math::Vec4f &gear1Color, const jau::math::Vec4f &gear2Color, const jau::math::Vec4f &gear3Color) noexcept
Definition GearsES2.hpp:435
PMVMat4f & pmvMatrix() noexcept
Definition GearsES2.hpp:425
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
Definition GearsES2.hpp:500
GearsObjectES2.
Definition GearsES2.hpp:55
std::string toString() const noexcept
Definition GearsES2.hpp:372
bool dispatchAction(const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Definition GearsES2.hpp:356
const jau::math::geom::AABBox3f & viewBounds() const noexcept
Definition GearsES2.hpp:369
const jau::math::geom::AABBox3f & objBounds() const noexcept
Definition GearsES2.hpp:368
constexpr int name() const noexcept
Definition GearsES2.hpp:371
static constexpr jau::math::Vec4f green
Definition GearsES2.hpp:58
GearsObjectES2(int name, ShaderState &st, const jau::math::Vec4f &gearColor, float inner_radius, float outer_radius, float width, GLsizei teeth, float tooth_depth, jau::math::Vec3f tx, GLUniformSyncPMVMat4fRef &pmvMatUni, GLUniformVec4fRef colorUniform)
Definition GearsES2.hpp:128
bool & picked() noexcept
Definition GearsES2.hpp:367
void dispose(GL &gl)
Definition GearsES2.hpp:302
void initGL(GL &gl)
Definition GearsES2.hpp:293
const jau::math::Mat4f & matPMvi() const noexcept
Definition GearsES2.hpp:370
void draw(GL &gl, float ang_rad)
Definition GearsES2.hpp:330
static constexpr jau::math::Vec4f red
Definition GearsES2.hpp:57
static constexpr jau::math::Vec4f blue
Definition GearsES2.hpp:59
static GLContext & downcast(RenderContext *rc)
Downcast dereferenced given RenderContext* to GLContext&, throws exception if signature doesn't match...
static server_ref createGLSLInterleaved(GLsizei compsPerElement, bool normalized, GLsizei initialElementCount, GLenum vboUsage)
static server_ref createGLSLInterleavedMapped(GLsizei compsPerElement, bool normalized, GLsizei mappedElementCount, GLenum vboUsage)
static std::shared_ptr< GLUniformVec3f > create(stringview_t name, const jau::math::Vec3f &v)
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
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
constexpr bool isBLOriented() const noexcept
Returns true if this surface is rendered in OpenGL's coordinate system, origin at bottom left.
Definition Surface.hpp:168
void dispose(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:355
std::string toString() const noexcept
Definition gamp_wt.cpp:145
Pointer event of type PointerType.
Class template jau::function is a general-purpose static-polymorphic function wrapper.
value_type z
Definition vec3f.hpp:68
Axis Aligned Bounding Box.
Definition aabbox3f.hpp:43
constexpr const Point3f & high() const noexcept
Returns the maximum right-top-near (xyz) coordinate.
Definition aabbox3f.hpp:99
constexpr PMVMatrix4 & scaleP(float x, float y, float z) noexcept
Scale the projection matrix.
Definition pmvmat4.hpp:704
void frustumP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar)
Multiply the projection matrix with the frustum matrix.
Definition pmvmat4.hpp:850
constexpr PMVMatrix4 & translateMv(float x, float y, float z) noexcept
Translate the modelview matrix.
Definition pmvmat4.hpp:641
constexpr_cxx26 PMVMatrix4 & rotateMv(const float ang_rad, const float x, const float y, const float z) noexcept
Rotate the modelview matrix by the given axis and angle in radians.
Definition pmvmat4.hpp:728
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
Definition pmvmat4.hpp:795
constexpr PMVMatrix4 & loadMvIdentity() noexcept
Load the modelview matrix with the values of the given Mat4.
Definition pmvmat4.hpp:577
constexpr Mat4 & getPMvi() noexcept
Returns the pre-multiplied inverse projection x modelview, if Mat4#invert(Mat4) succeeded,...
Definition pmvmat4.hpp:1342
constexpr PMVMatrix4 & loadPIdentity() noexcept
Load the projection matrix with the values of the given Mat4.
Definition pmvmat4.hpp:586
constexpr Mat4 & getMv() noexcept
Returns the modelview matrix (Mv).
Definition pmvmat4.hpp:275
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
Definition pmvmat4.hpp:813
consteval_cxx20 std::string_view name() noexcept
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
std::shared_ptr< GLUniformSyncPMVMat4f > GLUniformSyncPMVMat4fRef
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
std::shared_ptr< GLUniformVec3f > GLUniformVec3fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
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
RectI< int > Recti
Definition recti.hpp:146
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
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.