104static void printOutlineShape(
const std::string &tag,
const OutlineShape& o,
size_t idx=0) {
108 printf(
" - Outline [%2zu][%2zu]:\n", idx, o_idx);
109 for(
const Vertex& v : ol.vertices()){
110 printf(
" - V[%2zu][%2zu]: %s\n", idx, o_idx, v.coord().toString());
116static void printOutlineShapes(
const std::string &tag,
const std::vector<OutlineShape>& oshapes) {
117 printf(
"%s: %zu OutlineShapes\n", tag, oshapes.size());
120 printOutlineShape(tag, o, os_idx);
139 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
143 GLUniformSyncPMVMat4f m_pmvMat;
144 GLUniformVec3f m_light0Pos;
145 GLUniformVec4f m_staticColor;
149 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
155 m_pmvMat(
"gcu_PMVMatrix", mat_req),
156 m_light0Pos(
"gcu_Light0Pos", lightPos),
157 m_staticColor(
"gcu_StaticColor",
Vec4f(0, 0, 0, 1)),
160 m_st.manage(m_pmvMat);
161 m_st.manage(m_light0Pos);
162 m_st.manage(m_staticColor);
165 constexpr bool initialized() const noexcept {
return m_initialized; }
172 "demos/glsl/bin",
"SingleLight0");
174 "demos/glsl/bin",
"SingleLight0");
175 if( !rsVp || !rsFp ) {
180 std::string custom =
"#define MAX_TEXTURE_UNITS 0\n";
187 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
192 m_st.attachShaderProgram(
gl, sp0,
true);
195 pmv.getP().loadIdentity();
196 pmv.getMv().loadIdentity();
198 m_st.send(
gl, m_pmvMat);
199 m_st.send(
gl, m_light0Pos);
200 m_st.send(
gl, m_staticColor);
202 m_initialized = sp0->
inUse();
203 if( !m_initialized ) {
207 return m_initialized;
211 m_st.destroyShaderProgram(
gl);
215 m_st.useProgram(
gl, on);
219 m_st.send(
gl, m_staticColor);
222 m_st.send(
gl, m_pmvMat);
225 m_st.send(
gl, m_pmvMat);
226 m_st.send(
gl, m_staticColor);
230 const Vec4f&
color() const noexcept {
return m_staticColor.vec4f(); }
248 : m_renderer(renderer),
249 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)) {
250 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
251 if( m_renderer.usesNormal() ) {
252 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
254 m_renderer.st().manage(m_array);
258 constexpr bool initialized() const noexcept {
return m_renderer.initialized(); }
261 m_renderer.st().destroyAllData(
gl);
269 m_array->seal(
gl, seal_);
270 m_array->enableBuffer(
gl,
false);
291 m_segments.insert(m_segments.cend(), segs.cbegin(), segs.cend());
301 static bool once =
true;
310 m_renderer.useProgram(
gl,
true);
312 m_array->enableBuffer(
gl,
true);
314 ::glEnable(GL_BLEND);
315 ::glBlendEquation(GL_FUNC_ADD);
316 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
319 ::glDrawArrays(s.type, s.first, s.count);
322 m_array->enableBuffer(
gl,
false);
333 float m_zOffset = 0.0f;
344 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
345 constexpr float&
zOffset() noexcept {
return m_zOffset; }
353 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
357 bool hasPos = !m_position.is_zero();
359 bool hasRotate = !m_rotation.isIdentity();
360 bool hasRotPivot =
false;
362 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
364 if( sameScaleRotatePivot ) {
366 iMat.setToTranslation(m_position);
368 iMat.translate(
Vec3f(ctr).mul(m_scale));
369 iMat.rotate(m_rotation);
371 iMat.translate(-ctr);
372 }
else if( hasRotate || hasScale ) {
374 iMat.setToTranslation(m_position);
378 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
379 iMat.rotate(m_rotation);
380 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
383 iMat.translate(
Vec3f(ctr).mul(m_scale));
384 iMat.rotate(m_rotation);
385 iMat.translate(
Vec3f(-ctr).mul(m_scale));
390 iMat.translate(
Vec3f(ctr).mul(m_scale));
392 iMat.translate(
Vec3f(-ctr).mul(m_scale));
394 }
else if( hasPos ) {
396 iMat.setToTranslation(m_position);
414 std::vector<OutlineShape> m_oshapes;
426 bool iMatIdent =
true;
427 bool iMatDirty =
false;
429 struct Private{
explicit Private() =
default; };
433 m_sstate = m_sstateOrigin;
438 : m_renderer(renderer), m_region(m_renderer)
443 return std::make_shared<Shape>(Private(), renderer);
447 m_region.destroy(
gl);
460 constexpr const Vec3f&
position() const noexcept {
return m_sstate.position(); }
461 constexpr Vec3f&
position() noexcept { iMatDirty=
true;
return m_sstate.position(); }
464 constexpr const float&
zOffset() const noexcept {
return m_sstate.zOffset(); }
465 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_sstate.zOffset(); }
467 constexpr const Quat4f&
rotation() const noexcept {
return m_sstate.rotation(); }
468 constexpr Quat4f&
rotation() noexcept { iMatDirty=
true;
return m_sstate.rotation(); }
476 constexpr const std::vector<OutlineShape>&
outlineShapes() const noexcept {
return m_oshapes; }
477 constexpr std::vector<OutlineShape>&
outlineShapes() noexcept {
return m_oshapes; }
486 m_region.addOutlineShape(o);
487 m_bounds.resize(o.
bounds());
489 m_region.seal(
gl,
true);
490 m_sstateOrigin = m_sstate;
498 m_renderer.setColor(m_color);
499 m_renderer.updateAll(
gl);
521 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
537 constexpr float veloScalar() const noexcept {
return m_velo; }
540 void setVelo(
float v)
noexcept { m_velo = v; }
541 void addVelo(
float v)
noexcept { m_velo += v; }
549 constexpr float veloScalar() const noexcept {
return m_velo.length(); }
562 float m_zAxisDirRotationOffset = 0;
571 return std::make_shared<Ship>(Shape::Private(), renderer);
592 orientation.rotateByAngleZ(m_zAxisDirRotationOffset);
596 void setVelo(
float v)
noexcept { m_velo.setVelo(v); }
597 void addVelo(
float v)
noexcept { m_velo.addVelo(v); }
608 constexpr static float zNear= 1.0f;
609 constexpr static float zFar =100.0f;
614 bool m_animating =
true;
618 std::vector<ShapeRef> m_shapes;
627 m_initialized(false),
629 m_ship1(
Ship::createShared(m_renderer)),
631 m_light0Pos(
"gcu_Light0Pos", m_renderer.lightPosition().vec3f()),
632 m_staticColor(
"gcu_StaticColor",
Vec4f(0.05f, 0.05f, 0.5f, 1))
634 m_st.manage(m_pmvMat);
635 m_st.manage(m_light0Pos);
636 m_st.manage(m_staticColor);
641 std::vector<ShapeRef>&
shapes() noexcept {
return m_shapes; }
653 if( !m_renderer.init(
gl, when) ) {
661 m_ship1->setColor(
Vec4f(0.05f, 0.05f, 0.5f, 1.0f));
665 m_shapes.push_back(m_ship1);
669 m_shapes.push_back(frontShape);
670 std::vector<OutlineShape>& oshapes = frontShape->
outlineShapes();
675 oshapes.push_back(back);
681 frontShape->
scale().
x *= 2.0f;
682 frontShape->
scale().
y *= 2.0f;
685 ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
686 ::glEnable(GL_DEPTH_TEST);
688 ::glDisable(GL_CULL_FACE);
690 m_initialized =
true;
691 if( !m_initialized ) {
696 return m_initialized;
706 m_renderer.destroy(
gl);
708 m_initialized =
false;
718 const float aspect = 1.0f;
719 const float fovy_deg=45.0f;
720 const float aspect2 = ( (float) m_viewport.width() / (
float) m_viewport.height() ) / aspect;
725 m_st.useProgram(
gl,
true);
730 static bool once =
true;
735 if( !m_initialized ) {
739 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
741 m_st.useProgram(
gl,
true);
743 const float dt = float( (when - m_tlast).to_double() );
761 std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
766 class MyKeyListener :
public KeyListener {
770 MyKeyListener(
Game& p) : m_parent(p) {}
772 void keyPressed(KeyEvent& e, [[maybe_unused]]
const KeyboardTracker& kt)
override {
773 if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
779 }
else if( e.
keySym() == VKeyCode::VK_R) {
781 m_parent.ship1()->reset();
782 }
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
784 m_parent.animating() = !m_parent.animating();
785 }
else if( e.
keySym() == VKeyCode::VK_W ) {
788 }
else if( e.
keySym() == VKeyCode::VK_UP ) {
789 m_parent.ship1()->rotation().rotateByAngleX(-
jau::PI<float> / 50);
790 }
else if( e.
keySym() == VKeyCode::VK_DOWN ) {
791 m_parent.ship1()->rotation().rotateByAngleX(
jau::PI<float> / 50);
792 }
else if( e.
keySym() == VKeyCode::VK_RIGHT) {
793 m_parent.ship1()->rotation().rotateByAngleY(
jau::PI<float> / 50);
794 }
else if( e.
keySym() == VKeyCode::VK_LEFT ) {
795 m_parent.ship1()->rotation().rotateByAngleY(-
jau::PI<float> / 50);
796 }
else if( e.
keySym() == VKeyCode::VK_A ) {
797 m_parent.ship1()->addVelo(0.1f);
798 }
else if( e.
keySym() == VKeyCode::VK_S ) {
799 m_parent.ship1()->addVelo(-0.1f);
803 void keyReleased([[maybe_unused]] KeyEvent& e, [[maybe_unused]]
const KeyboardTracker& kt)
override {
807 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
808 MyKeyListenerRef m_kl;
813 m_kl(
std::make_shared<MyKeyListener>(*this)) { }
828int main(
int argc,
char *argv[])
830 return launch(
"PrimitivesCobraMK3.cpp",
834 std::make_shared<Example>(), argc, argv);
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerSRef &demo, int argc, char *argv[])
std::shared_ptr< Shape > ShapeRef
int main(int argc, char *argv[])
std::shared_ptr< Ship > ShipRef
std::shared_ptr< Shape > ShapeRef
bool init(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
void dispose(const WindowSRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
Recti & viewport() noexcept
bool init(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
void dispose(const WindowSRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
ShipRef & ship1() noexcept
std::vector< ShapeRef > & shapes() noexcept
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.
bool animating() const noexcept
void display(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
bool & animating() noexcept
const Recti & viewport() const noexcept
std::string toStringImpl() const noexcept override
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
constexpr bool initialized() const noexcept
void addOutlineShape(OutlineShape &shape)
GraphRegion(GraphRenderer &renderer)
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void seal(GL &gl, bool seal_)
ShaderState & st() noexcept
bool init(GL &gl, const jau::fraction_timespec &when)
const PMVMat4f & pmv() const noexcept
GLUniformVec3f & lightPosition() noexcept
constexpr GLsizei arrayCompsPerElement() const noexcept
const Vec4f & color() const noexcept
constexpr bool initialized() const noexcept
constexpr bool usesNormal() const noexcept
const ShaderState & st() const noexcept
const GLUniformVec3f & lightPosition() const noexcept
PMVMat4f & pmv() noexcept
GraphRenderer(ShaderState &st)
void useProgram(GL &gl, bool on)
void setColor(const Vec4f &c) noexcept
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
void resetSpatial() noexcept
Shape(Private, GraphRenderer &renderer)
constexpr Vec3f & position() noexcept
constexpr std::vector< OutlineShape > & outlineShapes() noexcept
static ShapeRef createShared(ShaderState &st, GraphRenderer &renderer)
virtual void destroy(GL &gl)
constexpr const std::vector< OutlineShape > & outlineShapes() const noexcept
constexpr const Quat4f & rotation() const noexcept
constexpr void set_position(Vec3f new_pos) noexcept
const AABBox3f & bounds() const noexcept
Shape(Private, ShaderState &st, GraphRenderer &renderer)
constexpr const Vec3f & rotationPivot() const noexcept
virtual void clear(GL &gl)
constexpr float & zOffset() noexcept
SpatialState & spatialState() 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
const SpatialState & spatialState() const noexcept
virtual ~Shape() noexcept=default
constexpr Quat4f & rotation() noexcept
Vec3f getDir() const noexcept
void setVelo(float v) noexcept
Vec3f velo() const noexcept
Ship(Shape::Private, GraphRenderer &renderer)
void destroy(GL &gl) override
static ShipRef createShared(GraphRenderer &renderer)
void tick(float dt) override
void addVelo(float v) noexcept
void setOriginZRotation(float v) noexcept
Set z-axis rotation offset of movement orientation.
void clear(GL &gl) override
A Generic shape objects which is defined by a list of Outlines.
const AABBox3f & bounds() const noexcept
const OutlineList & outlines() const noexcept
std::string toString() const noexcept
OutlineShape flipFace(float zoffset=0) const
Returns a copy of this instance with normal() pointing to the opposite direction and all outlines() v...
Define a single continuous stroke by control vertices.
GLUtilTesselator transform OutlineShapes to triangles using glutess2.
std::vector< Segment > SegmentList
static SegmentList tesselate(int flags, GLFloatArrayDataServer &array, OutlineShape &outlines)
static constexpr int FLAG_NORMAL
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.
static constexpr std::string_view GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
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 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 ...
constexpr RenderListener(Private) noexcept
Private ctor for shared_ptr<RenderListener> instance method w/o public ctor.
std::string toString() const noexcept
const gamp::render::RenderContext * renderContext() const noexcept
void addKeyListener(const KeyListenerSRef &l)
void dispose(const jau::fraction_timespec &when) noexcept override
size_t removeKeyListener(const KeyListenerSRef &l)
std::string toString() const noexcept
std::string toString() const noexcept
constexpr VKeyCode keySym() const noexcept
Returns the virtual key symbol reflecting the current keyboard layout.
constexpr const WindowWeakPtr & source() const noexcept
constexpr const jau::fraction_timespec & when() const noexcept
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
constexpr size_type size() const noexcept
Like std::vector::size().
constexpr Matrix4 & loadIdentity() noexcept
Set this matrix to identity.
constexpr Vector3F & scale(const value_type s) noexcept
this = this * s, component wise.
static constexpr const value_type one
Axis Aligned Bounding Box.
constexpr const Point3f & center() const noexcept
Returns computed center of this aabbox3f of low() and high().
constexpr Mat4 & getP() noexcept
Returns the projection matrix (P).
constexpr PMVMatrix4 & translateMv(float x, float y, float z) noexcept
Translate the modelview matrix.
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
PMVMatrix4 & perspectiveP(const float fovy_rad, const float aspect, const float zNear, const float zFar)
Multiply the projection matrix with the perspective/frustum matrix.
constexpr Mat4 & getMv() noexcept
Returns the modelview matrix (Mv).
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
#define jau_PLAIN_PRINT(printPrefix, fmt,...)
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
#define jau_fprintf_td2(elapsed_ms, stream, fmt,...)
std::shared_ptr< Shape > ShapeRef
constexpr T PI
Alias for π or half-circle radians (180 degrees), i.e. std::numbers::pi_v<T>
constexpr T PI_4
Alias for π/4 or half right-angle radians (45 degrees), i.e. std::numbers::pi_v<T>/T(4)
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
constexpr T PI_2
Alias for π/2 or right-angle radians (90 degrees), i.e. std::numbers::pi_v<T>/T(2)
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
std::shared_ptr< ShaderCode > ShaderCodeSRef
std::shared_ptr< ShaderProgram > ShaderProgramSRef
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowSRef
constexpr orientation_t orientation(const Point2f &a, const Point2f &b, const Point2f &c) noexcept
Return the orientation of the given point triplet a, b and c using triArea()
PMVData
PMVMatrix4 derived matrices and values.
Quaternion< float > Quat4f
PMVMatrix4< float > PMVMat4f
@ inv_mv
Bit value for inverse modelview matrix (Mvi), updated via update().
@ inv_proj
Bit value for inverse projection matrix (Pi), updated via update().
@ inv_tps_mv
Bit value for inverse transposed modelview matrix (Mvit), updated via update().
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
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...
void appendCobraMkIII(std::vector< OutlineShape > &oshapes, const float height=1.0f, const float width=2.0f, const float deep=0.3f)
bool m_hasFrustumClipping
constexpr const float & zOffset() const noexcept
SpatialState() noexcept=default
constexpr float & zOffset() noexcept
constexpr Quat4f & rotation() noexcept
constexpr const Quat4f & rotation() const noexcept
constexpr Vec3f & rotationPivot() noexcept
constexpr const Vec3f & position() const noexcept
void updateMat(const Vec3f &ctr, Mat4f &iMat, bool &iMatIdent) const noexcept
constexpr Vec3f & scale() noexcept
constexpr Vec3f & position() noexcept
constexpr void set_position(Vec3f new_pos) noexcept
constexpr const Vec3f & rotationPivot() const noexcept
constexpr const Vec3f & scale() const noexcept
void setVelo(float v) noexcept
const Vec3f velo(const Vec3f &dir) const noexcept
constexpr float veloScalar() const noexcept
void addVelo(float v) noexcept
void addVelo(Vec3f dir, float v) noexcept
void setVelo(Vec3f dir, float v) noexcept
const Vec3f & velo() const noexcept
constexpr float veloScalar() const noexcept
static std::string toString(const std::string &pre, const SegmentList &segments) noexcept
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.
int printf(const char *format,...)
Operating Systems predefined macros.