93 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
111 static constexpr std::string_view
source_dir =
"impl/graph/glsl";
112 static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
120 constexpr bool initialized() const noexcept {
return m_initialized; }
123 std::string vertexShaderName, fragmentShaderName;
125 if( m_props.m_isTwoPass ) {
126 vertexShaderName.append(
"-pass").append(m_props.m_pass1 ?
"1":
"2");
128 vertexShaderName.append(
"-single");
134 if( !rsVp || !rsFp ) {
141 if( posVp == std::string::npos || posFp == std::string::npos ) {
156 if( m_props.m_hasFrustumClipping ) {
165 if( m_props.m_hasLight0 ) {
169 if( m_props.m_hasColorChannel ) {
173 if( m_props.m_hasColorTexture ) {
183 if( posVp == std::string::npos ) {
191 if( posFp == std::string::npos ) {
196 if( posFp == std::string::npos ) {
201 if( posFp == std::string::npos ) {
205 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
207 if( posFp == std::string::npos ) {
219 std::string passS = m_props.m_pass1 ?
"-pass1-" :
"-pass2-";
222 jau::PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
225 if( posFp == std::string::npos ) {
230 if( posFp == std::string::npos ) {
235 if( m_props.m_hasColorTexture ) {
241 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
246 m_st.attachShaderProgram(
gl, sp0,
true);
248 m_st.pushAllUniforms(
gl);
250 m_initialized = sp0->
inUse();
251 if( !m_initialized ) {
255 return m_initialized;
259 m_st.useProgram(
gl, on);
273 int m_num_vertices, m_num_indices;
277 : m_renderer(renderer), m_st(st),
279 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
281 m_num_vertices(0), m_num_indices(0)
283 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
284 m_array->addGLSLSubArray(
"gca_CurveParam", 3, GL_ARRAY_BUFFER);
285 if( m_renderer.usesNormal() ) {
286 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
288 m_st.ownAttribute(m_array,
true);
292 constexpr bool initialized() const noexcept {
return m_initialized; }
295 if( !m_initialized ) {
298 m_array->seal(
gl, seal_);
299 m_indices->seal(
gl, seal_);
300 m_array->enableBuffer(
gl,
false);
301 m_indices->enableBuffer(
gl,
false);
306 m_array->put3f(v.
coord());
308 if( m_renderer.usesNormal() ) {
309 m_array->put3f(normal);
315 m_indices->putN(i, j, k);
319 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
327 jau::PLAIN_PRINT(
true,
"add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
339 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
340 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
342 uint32_t idxOffset = m_num_vertices;
343 if( vertsIn.
size() >= 3 ) {
347 for(
const Vertex& v : vertsIn) {
350 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() /
sizeof(uint32_t);
357 uint32_t tv0Idx = triInVertices[0].id();
358 if ( max_index - idxOffset > tv0Idx ) {
361 triInVertices[1].
id()+idxOffset,
362 triInVertices[2].
id()+idxOffset);
370 jau::PLAIN_PRINT(
true,
"add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
377 if( !m_initialized ) {
380 m_renderer.useProgram(
gl,
true);
382 m_array->enableBuffer(
gl,
true);
383 m_indices->bindBuffer(
gl,
true);
385 ::glEnable(GL_BLEND);
386 ::glBlendEquation(GL_FUNC_ADD);
387 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
389 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT,
nullptr);
392 m_indices->bindBuffer(
gl,
false);
393 m_array->enableBuffer(
gl,
false);
419 bool iMatIdent =
true;
420 bool iMatDirty =
false;
422 struct Private{
explicit Private() =
default; };
426 : m_st(st), m_pmvMat(pmvMatU), m_oshape(3, 16),
427 m_renderer(renderer), m_region(m_renderer, m_st)
430 m_st.ownUniform(m_uColor,
true);
434 return std::make_shared<Shape>(Private(), st, pmvMatU, renderer);
440 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
441 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
449 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
450 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
455 const Vec4f&
color() const noexcept {
return m_uColor->vec4f(); }
459 m_region.addOutlineShape(m_oshape);
460 m_region.seal(
gl,
true);
465 applyMatToMv(m_pmvMat.m);
466 m_st.pushUniform(
gl, m_pmvMat.u);
468 m_st.pushUniform(
gl, m_uColor);
488 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
496 void updateMat() noexcept {
497 bool hasPos = !m_position.is_zero();
499 bool hasRotate = !m_rotation.isIdentity();
500 bool hasRotPivot =
false;
501 const Vec3f& ctr = m_oshape.bounds().center();
502 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
504 if( sameScaleRotatePivot ) {
506 iMat.setToTranslation(m_position);
508 iMat.translate(
Vec3f(ctr).mul(m_scale));
509 iMat.rotate(m_rotation);
511 iMat.translate(-ctr);
512 }
else if( hasRotate || hasScale ) {
514 iMat.setToTranslation(m_position);
518 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
519 iMat.rotate(m_rotation);
520 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
523 iMat.translate(
Vec3f(ctr).mul(m_scale));
524 iMat.rotate(m_rotation);
525 iMat.translate(
Vec3f(-ctr).mul(m_scale));
530 iMat.translate(
Vec3f(ctr).mul(m_scale));
532 iMat.translate(
Vec3f(-ctr).mul(m_scale));
534 }
else if( hasPos ) {
536 iMat.setToTranslation(m_position);
549 constexpr static float zNear= 1.0f;
550 constexpr static float zFar =100.0f;
555 bool m_animating =
true;
556 bool m_oneframe =
false;
560 std::vector<ShapeRef> m_shapes;
565 m_initialized(false), m_renderer(m_st)
576 void setOneFrame() noexcept { m_animating=
false; m_oneframe=
true; }
585 m_pmvMat.m.getP().loadIdentity();
586 m_pmvMat.m.getMv().loadIdentity();
587 m_st.ownUniform(m_pmvMat.u,
true);
589 if( !m_renderer.init(
gl, when) ) {
596 m_st.ownUniform(lightU,
true);
597 m_st.pushAllUniforms(
gl);
599 const float lineWidth = 1/2.5f;
600 const float dz = 0.005f;
603 const float width = 1.5f;
604 const float height = 1.5f;
606 float lwh = lineWidth/2.0f;
608 float twh = width/2.0f;
609 float thh = height/2.0f;
611 float ctrX = 0, ctrY = 0, ctrZ = dz;
613 m_shapes.push_back(frontShape);
616 oshape.
moveTo(ctrX-lwh, ctrY+thh, ctrZ);
617 oshape.
lineTo(ctrX-lwh, ctrY+lwh, ctrZ);
618 oshape.
lineTo(ctrX-twh, ctrY+lwh, ctrZ);
619 oshape.
lineTo(ctrX-twh, ctrY-lwh, ctrZ);
620 oshape.
lineTo(ctrX-lwh, ctrY-lwh, ctrZ);
621 oshape.
lineTo(ctrX-lwh, ctrY-thh, ctrZ);
622 oshape.
lineTo(ctrX+lwh, ctrY-thh, ctrZ);
623 oshape.
lineTo(ctrX+lwh, ctrY-lwh, ctrZ);
624 oshape.
lineTo(ctrX+twh, ctrY-lwh, ctrZ);
625 oshape.
lineTo(ctrX+twh, ctrY+lwh, ctrZ);
626 oshape.
lineTo(ctrX+lwh, ctrY+lwh, ctrZ);
627 oshape.
lineTo(ctrX+lwh, ctrY+thh, ctrZ);
628 oshape.
lineTo(ctrX-lwh, ctrY+thh, ctrZ);
636 m_shapes.push_back(backShape);
645 m_shapes.push_back(frontShape);
647 oshape.
moveTo(0.0f,-10.0f, 0);
648 oshape.
lineTo(15.0f,-10.0f, 0);
649 oshape.
quadTo(10.0f,5.0f,0, 15.0f,10.0f,0);
650 oshape.
cubicTo(6.0f,15.0f,0, 5.0f,8.0f,0, 0.0f,10.0f,0);
652 oshape.
moveTo(5.0f,-5.0f,0);
653 oshape.
quadTo(10.0f,-5.0f,0, 10.0f,0.0f,0);
654 oshape.
quadTo(5.0f,0.0f,0, 5.0f,-5.0f,0);
660 frontShape->
scale().
x *= 0.1f;
661 frontShape->
scale().
y *= 0.1f;
664 m_shapes.push_back(backShape);
670 backShape->
scale().
x *= 0.1f;
671 backShape->
scale().
y *= 0.1f;
675 m_shapes.push_back(frontShape);
682 frontShape->
scale().
x *= 2.0f;
683 frontShape->
scale().
y *= 2.0f;
686 m_shapes.push_back(backShape);
693 backShape->
scale().
x *= 2.0f;
694 backShape->
scale().
y *= 2.0f;
698 m_shapes.push_back(frontShape);
705 frontShape->
scale().
x *= 2.0f;
706 frontShape->
scale().
y *= 2.0f;
709 m_shapes.push_back(backShape);
716 backShape->
scale().
x *= 2.0f;
717 backShape->
scale().
y *= 2.0f;
720 ::glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
721 ::glEnable(GL_DEPTH_TEST);
723 ::glDisable(GL_CULL_FACE);
725 m_initialized =
true;
726 if( !m_initialized ) {
731 return m_initialized;
737 m_initialized =
false;
745 m_pmvMat.m.getP().loadIdentity();
746 const float aspect = 1.0f;
747 const float fovy_deg=45.0f;
748 const float aspect2 = ( (float) m_viewport.width() / (
float) m_viewport.height() ) / aspect;
750 m_st.useProgram(
gl,
true);
751 m_st.pushUniform(
gl, m_pmvMat.u);
757 if( !m_initialized ) {
761 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
763 m_st.useProgram(
gl,
true);
764 m_pmvMat.m.getMv().loadIdentity();
765 m_pmvMat.m.translateMv(0, 0, -5);
769 constexpr double angle_per_sec = 30;
770 const float rad = (float) ( (when - m_tlast).to_double() * angle_per_sec );
782 std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
787 class MyKeyListener :
public KeyListener {
793 void keyPressed(KeyEvent& e,
const KeyboardTracker& kt)
override {
795 if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
800 }
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
801 m_parent.animating() = !m_parent.animating();
802 }
else if( e.
keySym() == VKeyCode::VK_PERIOD ) {
803 m_parent.setOneFrame();
804 }
else if( e.
keySym() == VKeyCode::VK_W ) {
809 void keyReleased(KeyEvent& e,
const KeyboardTracker& kt)
override {
813 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
814 MyKeyListenerRef m_kl;
819 m_kl(
std::make_shared<MyKeyListener>(*this)) { }
834int main(
int argc,
char *argv[])
838 return launch(
"GraphShapes01.cpp",
840 std::make_shared<Example>(), argc, argv);
int launch(std::string_view sfile, const 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
static constexpr bool DEBUG_MODE
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
Shape(Private, ShaderState &st, PMVMat4fUniform &pmvMatU, GraphRenderer &renderer)
constexpr Vec3f & position() noexcept
static ShapeRef create(ShaderState &st, PMVMat4fUniform &pmvMatU, GraphRenderer &renderer)
constexpr OutlineShape & outlines() noexcept
constexpr const Quat4f & rotation() const 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
const Vec4f & color() const noexcept
constexpr const Vec3f & scale() const noexcept
constexpr const OutlineShape & outlines() const noexcept
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...
void clearCache() noexcept
Clears cached triangulated data, i.e.
const VertexList & getVertices()
Return list of concatenated vertices associated with all Outlines of this object.
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 TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
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...
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
std::vector< Segment > SegmentList
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, bool addDefaultPrecision)
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_t bitCount() 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 T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
GLArrayDataServer< float > GLFloatArrayDataServer
GLsizeiptr glmemsize_t
Compatible with ssize_t.
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
std::shared_ptr< GLUniformData > GLUniformDataRef
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
Quaternion< float > Quat4f
PMVMatrix4< float > PMVMat4f
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.