103static void printOutlineShape(
const std::string &tag,
const OutlineShape& o,
size_t idx=0) {
107 printf(
" - Outline [%2zu][%2zu]:\n", idx, o_idx);
108 for(
const Vertex& v : ol.vertices()){
109 printf(
" - V[%2zu][%2zu]: %s\n", idx, o_idx, v.coord().toString().c_str());
115static void printOutlineShapes(
const std::string &tag,
const std::vector<OutlineShape>& oshapes) {
116 printf(
"%s: %zu OutlineShapes\n", tag.c_str(), oshapes.size());
119 printOutlineShape(tag, o, os_idx);
138 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
142 GLUniformSyncPMVMat4f m_pmvMat;
143 GLUniformVec3f m_light0Pos;
144 GLUniformVec4f m_staticColor;
148 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
154 m_pmvMat(
"gcu_PMVMatrix", mat_req),
155 m_light0Pos(
"gcu_Light0Pos", lightPos),
156 m_staticColor(
"gcu_StaticColor",
Vec4f(0, 0, 0, 1)),
159 m_st.manage(m_pmvMat);
160 m_st.manage(m_light0Pos);
161 m_st.manage(m_staticColor);
164 constexpr bool initialized() const noexcept {
return m_initialized; }
171 "demos/glsl/bin",
"SingleLight0");
173 "demos/glsl/bin",
"SingleLight0");
174 if( !rsVp || !rsFp ) {
179 std::string custom =
"#define MAX_TEXTURE_UNITS 0\n";
186 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
191 m_st.attachShaderProgram(
gl, sp0,
true);
194 pmv.getP().loadIdentity();
195 pmv.getMv().loadIdentity();
197 m_st.send(
gl, m_pmvMat);
198 m_st.send(
gl, m_light0Pos);
199 m_st.send(
gl, m_staticColor);
201 m_initialized = sp0->
inUse();
202 if( !m_initialized ) {
206 return m_initialized;
210 m_st.destroyShaderProgram(
gl);
214 m_st.useProgram(
gl, on);
218 m_st.send(
gl, m_staticColor);
221 m_st.send(
gl, m_pmvMat);
224 m_st.send(
gl, m_pmvMat);
225 m_st.send(
gl, m_staticColor);
229 const Vec4f&
color() const noexcept {
return m_staticColor.vec4f(); }
248 : m_renderer(renderer),
250 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)) {
251 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
252 if( m_renderer.usesNormal() ) {
253 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
255 m_renderer.st().manage(m_array);
259 constexpr bool initialized() const noexcept {
return m_initialized; }
262 m_renderer.st().destroyAllData(
gl);
267 if( !m_initialized ) {
270 m_array->seal(
gl, seal_);
271 m_array->enableBuffer(
gl,
false);
276 if( !m_initialized ) {
288 m_segments.insert(m_segments.cend(), segs.cbegin(), segs.cend());
298 if( !m_initialized ) {
301 m_renderer.useProgram(
gl,
true);
303 m_array->enableBuffer(
gl,
true);
305 ::glEnable(GL_BLEND);
306 ::glBlendEquation(GL_FUNC_ADD);
307 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
310 ::glDrawArrays(s.type, s.first, s.count);
313 m_array->enableBuffer(
gl,
false);
323 std::vector<OutlineShape> m_oshapes;
329 float m_zOffset = 0.0f;
336 bool iMatIdent =
true;
337 bool iMatDirty =
false;
341 struct Private{
explicit Private() =
default; };
345 : m_renderer(renderer), m_region(m_renderer)
347 std::cerr <<
"XXX ctor.x " << m_renderer.st() <<
"\n";
351 return std::make_shared<Shape>(Private(), renderer);
355 m_region.destroy(
gl);
362 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
363 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
371 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
372 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
374 constexpr const std::vector<OutlineShape>&
outlineShapes() const noexcept {
return m_oshapes; }
375 constexpr std::vector<OutlineShape>&
outlineShapes() noexcept {
return m_oshapes; }
382 m_region.addOutlineShape(o);
384 m_region.seal(
gl,
true);
392 m_renderer.setColor(m_color);
393 m_renderer.updateAll(
gl);
403 m_rotation.rotateByAngleZ( M_PI_2);
404 Vec3f dir = m_rotation.rotateVector(
Vec3f(1, 0, 0));
405 m_rotation.rotateByAngleZ(-M_PI_2);
406 Vec3f d_p = dir * m_velo * dt;
410 float&
velo() noexcept {
return m_velo; }
427 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
435 void updateMat() noexcept {
436 bool hasPos = !m_position.is_zero();
438 bool hasRotate = !m_rotation.isIdentity();
439 bool hasRotPivot =
false;
440 for(OutlineShape& o : m_oshapes){
442 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
444 if( sameScaleRotatePivot ) {
446 iMat.setToTranslation(m_position);
448 iMat.translate(
Vec3f(ctr).mul(m_scale));
449 iMat.rotate(m_rotation);
451 iMat.translate(-ctr);
452 }
else if( hasRotate || hasScale ) {
454 iMat.setToTranslation(m_position);
458 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
459 iMat.rotate(m_rotation);
460 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
463 iMat.translate(
Vec3f(ctr).mul(m_scale));
464 iMat.rotate(m_rotation);
465 iMat.translate(
Vec3f(-ctr).mul(m_scale));
470 iMat.translate(
Vec3f(ctr).mul(m_scale));
472 iMat.translate(
Vec3f(-ctr).mul(m_scale));
474 }
else if( hasPos ) {
476 iMat.setToTranslation(m_position);
489 constexpr static float zNear= 1.0f;
490 constexpr static float zFar =100.0f;
495 bool m_animating =
true;
496 bool m_oneframe =
false;
499 std::vector<ShapeRef> m_shapes;
508 m_initialized(false),
511 m_light0Pos(
"gcu_Light0Pos", m_renderer.lightPosition().vec3f()),
512 m_staticColor(
"gcu_StaticColor",
Vec4f(0.05f, 0.05f, 0.5f, 1))
514 m_st.manage(m_pmvMat);
515 m_st.manage(m_light0Pos);
516 m_st.manage(m_staticColor);
521 std::vector<ShapeRef>&
shapes() noexcept {
return m_shapes; }
525 void setOneFrame() noexcept { m_animating=
false; m_oneframe=
true; }
533 if( !m_renderer.init(
gl, when) ) {
542 cobraMkIII_Shape->setColor(
Vec4f(0.05f, 0.05f, 0.5f, 1.0f));
543 cobraMkIII_Shape->rotation().rotateByAngleX(-M_PI / 4.0f);
544 cobraMkIII_Shape->update(
gl);
545 m_shapes.push_back(cobraMkIII_Shape);
548 m_shapes.push_back(frontShape);
549 std::vector<OutlineShape>& oshapes = frontShape->outlineShapes();
554 oshapes.push_back(back);
556 frontShape->update(
gl);
557 frontShape->setColor(
Vec4f(0.05f, 0.5f, 0.05f, 1));
558 frontShape->position().x = 1.5f;
559 frontShape->position().y = 0.5f;
560 frontShape->scale().x *= 2.0f;
561 frontShape->scale().y *= 2.0f;
564 ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
565 ::glEnable(GL_DEPTH_TEST);
567 ::glDisable(GL_CULL_FACE);
569 m_initialized =
true;
570 if( !m_initialized ) {
575 return m_initialized;
584 m_renderer.destroy(
gl);
586 m_initialized =
false;
596 const float aspect = 1.0f;
597 const float fovy_deg=45.0f;
598 const float aspect2 = ( (float) m_viewport.width() / (
float) m_viewport.height() ) / aspect;
603 m_st.useProgram(
gl,
true);
609 if( !m_initialized ) {
613 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
615 m_st.useProgram(
gl,
true);
617 const float dt = float( (when - m_tlast).to_double() );
619 if( (
animating() || m_oneframe) && s != m_shapes[0]) {
620 constexpr float angle_per_sec = 30;
621 const float rad = dt * angle_per_sec;
633 std::cerr <<
"XXX draw " << m_st <<
"\n";
641 std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
646 class MyKeyListener :
public KeyListener {
652 void keyPressed(KeyEvent& e,
const KeyboardTracker& kt)
override {
654 std::vector<ShapeRef>& shapeList = m_parent.shapes();
655 if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
660 }
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
661 m_parent.animating() = !m_parent.animating();
662 }
else if( e.
keySym() == VKeyCode::VK_PERIOD ) {
663 m_parent.setOneFrame();
664 }
else if( e.
keySym() == VKeyCode::VK_W ) {
667 }
else if( e.
keySym() == VKeyCode::VK_UP ) {
668 shapeList[0]->rotation().rotateByAngleX(-M_PI / 50);
669 }
else if( e.
keySym() == VKeyCode::VK_DOWN ) {
670 shapeList[0]->rotation().rotateByAngleX( M_PI / 50);
671 }
else if( e.
keySym() == VKeyCode::VK_SHIFT ) {
672 shapeList[0]->velo() += 0.1f;
673 }
else if( e.
keySym() == VKeyCode::VK_ENTER ) {
674 shapeList[0]->velo() = std::max(shapeList[0]->velo() - 0.1f, 0.0f);
675 }
else if( e.
keySym() == VKeyCode::VK_RIGHT) {
676 shapeList[0]->rotation().rotateByAngleY( M_PI / 50);
677 }
else if( e.
keySym() == VKeyCode::VK_LEFT ) {
678 shapeList[0]->rotation().rotateByAngleY(-M_PI / 50);
681 void keyReleased(KeyEvent& e,
const KeyboardTracker& kt)
override {
685 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
686 MyKeyListenerRef m_kl;
691 m_kl(
std::make_shared<MyKeyListener>(*this)) { }
706int main(
int argc,
char *argv[])
708 return launch(
"Primitives03.cpp",
711 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< 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,...
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
bool init(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
bool & animating() noexcept
Recti & viewport() noexcept
std::string toStringImpl() const noexcept override
void setOneFrame() noexcept
void display(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
bool animating() const noexcept
std::vector< ShapeRef > & shapes() noexcept
const Recti & viewport() const noexcept
void dispose(const WindowSRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
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.
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
static ShapeRef createShared(ShaderState &st, GraphRenderer &renderer)
constexpr const std::vector< OutlineShape > & outlineShapes() const noexcept
constexpr const Quat4f & rotation() const noexcept
constexpr void set_position(Vec3f new_pos) noexcept
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
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() and all outlines() vertices()'s z-axis sign-flipped,...
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
static constexpr int FLAG_VERBOSE
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.
virtual const PressedKeyCodes & pressedKeyCodes() const noexcept=0
constexpr const WindowWeakPtr & source() const noexcept
constexpr const jau::fraction_timespec & when() const noexcept
size_type count() 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.
static constexpr const value_type one
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.
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
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
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,...
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, std::string_view format, const Args &...args) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
void appendCobraMkIII(std::vector< OutlineShape > &oshapes, const float height=1.0f, const float width=2.0f, const float deep=0.3f)
bool m_hasFrustumClipping
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.