Gamp v0.0.7-54-gccdc599
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/vec4f.hpp>
23
24#include <gamp/Gamp.hpp>
26
31
33
34using namespace jau::math;
35using namespace jau::math::util;
36
37using namespace gamp::wt;
38using namespace gamp::wt::event;
39using namespace gamp::render::gl::glsl;
40using namespace gamp::render::gl::data;
41
42class Example : public RenderListener {
43 public:
44 static constexpr float radius = 1.00f;
45 static constexpr float coreRadius = 0.20f;
46 static constexpr float coreRadiusHalfStep = 0.015f;
47
48 private:
49 ShaderState m_st;
50 Recti m_viewport;
51 GLUniformSyncPMVMat4fRef m_pmvMatUni;
52
53 GLUniformVec4fRef m_uWinCenter;
54 GLUniformVec4fRef m_uCoreColor, m_uHaloColor, m_uBackColor;
55 GLUniformScalarF32Ref m_uWinRadius, m_uCoreRadius, m_uSeam;
56
57 bool m_initialized;
59
60 class MyKeyListener : public KeyListener {
61 public:
62 MyKeyListener(Example &) { }
63
64 void keyPressed(KeyEvent &e, const KeyboardTracker &kt) override {
65 jau::fprintf_td(e.when().to_ms(), stdout, "KeyPressed: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
66 if (e.keySym() == VKeyCode::VK_ESCAPE) {
67 WindowRef win = e.source().lock();
68 if (win) {
69 win->dispose(e.when());
70 }
71 } else if (e.keySym() == VKeyCode::VK_W) {
72 WindowRef win = e.source().lock();
73 jau::fprintf_td(e.when().to_ms(), stdout, "Source: %s\n", win ? win->toString().c_str() : "null");
74 }
75 }
76 void keyReleased(KeyEvent &e, const KeyboardTracker &kt) override {
77 jau::fprintf_td(e.when().to_ms(), stdout, "KeyRelease: %s; keys %zu\n", e.toString().c_str(), kt.pressedKeyCodes().count());
78 }
79 };
80 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
82
83 public:
84
87 m_pmvMatUni(GLUniformSyncPMVMat4f::create("gcu_PMVMatrix")),
88 m_uWinCenter(GLUniformVec4f::create("gcu_solInSpace.winCenter", Vec4f())),
89 m_uCoreColor(GLUniformVec4f::create("gcu_solInSpace.coreColor", Vec4f(1.0f, 1.0f, 0.0f, 1.0f))),
90 m_uHaloColor(GLUniformVec4f::create("gcu_solInSpace.haloColor", Vec4f(1.0f, 0.99f, 0.0f, 1.0f))),
91 m_uBackColor(GLUniformVec4f::create("gcu_solInSpace.bgColor", Vec4f(0.0f, 0.0f, 0.0f, 0.5f))),
92 m_uWinRadius(GLUniformScalarF32::create("gcu_solInSpace.winRadius", 0)),
93 m_uCoreRadius(GLUniformScalarF32::create("gcu_solInSpace.coreRadius", coreRadius)),
94 m_uSeam(GLUniformScalarF32::create("gcu_solInSpace.seam", 0.005f)),
95 m_initialized(false),
96 m_kl(std::make_shared<MyKeyListener>(*this))
97 { }
98
99 Recti& viewport() noexcept { return m_viewport; }
100 const Recti& viewport() const noexcept { return m_viewport; }
101
102 PMVMat4f& pmv() noexcept { return m_pmvMatUni->pmv(); }
103 const PMVMat4f& pmv() const noexcept { return m_pmvMatUni->pmv(); }
104
105 bool init(const WindowRef& win, const jau::fraction_timespec& when) override {
107
108 jau::fprintf_td(when.to_ms(), stdout, "RL::init: %s\n", toString().c_str());
109 m_tlast = when;
110
111 GL& gl = GL::downcast(win->renderContext());
112 ShaderCodeRef vp0 = ShaderCode::create(gl, GL_VERTEX_SHADER, "demos/glsl",
113 "demos/glsl/bin", "default");
114 ShaderCodeRef fp0 = ShaderCode::create(gl, GL_FRAGMENT_SHADER, "demos/glsl",
115 "demos/glsl/bin", "SolInSpace");
116 if( !vp0 || !fp0 ) {
117 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
118 win->dispose(when);
119 return false;
120 }
124 if( !sp0->add(gl, vp0, true) || !sp0->add(gl, fp0, true) ) {
125 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
126 sp0->destroy(gl);
127 win->dispose(when);
128 return false;
129 }
130 m_st.attachShaderProgram(gl, sp0, true);
131
132 // setup mgl_PMVMatrix
133 PMVMat4f &pmv = m_pmvMatUni->pmv();
134 pmv.getP().loadIdentity();
135 pmv.getMv().loadIdentity();
136 m_st.ownUniform(m_pmvMatUni, true);
137
138 m_st.ownUniform(m_uWinCenter, true);
139 m_st.ownUniform(m_uCoreColor, true);
140 m_st.ownUniform(m_uHaloColor, true);
141 m_st.ownUniform(m_uBackColor, true);
142 m_st.ownUniform(m_uWinRadius, true);
143 m_st.ownUniform(m_uCoreRadius, true);
144 m_st.ownUniform(m_uSeam, true);
145
146 // ::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
147 // m_uBackColor->vec4f().set(1.0f, 1.0f, 1.0f, 0.5f);
148 ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
149 m_uBackColor->vec4f().set(0.0f, 0.0f, 0.0f, 0.5f);
150
151 // Allocate Vertex Array
152 GLFloatArrayDataServerRef vertices = GLFloatArrayDataServer::createGLSL("gca_Vertex", 3, false, 4, GL_STATIC_DRAW);
153 vertices->reserve(4); // reserve 4 elements (4x3 components) upfront, otherwise growIfNeeded is used
154 vertices->put( { -radius, radius, 0, // 1st vertex
155 radius, radius, 0, // burst transfer, instead of 4x `put3f` for single vertice-value
156 -radius, -radius, 0,
157 radius, -radius, 0 } );
158 m_st.ownAttribute(vertices, true);
159 vertices->seal(gl, true);
160
161 ::glEnable(GL_DEPTH_TEST);
162
163 m_initialized = sp0->inUse();
164 if( !m_initialized ) {
165 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d: %s\n", E_FILE_LINE, toString().c_str());
166 m_st.destroy(gl);
167 win->dispose(when);
168 }
169 m_st.pushAllUniforms(gl);
170 m_st.useProgram(gl, false);
171
172 win->addKeyListener(m_kl);
173 return m_initialized;
174 }
175
176 void dispose(const WindowRef& win, const jau::fraction_timespec& when) override {
177 jau::fprintf_td(when.to_ms(), stdout, "RL::dispose: %s\n", toString().c_str());
178 win->removeKeyListener(m_kl);
179 m_st.destroy(GL::downcast(win->renderContext()));
180 m_initialized = false;
181 }
182
183 void reshape(const WindowRef& win, const jau::math::Recti& viewport, const jau::fraction_timespec& when) override {
184 GL& gl = GL::downcast(win->renderContext());
185 jau::fprintf_td(when.to_ms(), stdout, "RL::reshape: %s\n", toString().c_str());
186 m_viewport = viewport;
187
188 const float aspect = 1.0f;
189 const float fovy_deg=45.0f;
190 const float aspect2 = ( (float) m_viewport.width() / (float) m_viewport.height() ) / aspect;
191 const float zNear=1.0f;
192 const float zFar=100.0f;
193 PMVMat4f &pmv = m_pmvMatUni->pmv();
194 pmv.setToPerspective(jau::adeg_to_rad(fovy_deg), aspect2, zNear, zFar);
195
196 m_st.useProgram(gl, true);
197 m_st.pushUniform(gl, m_pmvMatUni);
198 m_st.useProgram(gl, false);
199 }
200
201 bool m_once = true;
202
203 void display(const WindowRef& win, const jau::fraction_timespec& when) override {
204 // jau::fprintf_td(when.to_ms(), stdout, "RL::display: %s, %s\n", toString().c_str(), win->toString().c_str());
205 if( !m_initialized ) {
206 return;
207 }
208 GL& gl = GL::downcast(win->renderContext());
209 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
210
211 m_st.useProgram(gl, true);
212 PMVMat4f &pmv = m_pmvMatUni->pmv();
213 pmv.getMv().loadIdentity();
214 pmv.translateMv(0, 0, -3);
215
216 {
217 const Vec3f center(0,0,0);
218 Vec3f winCenter;
219 pmv.mapObjToWin(center, m_viewport, winCenter);
220 m_uWinCenter->vec4f().set(winCenter, 1.0f);
221
222 const Vec3f p1 = center + Vec3f(radius,0,0);
223 Vec3f winP1;
224 pmv.mapObjToWin(p1, m_viewport, winP1);
225 Vec3f winR = winP1 - winCenter;
226 m_uWinRadius->scalar() = winR.length();
227
228 static float dr_dir = 1;
229 constexpr float dr_min = coreRadius * 1.0f-coreRadiusHalfStep;
230 constexpr float dr_max = coreRadius * 1.0f+coreRadiusHalfStep;
231 const float dt = (float)(when - m_tlast).to_ms() / 1000.0f;
232 float r = m_uCoreRadius->scalar() + coreRadiusHalfStep * dt * dr_dir;
233 if( r <= dr_min ) {
234 dr_dir = 1;
235 r = dr_min;
236 } else if( r >= dr_max ) {
237 dr_dir = -1;
238 r = dr_max;
239 }
240 m_uCoreRadius->scalar() = r;
241 }
242 m_st.pushUniform(gl, m_pmvMatUni);
243 m_st.pushUniform(gl, m_uWinCenter);
244 m_st.pushUniform(gl, m_uWinRadius);
245 m_st.pushUniform(gl, m_uCoreRadius);
246 if( m_once ) {
247 std::cerr << "XXX: " << m_st << "\n";
248 m_once = false;
249 }
250
251 if( true ) {
252 ::glEnable(GL_BLEND);
253 ::glBlendEquation(GL_FUNC_ADD); // default
254 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
255 }
256
257 // Draw a square
258 ::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
259 m_st.useProgram(gl, false);
260
261 m_tlast = when;
262 }
263
264 std::string toStringImpl() const noexcept override { return "SolInSpace"; }
265};
266
267int main(int argc, char *argv[]) // NOLINT(bugprone-exception-escape)
268{
269 return launch("SolInSpace",
271 std::make_shared<Example>(), argc, argv);
272}
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerRef &demo, int argc, char *argv[])
std::shared_ptr< MyKeyListener > MyKeyListenerRef
int main(int argc, char *argv[])
#define E_FILE_LINE
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.
static constexpr float radius
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 constexpr float coreRadiusHalfStep
static constexpr float coreRadius
PMVMat4f & pmv() noexcept
bool m_once
void display(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
const Recti & viewport() const noexcept
const PMVMat4f & pmv() const noexcept
Recti & viewport() noexcept
std::string toStringImpl() const noexcept override
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_ref 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 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
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
Listener for multiple KeyEvent.
Definition KeyEvent.hpp:894
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
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition vec3f.hpp:252
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< GLUniformScalarF32 > GLUniformScalarF32Ref
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowRef
Definition Event.hpp:36
@ VK_ESCAPE
Constant for the ESCAPE function key.
Definition KeyEvent.hpp:129
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
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.