Gamp v0.0.8
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
SolInSpace.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 <gamp/Gamp.hpp>
13
14#include <cstdio>
15#include <cmath>
16#include <memory>
17
18#include <jau/basic_types.hpp>
19#include <jau/float_types.hpp>
20#include <jau/fraction_type.hpp>
21#include <jau/io/file_util.hpp>
22#include <jau/math/mat4f.hpp>
23#include <jau/math/vec4f.hpp>
24
25#include <gamp/Gamp.hpp>
27
32
35
36using namespace jau::math;
37using namespace jau::math::util;
38
39using namespace gamp::wt;
40using namespace gamp::wt::event;
41using namespace gamp::render::gl::glsl;
42using namespace gamp::render::gl::data;
43
44class Example : public RenderListener {
45 private:
46 constexpr static float defaultCoreRadius = 0.20f;
47 constexpr static float animCoreRadiusHalfStep = 0.015f;
48
49 Vec3f m_center = Vec3f(0, 0, 0);
50 float m_radius = 1.00f;
51
52 ShaderState m_st;
53 Recti m_viewport;
54 GLUniformSyncPMVMat4f m_pmvMatUni;
55
56 GLUniformVec4f m_uWinCenter;
57 GLUniformVec4f m_uCoreColor, m_uHaloColor, m_uBackColor;
58 GLUniformScalarF32 m_uWinRadius, m_uCoreRadius, m_uSeam;
59
60 bool m_initialized;
61 jau::fraction_timespec m_tlast;
62
63 class MyKeyListener : public KeyListener {
64 public:
65 MyKeyListener(Example &) { }
66
67 void keyPressed(KeyEvent &e, const KeyboardTracker &kt) override {
68 jau::fprintf_td(e.when().to_ms(), stdout, "KeyPressed: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
69 if (e.keySym() == VKeyCode::VK_ESCAPE) {
70 WindowSRef win = e.source().lock();
71 if (win) {
72 win->dispose(e.when());
73 }
74 } else if (e.keySym() == VKeyCode::VK_W) {
75 WindowSRef win = e.source().lock();
76 jau::fprintf_td(e.when().to_ms(), stdout, "Source: %s\n", win ? win->toString().c_str() : "null");
77 }
78 }
79 void keyReleased(KeyEvent &e, const KeyboardTracker &kt) override {
80 jau::fprintf_td(e.when().to_ms(), stdout, "KeyRelease: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
81 }
82 };
83 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
84 MyKeyListenerRef m_kl;
85
86 public:
87
90 m_pmvMatUni("gcu_PMVMatrix"),
91 m_uWinCenter("gcu_solInSpace.winCenter", Vec4f()),
92 m_uCoreColor("gcu_solInSpace.coreColor", Vec4f(1.0f, 1.0f, 0.0f, 1.0f)),
93 m_uHaloColor("gcu_solInSpace.haloColor", Vec4f(1.0f, 0.99f, 0.0f, 1.0f)),
94 m_uBackColor("gcu_solInSpace.bgColor", Vec4f(0.0f, 0.0f, 0.0f, 0.5f)),
95 m_uWinRadius("gcu_solInSpace.winRadius", 0),
96 m_uCoreRadius("gcu_solInSpace.coreRadius", defaultCoreRadius),
97 m_uSeam("gcu_solInSpace.seam", 0.005f),
98 m_initialized(false),
99 m_kl(std::make_shared<MyKeyListener>(*this))
100 {
101 m_st.manage(m_pmvMatUni);
102
103 m_st.manage(m_uWinCenter);
104 m_st.manage(m_uCoreColor);
105 m_st.manage(m_uHaloColor);
106 m_st.manage(m_uBackColor);
107 m_st.manage(m_uWinRadius);
108 m_st.manage(m_uCoreRadius);
109 m_st.manage(m_uSeam);
110 }
111
112 Recti& viewport() noexcept { return m_viewport; }
113 const Recti& viewport() const noexcept { return m_viewport; }
114
115 PMVMat4f& pmv() noexcept { return m_pmvMatUni.pmv(); }
116 const PMVMat4f& pmv() const noexcept { return m_pmvMatUni.pmv(); }
117
118 bool init(const WindowSRef& win, const jau::fraction_timespec& when) override {
120 // ShaderState::VERBOSE_STATE = true;
121 // ShaderState::DEBUG_STATE = true;
122
123 jau::fprintf_td(when.to_ms(), stdout, "RL::init: %s\n", toString().c_str());
124 m_tlast = when;
125
126 GL& gl = GL::downcast(win->renderContext());
127 ShaderCodeSRef vp0 = ShaderCode::create(gl, GL_VERTEX_SHADER, "demos/glsl",
128 "demos/glsl/bin", "default");
129 ShaderCodeSRef fp0 = ShaderCode::create(gl, GL_FRAGMENT_SHADER, "demos/glsl",
130 "demos/glsl/bin", "SolInSpace");
131 if( !vp0 || !fp0 ) {
132 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
133 win->dispose(when);
134 return false;
135 }
139 if( !sp0->add(gl, vp0, true) || !sp0->add(gl, fp0, true) ) {
140 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
141 sp0->destroy(gl);
142 win->dispose(when);
143 return false;
144 }
145 m_st.attachShaderProgram(gl, sp0, true);
146
147 // setup mgl_PMVMatrix
148 PMVMat4f &pmv = m_pmvMatUni.pmv();
149 pmv.getP().loadIdentity();
150 pmv.getMv().loadIdentity();
151
152 // ::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
153 // m_uBackColor->vec4f().set(1.0f, 1.0f, 1.0f, 0.5f);
154 ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
155 m_uBackColor.vec4f().set(0.0f, 0.0f, 0.0f, 0.5f);
156
157 // Allocate Vertex Array
158 GLFloatArrayDataServerSRef vertices = GLFloatArrayDataServer::createGLSL("gca_Vertex", 3, false, 4, GL_STATIC_DRAW);
159 vertices->reserve(4); // reserve 4 elements (4x3 components) upfront, otherwise growIfNeeded is used
160 vertices->put( { -m_radius, m_radius, 0, // 1st vertex
161 m_radius, m_radius, 0, // burst transfer, instead of 4x `put3f` for single vertice-value
162 -m_radius, -m_radius, 0,
163 m_radius, -m_radius, 0 } );
164 m_st.manage(vertices);
165 vertices->seal(gl, true);
166
167 ::glEnable(GL_DEPTH_TEST);
168
169 m_initialized = sp0->inUse();
170 if( m_initialized ) {
171 m_st.sendAllUniforms(gl);
172 } else {
173 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
174 m_st.destroy(gl);
175 win->dispose(when);
176 }
177 m_st.useProgram(gl, false);
178
179 win->addKeyListener(m_kl);
180 return m_initialized;
181 }
182
184 PMVMat4f &pmv = m_pmvMatUni.pmv();
185 {
186 Vec3f winCenter;
187 pmv.mapObjToWin(m_center, m_viewport, winCenter);
188 m_uWinCenter.vec4f().set(winCenter, 1.0f);
189
190 const Vec3f p1 = m_center + Vec3f(m_radius,0,0);
191 Vec3f winP1;
192 pmv.mapObjToWin(p1, m_viewport, winP1);
193 Vec3f winR = winP1 - winCenter;
194 m_uWinRadius.scalar() = winR.length();
195 }
196 m_st.send(gl, m_uWinCenter);
197 m_st.send(gl, m_uWinRadius);
198 }
199
200 void dispose(const WindowSRef& win, const jau::fraction_timespec& when) override {
201 jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", toString().c_str());
202 win->removeKeyListener(m_kl);
203 m_st.destroy(GL::downcast(win->renderContext()));
204 m_initialized = false;
205 }
206
207 void reshape(const WindowSRef& win, const jau::math::Recti& viewport, const jau::fraction_timespec& when) override {
208 GL& gl = GL::downcast(win->renderContext());
209 jau::fprintf_td(when.to_ms(), stdout, "RL::reshape: %s\n", toString().c_str());
210 m_viewport = viewport;
211
212 const float aspect = 1.0f;
213 const float fovy_deg=45.0f;
214 const float aspect2 = ( (float) m_viewport.width() / (float) m_viewport.height() ) / aspect;
215 const float zNear=1.0f;
216 const float zFar=100.0f;
217 PMVMat4f &pmv = m_pmvMatUni.pmv();
218 pmv.setToPerspective(jau::adeg_to_rad(fovy_deg), aspect2, zNear, zFar);
219 pmv.getMv().loadIdentity();
220 pmv.translateMv(0, 0, -3);
221
222 m_st.useProgram(gl, true);
223 m_st.send(gl, m_pmvMatUni);
225 m_st.useProgram(gl, false);
226 }
227
228 bool m_once = true;
229
230 void display(const WindowSRef& win, const jau::fraction_timespec& when) override {
231 // jau::fprintf_td(when.to_ms(), stdout, "RL::display: %s, %s\n", toString().c_str(), win->toString().c_str());
232 if( !m_initialized ) {
233 return;
234 }
235 GL& gl = GL::downcast(win->renderContext());
236 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
237
238 m_st.useProgram(gl, true);
239 {
240 static float dr_dir = 1;
241 constexpr float dr_min = defaultCoreRadius * 1.0f-animCoreRadiusHalfStep;
242 constexpr float dr_max = defaultCoreRadius * 1.0f+animCoreRadiusHalfStep;
243 const float dt = (float)(when - m_tlast).to_ms() / 1000.0f;
244 float r = m_uCoreRadius.scalar() + animCoreRadiusHalfStep * dt * dr_dir;
245 if( r <= dr_min ) {
246 dr_dir = 1;
247 r = dr_min;
248 } else if( r >= dr_max ) {
249 dr_dir = -1;
250 r = dr_max;
251 }
252 m_uCoreRadius.scalar() = r;
253 }
254 m_st.send(gl, m_uCoreRadius);
255 if( m_once ) {
256 std::cerr << "XXX: " << m_st << "\n";
257 m_once = false;
258 }
259
260 if( true ) {
261 ::glEnable(GL_BLEND);
262 ::glBlendEquation(GL_FUNC_ADD); // default
263 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
264 }
265
266 // Draw a square
267 ::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
268 m_st.useProgram(gl, false);
269
270 m_tlast = when;
271 }
272
273 std::string toStringImpl() const noexcept override { return "SolInSpace"; }
274};
275
276int main(int argc, char *argv[]) // NOLINT(bugprone-exception-escape)
277{
278 return launch("SolInSpace",
280 std::make_shared<Example>(), argc, argv);
281}
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerSRef &demo, int argc, char *argv[])
int main(int argc, char *argv[])
void reshape(const WindowSRef &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.
void display(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
PMVMat4f & pmv() noexcept
bool m_once
bool init(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
const Recti & viewport() const noexcept
const PMVMat4f & pmv() const noexcept
void updateSolSpatial(GL &gl)
Recti & viewport() noexcept
std::string toStringImpl() const noexcept override
void dispose(const WindowSRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
Specifies a set of OpenGL capabilities.
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 server_sref createGLSL(std::string_view name, GLsizei compsPerElement, bool normalized, GLsizei initialElementCount, GLenum vboUsage)
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)
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
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:131
void addKeyListener(const KeyListenerSRef &l)
Definition Window.hpp:310
void dispose(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:355
size_t removeKeyListener(const KeyListenerSRef &l)
Definition Window.hpp:311
std::string toString() const noexcept
Definition gamp_wt.cpp:145
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:368
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition vec3f.hpp:252
#define E_FILE_LINE
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
GLArrayDataServerSRef< float > GLFloatArrayDataServerSRef
std::shared_ptr< ShaderCode > ShaderCodeSRef
std::shared_ptr< ShaderProgram > ShaderProgramSRef
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowSRef
Definition Event.hpp:36
Vector4F< float > Vec4f
Definition vec4f.hpp:360
RectI< int > Recti
Definition recti.hpp:146
Vector3F< float > Vec3f
Definition vec3f.hpp:422
PMVMatrix4< float > PMVMat4f
Definition pmvmat4.hpp:1463
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
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.