78 constexpr static PMVData mat_req = PMVData::inv_proj | PMVData::inv_mv | PMVData::inv_tps_mv;
82 GLUniformSyncPMVMat4f m_pmvMat;
83 GLUniformVec3f m_light0Pos;
84 GLUniformVec4f m_staticColor;
88 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
95 static constexpr std::string_view
GLSL_USE_LIGHT0 =
"#define USE_LIGHT0 1\n";
98 static constexpr std::string_view
GLSL_USE_DISCARD =
"#define USE_DISCARD 1\n";
101 static constexpr std::string_view
GLSL_MAIN_BEGIN =
"void main (void)\n{\n";
102 static constexpr std::string_view
gcuTexture2D =
"gcuTexture2D";
105 static constexpr std::string_view
source_dir =
"impl/graph/glsl";
106 static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
111 m_pmvMat(
"gcu_PMVMatrix", mat_req),
112 m_light0Pos(
"gcu_Light0Pos", lightPos),
113 m_staticColor(
"gcu_StaticColor",
Vec4f(0, 0, 0, 1)),
116 m_st.manage(m_pmvMat);
117 m_st.manage(m_light0Pos);
118 m_st.manage(m_staticColor);
121 constexpr bool initialized() const noexcept {
return m_initialized; }
127 std::string vertexShaderName, fragmentShaderName;
129 if( m_props.m_isTwoPass ) {
130 vertexShaderName.append(
"-pass").append(m_props.m_pass1 ?
"1":
"2");
132 vertexShaderName.append(
"-single");
138 if( !rsVp || !rsFp ) {
145 if( posVp == std::string::npos || posFp == std::string::npos ) {
157 if( m_props.m_hasDiscard ) {
161 if( m_props.m_hasFrustumClipping ) {
170 if( m_props.m_hasLight0 ) {
174 if( m_props.m_hasColorChannel ) {
178 if( m_props.m_hasColorTexture ) {
188 if( posVp == std::string::npos ) {
196 if( posFp == std::string::npos ) {
201 if( posFp == std::string::npos ) {
206 if( posFp == std::string::npos ) {
210 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
212 if( posFp == std::string::npos ) {
224 std::string passS = m_props.m_pass1 ?
"-pass1-" :
"-pass2-";
227 jau_PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
230 if( posFp == std::string::npos ) {
235 if( posFp == std::string::npos ) {
240 if( m_props.m_hasColorTexture ) {
246 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
251 m_st.attachShaderProgram(
gl, sp0,
true);
254 pmv.getP().loadIdentity();
255 pmv.getMv().loadIdentity();
257 m_st.send(
gl, m_pmvMat);
258 m_st.send(
gl, m_light0Pos);
259 m_st.send(
gl, m_staticColor);
261 m_initialized = sp0->
inUse();
262 if( !m_initialized ) {
266 return m_initialized;
270 m_st.destroyShaderProgram(
gl);
274 m_st.useProgram(
gl, on);
278 m_st.send(
gl, m_staticColor);
281 m_st.send(
gl, m_pmvMat);
284 m_st.send(
gl, m_pmvMat);
285 m_st.send(
gl, m_staticColor);
289 const Vec4f&
color() const noexcept {
return m_staticColor.vec4f(); }
303 int m_num_vertices, m_num_indices;
307 : m_renderer(renderer),
309 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
311 m_num_vertices(0), m_num_indices(0)
313 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
314 m_array->addGLSLSubArray(
"gca_CurveParam", 3, GL_ARRAY_BUFFER);
315 if( m_renderer.usesNormal() ) {
316 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
318 m_renderer.st().manage(m_array);
322 constexpr bool initialized() const noexcept {
return m_initialized; }
325 m_renderer.st().destroyAllData(
gl);
327 m_indices->destroy(
gl);
333 if( !m_initialized ) {
336 m_array->seal(
gl, seal_);
337 m_indices->seal(
gl, seal_);
338 m_array->enableBuffer(
gl,
false);
339 m_indices->enableBuffer(
gl,
false);
343 void pushVertex(
const Vertex& v,
const Vec3f& normal) {
345 m_array->put3f(v.
coord());
348 m_array->put3f(normal);
352 void pushIndices(uint32_t i, uint32_t j, uint32_t k) {
354 m_indices->putN(i, j, k);
357 void pushNewVerticesIdx(
const Vertex& vertIn1,
const Vertex& vertIn2,
const Vertex& vertIn3,
const Vec3f& normal) {
358 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
359 pushVertex(vertIn1, normal);
360 pushVertex(vertIn2, normal);
361 pushVertex(vertIn3, normal);
366 if( !m_initialized ) {
370 jau_PLAIN_PRINT(
true,
"add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
372 jau_PLAIN_PRINT(
true,
"add.0 indices: %s", m_indices->toString().c_str());
382 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
383 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
385 uint32_t idxOffset = m_num_vertices;
386 if( vertsIn.
size() >= 3 ) {
390 for(
const Vertex& v : vertsIn) {
391 pushVertex(v, shape.
normal());
393 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() /
sizeof(uint32_t);
400 uint32_t tv0Idx = triInVertices[0].id();
401 if ( max_index - idxOffset > tv0Idx ) {
403 pushIndices(tv0Idx+idxOffset,
404 triInVertices[1].
id()+idxOffset,
405 triInVertices[2].
id()+idxOffset);
408 pushNewVerticesIdx(triInVertices[0], triInVertices[1], triInVertices[2], shape.
normal());
413 jau_PLAIN_PRINT(
true,
"add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
415 jau_PLAIN_PRINT(
true,
"add.x indices: %s", m_indices->toString().c_str());
420 if( !m_initialized ) {
423 m_renderer.useProgram(
gl,
true);
425 m_array->enableBuffer(
gl,
true);
426 m_indices->bindBuffer(
gl,
true);
428 ::glEnable(GL_BLEND);
429 ::glBlendEquation(GL_FUNC_ADD);
430 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
432 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT,
nullptr);
434 m_indices->bindBuffer(
gl,
false);
435 m_array->enableBuffer(
gl,
false);
445 std::vector<OutlineShape> m_oshapes;
451 float m_zOffset = 0.0f;
458 bool iMatIdent =
true;
459 bool iMatDirty =
false;
463 struct Private{
explicit Private() =
default; };
467 : m_renderer(renderer), m_region(m_renderer)
469 std::cerr <<
"XXX ctor.x " << m_renderer.st() <<
"\n";
473 return std::make_shared<Shape>(Private(), renderer);
477 m_region.destroy(
gl);
484 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
485 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
493 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
494 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
496 constexpr const std::vector<OutlineShape>&
outlineShapes() const noexcept {
return m_oshapes; }
497 constexpr std::vector<OutlineShape>&
outlineShapes() noexcept {
return m_oshapes; }
504 m_region.addOutlineShape(o);
506 m_region.seal(
gl,
true);
514 m_renderer.setColor(m_color);
515 m_renderer.updateAll(
gl);
525 m_rotation.rotateByAngleZ( M_PI_2);
526 Vec3f dir = m_rotation.rotateVector(
Vec3f(1, 0, 0));
527 m_rotation.rotateByAngleZ(-M_PI_2);
528 Vec3f d_p = dir * m_velo * dt;
533 float&
velo() noexcept {
return m_velo; }
550 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
558 void updateMat() noexcept {
559 bool hasPos = !m_position.is_zero();
561 bool hasRotate = !m_rotation.isIdentity();
562 bool hasRotPivot =
false;
563 for(OutlineShape& o : m_oshapes){
564 const Vec3f& ctr = o.bounds().center();
565 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
567 if( sameScaleRotatePivot ) {
569 iMat.setToTranslation(m_position);
571 iMat.translate(
Vec3f(ctr).mul(m_scale));
572 iMat.rotate(m_rotation);
574 iMat.translate(-ctr);
575 }
else if( hasRotate || hasScale ) {
577 iMat.setToTranslation(m_position);
581 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
582 iMat.rotate(m_rotation);
583 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
586 iMat.translate(
Vec3f(ctr).mul(m_scale));
587 iMat.rotate(m_rotation);
588 iMat.translate(
Vec3f(-ctr).mul(m_scale));
593 iMat.translate(
Vec3f(ctr).mul(m_scale));
595 iMat.translate(
Vec3f(-ctr).mul(m_scale));
597 }
else if( hasPos ) {
599 iMat.setToTranslation(m_position);
612 constexpr static float zNear= 1.0f;
613 constexpr static float zFar =100.0f;
618 bool m_animating =
true;
619 bool m_oneframe =
false;
622 std::vector<ShapeRef> m_shapes;
628 m_initialized(false),
635 std::vector<ShapeRef>&
shapes() noexcept {
return m_shapes; }
639 void setOneFrame() noexcept { m_animating=
false; m_oneframe=
true; }
647 if( !m_renderer.init(
gl, when) ) {
657 m_shapes.push_back(cobraMkIII_Shape);
660 ::glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
661 ::glEnable(GL_DEPTH_TEST);
663 ::glDisable(GL_CULL_FACE);
665 m_initialized =
true;
666 if( !m_initialized ) {
671 return m_initialized;
680 m_renderer.destroy(
gl);
682 m_initialized =
false;
692 const float aspect = 1.0f;
693 const float fovy_deg=45.0f;
694 const float aspect2 = ( (float) m_viewport.width() / (
float) m_viewport.height() ) / aspect;
699 m_st.useProgram(
gl,
true);
705 if( !m_initialized ) {
709 ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
711 m_st.useProgram(
gl,
true);
713 const float dt = float( (when - m_tlast).to_double() );
715 if( (
animating() || m_oneframe) && s != m_shapes[0]) {
716 constexpr float angle_per_sec = 30;
717 const float rad = dt * angle_per_sec;
729 std::cerr <<
"XXX draw " << m_st <<
"\n";
737 std::string
toStringImpl() const noexcept
override {
return "GraphShapes01"; }
742 class MyKeyListener :
public KeyListener {
748 void keyPressed(KeyEvent& e,
const KeyboardTracker& kt)
override {
750 std::vector<ShapeRef>& shapeList = m_parent.shapes();
751 if( e.
keySym() == VKeyCode::VK_ESCAPE ) {
756 }
else if( e.
keySym() == VKeyCode::VK_PAUSE || e.
keySym() == VKeyCode::VK_P ) {
757 m_parent.animating() = !m_parent.animating();
758 }
else if( e.
keySym() == VKeyCode::VK_PERIOD ) {
759 m_parent.setOneFrame();
760 }
else if( e.
keySym() == VKeyCode::VK_W ) {
763 }
else if( e.
keySym() == VKeyCode::VK_UP ) {
764 shapeList[0]->rotation().rotateByAngleX(-M_PI / 50);
765 }
else if( e.
keySym() == VKeyCode::VK_DOWN ) {
766 shapeList[0]->rotation().rotateByAngleX( M_PI / 50);
767 }
else if( e.
keySym() == VKeyCode::VK_SHIFT ) {
768 shapeList[0]->velo() += 0.1f;
769 }
else if( e.
keySym() == VKeyCode::VK_ENTER ) {
770 shapeList[0]->velo() = std::max(shapeList[0]->velo() - 0.1f, 0.0f);
771 }
else if( e.
keySym() == VKeyCode::VK_RIGHT) {
772 shapeList[0]->rotation().rotateByAngleY( M_PI / 50);
773 }
else if( e.
keySym() == VKeyCode::VK_LEFT ) {
774 shapeList[0]->rotation().rotateByAngleY(-M_PI / 50);
777 void keyReleased(KeyEvent& e,
const KeyboardTracker& kt)
override {
781 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
782 MyKeyListenerRef m_kl;
787 m_kl(
std::make_shared<MyKeyListener>(*this)) { }
802int main(
int argc,
char *argv[])
804 return launch(
"GraphShapes02.cpp",
807 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
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,...
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_)
static constexpr std::string_view GLSL_USE_LIGHT0
ShaderState & st() noexcept
bool init(GL &gl, const jau::fraction_timespec &when)
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_USE_DISCARD
const PMVMat4f & pmv() const noexcept
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view source_dir
static constexpr std::string_view GLSL_PARAM_COMMENT_END
constexpr GLsizei arrayCompsPerElement() const noexcept
const Vec4f & color() const noexcept
constexpr bool initialized() const noexcept
static constexpr std::string_view shader_basename
static constexpr std::string_view bin_dir
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view GLSL_MAIN_BEGIN
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
constexpr bool usesNormal() const noexcept
const ShaderState & st() const noexcept
PMVMat4f & pmv() noexcept
static constexpr std::string_view colTexLookupFuncName
GraphRenderer(ShaderState &st)
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_PARAM_COMMENT_START
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
void setColor(const Vec4f &c) 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,...
bool init(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
void display(const WindowSRef &win, const jau::fraction_timespec &when) override
Called by the drawable to initiate rendering by the client.
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() noexcept
const Recti & viewport() const noexcept
bool animating() const noexcept
void setOneFrame() noexcept
std::vector< ShapeRef > & shapes() noexcept
std::string toStringImpl() const noexcept override
Recti & viewport() noexcept
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.
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.
constexpr const Vec3f & normal() const noexcept
Normal vector, optionally used by tesselator to add (interleaved) normals.
const TriangleRefList & getTriangles(VertexState destinationType=VertexState::quadratic_nurbs)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
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 ShaderCodeSRef create(GLenum type, size_t count, const source_list_t &sources)
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.
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.
constexpr_cxx26 Quaternion & rotateByAngleX(const value_type angle) noexcept
Rotate this quaternion around X axis with the given angle in radians.
static constexpr const value_type one
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
GLsizeiptr glmemsize_t
Compatible with ssize_t.
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
GLArrayDataServerSRef< uint32_t > GLUIntArrayDataServerSRef
std::shared_ptr< ShaderCode > ShaderCodeSRef
std::shared_ptr< ShaderProgram > ShaderProgramSRef
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 > WindowSRef
PMVData
PMVMatrix4 derived matrices and values.
Quaternion< float > Quat4f
PMVMatrix4< float > PMVMat4f
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
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.