12#ifndef GAMP_GRAPH_REGION_HPP_
13#define GAMP_GRAPH_REGION_HPP_
87 constexpr bool usesNormal() const noexcept {
return m_props.m_hasLight0 || m_props.m_hasNormalChannel; }
94 static constexpr std::string_view
GLSL_USE_LIGHT0 =
"#define USE_LIGHT0 1\n";
97 static constexpr std::string_view
GLSL_USE_DISCARD =
"#define USE_DISCARD 1\n";
100 static constexpr std::string_view
GLSL_MAIN_BEGIN =
"void main (void)\n{\n";
101 static constexpr std::string_view
gcuTexture2D =
"gcuTexture2D";
104 static constexpr std::string_view
source_dir =
"impl/graph/glsl";
105 static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
111 m_light0Pos(
"gcu_Light0Pos", lightPos),
112 m_staticColor(
"gcu_StaticColor",
Vec4f(0, 0, 0, 1)),
115 m_st.manage(m_light0Pos);
116 m_st.manage(m_staticColor);
119 constexpr bool initialized() const noexcept {
return m_initialized; }
125 std::string vertexShaderName, fragmentShaderName;
127 if( m_props.m_isTwoPass ) {
128 vertexShaderName.append(
"-pass").append(m_props.m_pass1 ?
"1":
"2");
130 vertexShaderName.append(
"-single");
136 if( !rsVp || !rsFp ) {
143 if( posVp == std::string::npos || posFp == std::string::npos ) {
155 if( m_props.m_hasDiscard ) {
159 if( m_props.m_hasFrustumClipping ) {
168 if( m_props.m_hasLight0 ) {
172 if( m_props.m_hasColorChannel ) {
176 if( m_props.m_hasColorTexture ) {
186 if( posVp == std::string::npos ) {
194 if( posFp == std::string::npos ) {
199 if( posFp == std::string::npos ) {
204 if( posFp == std::string::npos ) {
208 if( m_props.m_hasColorTexture || m_props.m_hasFrustumClipping ) {
210 if( posFp == std::string::npos ) {
222 std::string passS = m_props.m_pass1 ?
"-pass1-" :
"-pass2-";
225 jau_PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
228 if( posFp == std::string::npos ) {
233 if( posFp == std::string::npos ) {
238 if( m_props.m_hasColorTexture ) {
244 if( !sp0->
add(
gl, rsVp,
true) || !sp0->
add(
gl, rsFp,
true) ) {
249 m_st.attachShaderProgram(
gl, sp0,
true);
251 m_st.send(
gl, m_light0Pos);
252 m_st.send(
gl, m_staticColor);
254 m_initialized = sp0->
inUse();
255 if( !m_initialized ) {
259 return m_initialized;
263 m_st.destroyShaderProgram(
gl);
267 m_st.useProgram(
gl, on);
271 m_st.send(
gl, m_staticColor);
274 m_st.send(
gl, m_staticColor);
278 const Vec4f&
color() const noexcept {
return m_staticColor.vec4f(); }
292 int m_num_vertices, m_num_indices;
296 : m_renderer(renderer),
298 m_array(
GLFloatArrayDataServer::createGLSLInterleaved(m_renderer.arrayCompsPerElement(), false, 256, GL_STATIC_DRAW)),
300 m_num_vertices(0), m_num_indices(0)
302 m_array->addGLSLSubArray(
"gca_Vertex", 3, GL_ARRAY_BUFFER);
303 m_array->addGLSLSubArray(
"gca_CurveParam", 3, GL_ARRAY_BUFFER);
304 if( m_renderer.usesNormal() ) {
305 m_array->addGLSLSubArray(
"gca_Normal", 3, GL_ARRAY_BUFFER);
307 m_renderer.st().manage(m_array);
311 constexpr bool initialized() const noexcept {
return m_initialized; }
314 m_renderer.st().destroyAllData(
gl);
316 m_indices->destroy(
gl);
322 if( !m_initialized ) {
325 m_array->seal(
gl, seal_);
326 m_indices->seal(
gl, seal_);
327 m_array->enableBuffer(
gl,
false);
328 m_indices->enableBuffer(
gl,
false);
332 void pushVertex(
const Vertex& v,
const Vec3f& normal) {
334 m_array->put3f(v.
coord());
337 m_array->put3f(normal);
341 void pushIndices(uint32_t i, uint32_t j, uint32_t k) {
343 m_indices->putN(i, j, k);
346 void pushNewVerticesIdx(
const Vertex& vertIn1,
const Vertex& vertIn2,
const Vertex& vertIn3,
const Vec3f& normal) {
347 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
348 pushVertex(vertIn1, normal);
349 pushVertex(vertIn2, normal);
350 pushVertex(vertIn3, normal);
355 if( !m_initialized ) {
359 jau_PLAIN_PRINT(
true,
"add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
361 jau_PLAIN_PRINT(
true,
"add.0 indices: %s", m_indices->toString().c_str());
371 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
372 m_indices->growIfNeeded(indexCount * m_indices->compsPerElem());
374 uint32_t idxOffset = m_num_vertices;
375 if( vertsIn.
size() >= 3 ) {
379 for(
const Vertex& v : vertsIn) {
380 pushVertex(v, shape.
normal());
382 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() /
sizeof(uint32_t);
389 uint32_t tv0Idx = triInVertices[0].id();
390 if ( max_index - idxOffset > tv0Idx ) {
392 pushIndices(tv0Idx+idxOffset,
393 triInVertices[1].
id()+idxOffset,
394 triInVertices[2].
id()+idxOffset);
397 pushNewVerticesIdx(triInVertices[0], triInVertices[1], triInVertices[2], shape.
normal());
402 jau_PLAIN_PRINT(
true,
"add.x num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
404 jau_PLAIN_PRINT(
true,
"add.x indices: %s", m_indices->toString().c_str());
409 if( !m_initialized ) {
412 m_renderer.useProgram(
gl,
true);
414 m_array->enableBuffer(
gl,
true);
415 m_indices->bindBuffer(
gl,
true);
417 ::glEnable(GL_BLEND);
418 ::glBlendEquation(GL_FUNC_ADD);
419 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
421 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT,
nullptr);
423 m_indices->bindBuffer(
gl,
false);
424 m_array->enableBuffer(
gl,
false);
434 std::vector<OutlineShape> m_oshapes;
440 float m_zOffset = 0.0f;
447 bool iMatIdent =
true;
448 bool iMatDirty =
false;
452 struct Private{
explicit Private() =
default; };
456 : m_renderer(renderer), m_region(m_renderer)
458 std::cerr <<
"XXX ctor.x " << m_renderer.st() <<
"\n";
462 return std::make_shared<Shape>(Private(), renderer);
466 m_region.destroy(
gl);
473 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
474 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
482 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
483 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
485 constexpr const std::vector<OutlineShape>&
outlineShapes() const noexcept {
return m_oshapes; }
486 constexpr std::vector<OutlineShape>&
outlineShapes() noexcept {
return m_oshapes; }
493 m_region.addOutlineShape(o);
495 m_region.seal(
gl,
true);
503 m_renderer.setColor(m_color);
504 m_renderer.updateAll(
gl);
514 m_rotation.rotateByAngleZ( M_PI_2);
515 Vec3f dir = m_rotation.rotateVector(
Vec3f(1, 0, 0));
516 m_rotation.rotateByAngleZ(-M_PI_2);
517 Vec3f d_p = dir * m_velo * dt;
522 float&
velo() noexcept {
return m_velo; }
539 void applyMatToMv(
PMVMat4f& pmvMat)
noexcept {
547 void updateMat() noexcept {
548 bool hasPos = !m_position.is_zero();
550 bool hasRotate = !m_rotation.isIdentity();
551 bool hasRotPivot =
false;
552 for(OutlineShape& o : m_oshapes){
553 const Vec3f& ctr = o.bounds().center();
554 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
556 if( sameScaleRotatePivot ) {
558 iMat.setToTranslation(m_position);
560 iMat.translate(
Vec3f(ctr).mul(m_scale));
561 iMat.rotate(m_rotation);
563 iMat.translate(-ctr);
564 }
else if( hasRotate || hasScale ) {
566 iMat.setToTranslation(m_position);
570 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
571 iMat.rotate(m_rotation);
572 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
575 iMat.translate(
Vec3f(ctr).mul(m_scale));
576 iMat.rotate(m_rotation);
577 iMat.translate(
Vec3f(-ctr).mul(m_scale));
582 iMat.translate(
Vec3f(ctr).mul(m_scale));
584 iMat.translate(
Vec3f(-ctr).mul(m_scale));
586 }
else if( hasPos ) {
588 iMat.setToTranslation(m_position);
std::shared_ptr< Shape > ShapeRef
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
void useProgram(GL &gl, bool on)
static constexpr std::string_view GLSL_PARAM_COMMENT_START
GraphRenderer(PMVMat4f &pmvMat, ShaderState &st)
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
void setColor(const Vec4f &c) 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
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
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 ...
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.
#define jau_PLAIN_PRINT(printPrefix, fmt,...)
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
std::shared_ptr< Shape > ShapeRef
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
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...
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.