83 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
100 static constexpr std::string_view
source_dir =
"impl/graph/glsl";
101 static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
109 constexpr bool initialized() const noexcept {
return m_initialized; }
114 std::string vertexShaderName, fragmentShaderName;
116 if( m_props.m_isTwoPass ) {
117 vertexShaderName.append(
"-pass").append(m_props.m_pass1 ?
"1":
"2");
119 vertexShaderName.append(
"-single");
125 if( !rsVp || !rsFp ) {
132 if( posVp == std::string::npos || posFp == std::string::npos ) {
144 if( m_props.m_hasDiscard ) {
148 if( m_props.m_hasFrustumClipping ) {
157 if( m_props.m_hasLight0 ) {
161 if( m_props.m_hasColorChannel ) {
165 if( m_props.m_hasColorTexture ) {
175 if( posVp == std::string::npos ) {
183 if( posFp == std::string::npos ) {
188 if( posFp == std::string::npos ) {
193 if( posFp == std::string::npos ) {
197 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
199 if( posFp == std::string::npos ) {
211 std::string passS = m_props.m_pass1 ?
"-pass1-" :
"-pass2-";
214 jau::PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
217 if( posFp == std::string::npos ) {
222 if( posFp == std::string::npos ) {
227 if( m_props.m_hasColorTexture ) {
233 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
238 m_st.attachShaderProgram(
gl, sp0,
true);
240 m_st.pushAllUniforms(
gl);
242 m_initialized = sp0->
inUse();
243 if( !m_initialized ) {
247 return m_initialized;
251 m_st.useProgram(
gl, on);
265 int m_num_vertices, m_num_indices;
269 : m_renderer(renderer), m_st(st),
271 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
273 m_num_vertices(0), m_num_indices(0)
275 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
276 m_array->addGLSLSubArray(
"gca_CurveParam", 3, GL_ARRAY_BUFFER);
277 if( m_renderer.usesNormal() ) {
278 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
280 m_st.ownAttribute(m_array,
true);
284 constexpr bool initialized() const noexcept {
return m_initialized; }
287 if( !m_initialized ) {
290 m_array->seal(
gl, seal_);
291 m_indices->seal(
gl, seal_);
292 m_array->enableBuffer(
gl,
false);
293 m_indices->enableBuffer(
gl,
false);
298 m_array->put3f(v.
coord());
300 if( m_renderer.usesNormal() ) {
301 m_array->put3f(normal);
307 m_indices->putN(i, j, k);
311 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
319 jau::PLAIN_PRINT(
true,
"add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
331 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
332 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
334 uint32_t idxOffset = m_num_vertices;
335 if( vertsIn.
size() >= 3 ) {
339 for(
const Vertex& v : vertsIn) {
342 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() /
sizeof(uint32_t);
349 uint32_t tv0Idx = triInVertices[0].id();
350 if ( max_index - idxOffset > tv0Idx ) {
353 triInVertices[1].
id()+idxOffset,
354 triInVertices[2].
id()+idxOffset);
362 jau::PLAIN_PRINT(
true,
"add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
369 if( !m_initialized ) {
372 m_renderer.useProgram(
gl,
true);
374 m_array->enableBuffer(
gl,
true);
375 m_indices->bindBuffer(
gl,
true);
377 ::glEnable(GL_BLEND);
378 ::glBlendEquation(GL_FUNC_ADD);
379 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
381 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT,
nullptr);
384 m_indices->bindBuffer(
gl,
false);
385 m_array->enableBuffer(
gl,
false);
410 bool iMatIdent =
true;
411 bool iMatDirty =
false;
413 struct Private{
explicit Private() =
default; };
417 : m_st(st), m_pmvMatUni(
std::move(pmvMatU)), m_oshape(3, 16),
418 m_renderer(renderer), m_region(m_renderer, m_st)
421 m_st.ownUniform(m_uColor,
true);
425 return std::make_shared<Shape>(Private(), st, std::move(pmvMatU), renderer);
431 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
432 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
440 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
441 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
446 const Vec4f&
color() const noexcept {
return m_uColor->vec4f(); }
450 m_region.addOutlineShape(m_oshape);
451 m_region.seal(
gl,
true);
458 m_st.pushUniform(
gl, m_pmvMatUni);
460 m_st.pushUniform(
gl, m_uColor);
480 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
488 void updateMat() noexcept {
489 bool hasPos = !m_position.is_zero();
491 bool hasRotate = !m_rotation.isIdentity();
492 bool hasRotPivot =
false;
493 const Vec3f& ctr = m_oshape.bounds().center();
494 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
496 if( sameScaleRotatePivot ) {
498 iMat.setToTranslation(m_position);
500 iMat.translate(
Vec3f(ctr).mul(m_scale));
501 iMat.rotate(m_rotation);
503 iMat.translate(-ctr);
504 }
else if( hasRotate || hasScale ) {
506 iMat.setToTranslation(m_position);
510 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
511 iMat.rotate(m_rotation);
512 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
515 iMat.translate(
Vec3f(ctr).mul(m_scale));
516 iMat.rotate(m_rotation);
517 iMat.translate(
Vec3f(-ctr).mul(m_scale));
522 iMat.translate(
Vec3f(ctr).mul(m_scale));
524 iMat.translate(
Vec3f(-ctr).mul(m_scale));
526 }
else if( hasPos ) {
528 iMat.setToTranslation(m_position);
540 constexpr static float zNear= 1.0f;
541 constexpr static float zFar =100.0f;
547 bool m_animating =
true;
548 bool m_oneframe =
false;
552 std::vector<ShapeRef> m_shapes;
558 m_initialized(false),
568 const PMVMat4f&
pmv() const noexcept {
return m_pmvMatUni->pmv(); }
571 void setOneFrame() noexcept { m_animating=
false; m_oneframe=
true; }
581 pmv.getP().loadIdentity();
582 pmv.getMv().loadIdentity();
583 m_st.ownUniform(m_pmvMatUni,
true);
585 if( !m_renderer.init(
gl, when) ) {
592 m_st.ownUniform(lightU,
true);
593 m_st.pushAllUniforms(
gl);
595 const float lineWidth = 1/2.5f;
596 const float dz = 0.005f;
599 const float width = 1.5f;
600 const float height = 1.5f;
602 float lwh = lineWidth/2.0f;
604 float twh = width/2.0f;
605 float thh = height/2.0f;
607 float ctrX = 0, ctrY = 0, ctrZ = dz;
609 m_shapes.push_back(frontShape);
612 oshape.
moveTo(ctrX-lwh, ctrY+thh, ctrZ);
613 oshape.
lineTo(ctrX-lwh, ctrY+lwh, ctrZ);
614 oshape.
lineTo(ctrX-twh, ctrY+lwh, ctrZ);
615 oshape.
lineTo(ctrX-twh, ctrY-lwh, ctrZ);
616 oshape.
lineTo(ctrX-lwh, ctrY-lwh, ctrZ);
617 oshape.
lineTo(ctrX-lwh, ctrY-thh, ctrZ);
618 oshape.
lineTo(ctrX+lwh, ctrY-thh, ctrZ);
619 oshape.
lineTo(ctrX+lwh, ctrY-lwh, ctrZ);
620 oshape.
lineTo(ctrX+twh, ctrY-lwh, ctrZ);
621 oshape.
lineTo(ctrX+twh, ctrY+lwh, ctrZ);
622 oshape.
lineTo(ctrX+lwh, ctrY+lwh, ctrZ);
623 oshape.
lineTo(ctrX+lwh, ctrY+thh, ctrZ);
624 oshape.
lineTo(ctrX-lwh, ctrY+thh, ctrZ);
632 m_shapes.push_back(backShape);
641 m_shapes.push_back(frontShape);
644 oshape.
moveTo(0.0f,-10.0f, 0);
645 oshape.
lineTo(15.0f,-10.0f, 0);
646 oshape.
quadTo(10.0f,5.0f,0, 15.0f,10.0f,0);
647 oshape.
cubicTo(6.0f,15.0f,0, 5.0f,8.0f,0, 0.0f,10.0f,0);
650 oshape.
moveTo(5.0f,-5.0f,0);
651 oshape.
quadTo(10.0f,-5.0f,0, 10.0f,0.0f,0);
652 oshape.
quadTo(5.0f,0.0f,0, 5.0f,-5.0f,0);
668 frontShape->
scale().
x *= 0.1f;
669 frontShape->
scale().
y *= 0.1f;
672 m_shapes.push_back(backShape);
678 backShape->
scale().
x *= 0.1f;
679 backShape->
scale().
y *= 0.1f;
687 m_shapes.push_back(frontShape);
694 frontShape->
scale().
x *= 2.0f;
695 frontShape->
scale().
y *= 2.0f;
698 m_shapes.push_back(backShape);
705 backShape->
scale().
x *= 2.0f;
706 backShape->
scale().
y *= 2.0f;
710 m_shapes.push_back(frontShape);
717 frontShape->
scale().
x *= 2.0f;
718 frontShape->
scale().
y *= 2.0f;
721 m_shapes.push_back(backShape);
728 backShape->
scale().
x *= 2.0f;
729 backShape->
scale().
y *= 2.0f;
732 ::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
733 ::glEnable(GL_DEPTH_TEST);
735 ::glDisable(GL_CULL_FACE);
737 m_initialized =
true;
738 if( !m_initialized ) {
743 return m_initialized;
749 m_initialized =
false;
758 pmv.getP().loadIdentity();
759 const float aspect = 1.0f;
760 const float fovy_deg=45.0f;
761 const float aspect2 = ( (float) m_viewport.width() / (
float) m_viewport.height() ) / aspect;
763 m_st.useProgram(
gl,
true);
764 m_st.pushUniform(
gl, m_pmvMatUni);
770 if( !m_initialized ) {
774 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
776 m_st.useProgram(
gl,
true);
778 pmv.getMv().loadIdentity();
779 pmv.translateMv(0, 0, -5);
783 constexpr double angle_per_sec = 30;
784 const float rad = (float) ( (when - m_tlast).to_double() * angle_per_sec );
796 std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
801 class MyKeyListener :
public KeyListener {
807 void keyPressed(KeyEvent& e,
const KeyboardTracker& kt)
override {
809 if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
814 }
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
815 m_parent.animating() = !m_parent.animating();
816 }
else if( e.
keySym() == VKeyCode::VK_PERIOD ) {
817 m_parent.setOneFrame();
818 }
else if( e.
keySym() == VKeyCode::VK_W ) {
823 void keyReleased(KeyEvent& e,
const KeyboardTracker& kt)
override {
827 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
828 MyKeyListenerRef m_kl;
833 m_kl(
std::make_shared<MyKeyListener>(*this)) { }
848int main(
int argc,
char *argv[])
850 return launch(
"GraphShapes01.cpp",
853 std::make_shared<Example>(), argc, argv);
int launch(std::string_view sfile, GLLaunchProps props, const RenderListenerRef &demo, int argc, char *argv[])
int main(int argc, char *argv[])
std::shared_ptr< Shape > ShapeRef
std::shared_ptr< Shape > ShapeRef
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 void addShapeToRegion(gamp::graph::OutlineShape &shape)
static void addShapeToRegion(gamp::graph::OutlineShape &shape)
constexpr bool initialized() const noexcept
void addOutlineShape(OutlineShape &shape)
void pushVertex(const Vertex &v, const Vec3f &normal)
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void pushNewVerticesIdx(const Vertex &vertIn1, const Vertex &vertIn2, const Vertex &vertIn3, const Vec3f &normal)
GraphRegion(GraphRenderer &renderer, ShaderState &st)
void pushIndices(uint32_t i, uint32_t j, uint32_t k)
void seal(GL &gl, bool seal_)
static constexpr std::string_view GLSL_USE_LIGHT0
bool init(GL &gl, const jau::fraction_timespec &when)
static constexpr std::string_view GLSL_MAIN_BEGIN
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view GLSL_PARAM_COMMENT_START
static constexpr std::string_view GLSL_USE_DISCARD
static constexpr std::string_view colTexLookupFuncName
static constexpr std::string_view bin_dir
static constexpr std::string_view GLSL_PARAM_COMMENT_END
constexpr GLsizei arrayCompsPerElement() const noexcept
constexpr bool initialized() const noexcept
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
constexpr bool usesNormal() const noexcept
static constexpr std::string_view source_dir
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
GraphRenderer(ShaderState &st)
static constexpr std::string_view shader_basename
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
void setOneFrame() noexcept
bool animating() const noexcept
std::string toStringImpl() const noexcept override
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.
const PMVMat4f & pmv() const noexcept
void display(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
PMVMat4f & pmv() noexcept
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
bool & animating() noexcept
Recti & viewport() noexcept
const Recti & viewport() const noexcept
constexpr const float & zOffset() const noexcept
void setColor(const Vec4f &c) noexcept
constexpr Vec3f & position() noexcept
constexpr OutlineShape & outlines() noexcept
constexpr const Quat4f & rotation() const noexcept
static ShapeRef create(ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr const Vec3f & rotationPivot() const noexcept
constexpr float & zOffset() 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
constexpr const OutlineShape & outlines() const noexcept
Shape(Private, ShaderState &st, GLUniformSyncPMVMat4fRef pmvMatU, GraphRenderer &renderer)
constexpr Quat4f & rotation() noexcept
A Generic shape objects which is defined by a list of Outlines.
constexpr size_type addedVertexCount() const noexcept
Return the number of newly added vertices during getTriangles(VerticesState) while transforming the o...
const VertexList & getVertices()
Return list of concatenated vertices associated with all Outlines of this object.
void clearCache() noexcept
Clears cached triangulated data, i.e.
void cubicTo(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3)
Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
const OutlineList & outlines() const noexcept
void quadTo(float x1, float y1, float z1, float x2, float y2, float z2)
Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
constexpr const Vec3f & normal() const noexcept
Normal vector, optionally used by tesselator to add (interleaved) normals.
void moveTo(float x, float y, float z)
Start a new position for the next line segment at given point x/y (P1).
void closePath()
Closes the current sub-path segment by drawing a straight line back to the coordinates of the last mo...
const TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
OutlineShape flipFace(float zoffset=0) const
Returns a copy of this instance with normal() and all outlines() vertices()'s z-axis sign-flipped,...
void lineTo(float x, float y, float z)
Add a line segment, intersecting the last point and the given point x/y (P1).
std::array< Vertex, 3 > trivert_t
constexpr const trivert_t & vertices() const noexcept
Returns array of 3 vertices, denominating the triangle.
constexpr const Vec3f & texCoord() const noexcept
constexpr const Vec3f & coord() const noexcept
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 replaceInShaderSource(const string_t &oldName, const string_t &newName) noexcept
Replaces oldName with newName in all shader sources.
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
size_t insertShaderSourceFile(size_t shaderIdx, size_t position, const string_t &path) noexcept
Adds shader source located in path, either relative to the location or absolute as-is at position in ...
size_t insertShaderSource(size_t shaderIdx, stringview_t tag, size_t fromIndex, stringview_t data) noexcept
Adds data after the line containing tag.
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.
std::string toString() const noexcept
const gamp::render::RenderContext * renderContext() const noexcept
size_t removeKeyListener(const KeyListenerRef &l)
void dispose(const jau::fraction_timespec &when) noexcept override
std::string toString() const noexcept
void addKeyListener(const KeyListenerRef &l)
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().
static constexpr const value_type one
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
GLArrayDataServer< float > GLFloatArrayDataServer
GLsizeiptr glmemsize_t
Compatible with ssize_t.
std::shared_ptr< GLUniformSyncPMVMat4f > GLUniformSyncPMVMat4fRef
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
GLArrayDataServerRef< uint32_t > GLUIntArrayDataServerRef
std::shared_ptr< GLUniformVec3f > GLUniformVec3fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
jau::darray< Vertex, uint32_t > VertexList
std::shared_ptr< Triangle > TriangleRef
jau::darray< TriangleRef, uint32_t > TriangleRefList
@ verbose
Verbose operations (debugging).
std::shared_ptr< Window > WindowRef
PMVData
PMVMatrix4 derived matrices and values.
Quaternion< float > Quat4f
std::string to_string(const math_error_t v) noexcept
Returns std::string representation of math_error_t.
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,...
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
bool m_hasFrustumClipping
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.