Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GraphRegion.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com> (C++, Java) and Rami Santina (Java)
3 * Copyright Gothel Software e.K. and the authors
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11#ifndef JAU_GAMP_GRAPH_GL_REGION_HPP_
12#define JAU_GAMP_GRAPH_GL_REGION_HPP_
13
14#include <string>
15
16#include <jau/enum_util.hpp>
18
22
27
28namespace gamp::graph::gl {
29
30 using namespace jau::math;
31 using namespace jau::math::geom;
32 using namespace jau::enums;
34
35 using namespace gamp::render::gl;
36 using namespace gamp::render::gl::glsl;
37
38 /** \addtogroup Gamp_Graph
39 *
40 * @{
41 */
42
44 public:
46
47 constexpr static int DEFAULT_TWO_PASS_TEXTURE_UNIT = 0;
48
49 enum class DirtyBits : uint16_t {
50 none = 0,
51 shape = 1 << 0,
52 state = 1 << 1
53 };
55
56 private:
57 RenderMode m_renderMode;
60 int m_num_vertices, m_num_indices;
61 AABBox3f m_box;
62 DirtyBits m_dirty;
63
64 constexpr static GLsizei arrayCompsPerElement(RenderMode m) noexcept {
65 GLsizei c = 3+3; // vec4 gca_Vertex (skipping 4th comp) + vec3 gca_CurveParam
66 if( gamp::graph::hasNormalChannel(m) ) { c+=3; } // vec3 gca_Normal
67 if( is_set(m, RenderMode::colorchannel) ) { c+=4; } // vec4 gca_Color
68 return c;
69 }
70
71 public:
73 : m_renderMode(m), m_array(GLFloatArrayDataServer::createGLSLInterleaved(arrayCompsPerElement(m), false, 256, GL_STATIC_DRAW)),
74 m_indices(GLUIntArrayDataServer::createData(3, 256, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER)),
75 m_num_vertices(0), m_num_indices(0), m_box(), m_dirty(DirtyBits::shape | DirtyBits::state)
76 {
77 m_array->addGLSLSubArray(RenderNames::gca_Vertex, 3, GL_ARRAY_BUFFER);
78 m_array->addGLSLSubArray(RenderNames::gca_CurveParam, 3, GL_ARRAY_BUFFER);
80 m_array->addGLSLSubArray(RenderNames::gca_Normal, 3, GL_ARRAY_BUFFER);
81 }
83 m_array->addGLSLSubArray(RenderNames::gca_Color, 4, GL_ARRAY_BUFFER);
84 }
85 }
86
87 constexpr RenderMode renderMode() const noexcept { return m_renderMode; }
88 constexpr bool hasNormalChannel() const noexcept { return gamp::graph::hasNormalChannel(m_renderMode); }
89 constexpr bool hasColorChannel() const noexcept { return gamp::graph::hasColorChannel(m_renderMode); }
90 constexpr GLsizei arrayCompsPerElement() const noexcept { return arrayCompsPerElement(m_renderMode); }
91
92 GLsizei indexCount() const noexcept { return m_num_indices; }
93 GLsizei vertexCount() const noexcept { return m_num_vertices; }
94
95 void clear(GL& gl) {
96 m_array->clear(gl);
97 m_indices->clear(gl);
98 m_num_indices = 0;
99 m_num_vertices = 0;
100 }
101 void seal(GL& gl, bool seal_) {
102 m_array->seal(gl, seal_);
103 m_indices->seal(gl, seal_);
104 // m_array->enableBuffer(gl, false);
105 // m_indices->enableBuffer(gl, false);
106 }
107
108 private:
109 void pushVertex(const Vertex& v, const Vec3f& normal) {
110 // jau::PLAIN_PRINT(true, "pushVertex.0[%d]: v %s]", m_num_vertices, v.toString().c_str());
111 m_array->put3f(v.coord());
112 m_array->put3f(v.texCoord());
113 if( hasNormalChannel() ) {
114 m_array->put3f(normal);
115 }
116 ++m_num_vertices;
117 }
118 void pushVertex(const Vertex& v, const Vec3f& normal, const Vec4f& color) {
119 // jau::PLAIN_PRINT(true, "pushVertex.0[%d]: v %s]", m_num_vertices, v.toString().c_str());
120 m_array->put3f(v.coord());
121 m_array->put3f(v.texCoord());
122 if( hasNormalChannel() ) {
123 m_array->put3f(normal);
124 }
125 if( hasColorChannel() ) {
126 m_array->put4f(color);
127 }
128 ++m_num_vertices;
129 }
130 void pushIndices(uint32_t i, uint32_t j, uint32_t k) {
131 // jau::PLAIN_PRINT(true, "pushIndices.0[%d]: %u, %u, %u]", m_num_indices, i, j, k);
132 m_indices->putN(i, j, k);
133 m_num_indices += 3;
134 }
135 void pushNewVerticesIdx(const Vertex& vertIn1, const Vertex& vertIn2, const Vertex& vertIn3, const Vec3f& normal) {
136 pushIndices(m_num_vertices, m_num_vertices+1, m_num_vertices+2);
137 pushVertex(vertIn1, normal);
138 pushVertex(vertIn2, normal);
139 pushVertex(vertIn3, normal);
140 }
141
142 public:
145 seal(gl, true);
146 }
147
149 if( Graph::DEBUG_MODE ) {
150 jau::PLAIN_PRINT(true, "add.0 num[vertices %d, indices %d]", m_num_vertices, m_num_indices);
151 jau::PLAIN_PRINT(true, "add.0 array: %s", m_array->toString().c_str());
152 jau::PLAIN_PRINT(true, "add.0 indices: %s", m_indices->toString().c_str());
153 }
154 const TriangleRefList& trisIn = shape.getTriangles();
155 const VertexList& vertsIn = shape.getVertices();
156 if( Graph::DEBUG_MODE ) {
157 jau::PLAIN_PRINT(true, "add.0 triangles %u, vertices %u", trisIn.size(), vertsIn.size());
158 }
159 {
160 glmemsize_t verticeCount = (glmemsize_t)vertsIn.size() + shape.addedVertexCount();
161 glmemsize_t indexCount = (glmemsize_t)trisIn.size() * 3;
162 m_array->growIfNeeded(verticeCount * m_array->compsPerElem());
163 m_indices->growIfNeeded(indexCount); // * m_indices->compsPerElem());
164 }
165 uint32_t idxOffset = m_num_vertices;
166 if( vertsIn.size() >= 3 ) {
167 //
168 // Processing Vertices
169 //
170 for(const Vertex& v : vertsIn) {
171 pushVertex(v, shape.normal());
172 }
173 constexpr static uint32_t max_index = std::numeric_limits<uint32_t>::max() / sizeof(uint32_t);
174 OutlineShape::size_type trisIn_sz = trisIn.size();
175 for(OutlineShape::size_type i=0; i < trisIn_sz; ++i) {
176 const TriangleRef& triIn = trisIn[i];
177 // triEx.addVertexIndicesOffset(idxOffset);
178 // triangles.add( triEx );
179 Triangle::trivert_t& triInVertices = triIn->vertices();
180 uint32_t tv0Idx = triInVertices[0].id();
181 if ( max_index - idxOffset > tv0Idx ) {
182 // valid 'known' idx - move by offset
183 pushIndices(tv0Idx+idxOffset,
184 triInVertices[1].id()+idxOffset,
185 triInVertices[2].id()+idxOffset);
186 } else {
187 // FIXME: If exceeding max_indices, we would need to generate a new buffer w/ indices
188 pushNewVerticesIdx(triInVertices[0], triInVertices[1], triInVertices[2], shape.normal());
189 }
190 }
191 }
193 if( Graph::DEBUG_MODE ) {
194 jau::PLAIN_PRINT(true, "add.x num[vertices %d, indices %d (%d)]", m_num_vertices,
195 m_num_indices, m_indices->elemCount() * m_indices->compsPerElem());
196 jau::PLAIN_PRINT(true, "add.x array: %s", m_array->toString().c_str());
197 jau::PLAIN_PRINT(true, "add.x indices: %s", m_indices->toString().c_str());
198 }
199 assert(m_num_indices == m_indices->elemCount() * m_indices->compsPerElem());
200 }
201
202 /**
203 * Renders the associated OGL objects specifying
204 * current width/hight of window for optional multi pass rendering of the region.
205 *
206 * User shall consider {@link RegionRenderer#enable(GL2ES2, boolean) enabling}
207 * the renderer beforehand and {@link RegionRenderer#enable(GL2ES2, boolean) disabling}
208 * it afterwards when used in conjunction with other renderer.
209 *
210 * Users shall also consider setting the {@link GL#glClearColor(float, float, float, float) clear-color}
211 * appropriately:
212 * - If {@link GL#GL_BLEND blending} is enabled, <i>RGB</i> shall be set to text color, otherwise
213 * blending will reduce the alpha seam's contrast and the font will appear thinner.
214 * - If {@link GL#GL_BLEND blending} is disabled, <i>RGB</i> shall be set to the actual desired background.
215 * The <i>alpha</i> component shall be set to zero.
216 * Note: If {@link GL#GL_BLEND blending} is enabled, the
217 * {@link RegionRenderer} might need to be
218 * {@link RegionRenderer#create(Vertex.Factory<? extends Vertex>, RenderState, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) created}
219 * with the appropriate {@link RegionRenderer.GLCallback callbacks}.
220 * @param gl current {@link GL2ES2}.
221 * @param renderer the GraphRenderer to be used
222 * @see RegionRenderer#enable(GL2ES2, boolean)
223 * @see RegionRenderer#setAAQuality(int)
224 * @see RegionRenderer#setSampleCount(int)
225 * @see RegionRenderer#setClipBBox(com.jogamp.math.geom.AABBox)
226 */
227 void draw(GL &gl, GraphRenderer& renderer) {
228 const RenderState& rs = renderer.renderState();
229 int pass2Quality = rs.aaQuality();
230 int pass2SampleCount = rs.sampleCount();
231 RenderMode curRenderMode = RenderMode::none;
232 if( 0 == pass2SampleCount ) {
233 // no sampling, reduce to pass1
234 curRenderMode = renderMode() & ~( RenderMode::vbaa | RenderMode::msaa );
235 } else {
236 // normal 2-pass sampling
237 curRenderMode = renderMode();
238 }
239 // System.err.println("XXX.0 "+Region.getRenderModeString(getRenderModes(), sampleCount[0], 0)+": "+
240 // Region.getRenderModeString(lastRenderModes, sampleCount[0], 0)+" -> "+Region.getRenderModeString(curRenderModes, sampleCount[0], 0));
241
242 if( m_lastRenderMode != curRenderMode ) {
245 } else if( Region.isGraphAA(curRenderModes) &&
246 ( lastPass2Quality != pass2Quality || lastPass2SampleCount != pass2SampleCount ) ) {
248 }
249 if( isShapeDirty() ) {
250 updateImpl(gl, renderer, curRenderModes);
251 }
252 drawImpl(gl, renderer, curRenderModes);
253 clearDirtyBits(DIRTY_SHAPE|DIRTY_STATE);
254 lastRenderModes = curRenderModes;
255 lastPass2Quality = pass2Quality;
256 lastPass2SampleCount = pass2SampleCount;
257
258 renderer.useProgram(gl, true);
259
260 m_array->enableBuffer(gl, true);
261 m_indices->bindBuffer(gl, true); // keeps VBO binding
262
263 ::glEnable(GL_BLEND);
264 ::glBlendEquation(GL_FUNC_ADD); // default
265 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
266
267 ::glDrawElements(GL_TRIANGLES, m_indices->elemCount() * m_indices->compsPerElem(), GL_UNSIGNED_INT, nullptr);
268
269
270 m_indices->bindBuffer(gl, false);
271 m_array->enableBuffer(gl, false);
272 // renderer.useProgram(gl, false);
273 }
274
275 private:
276 RenderMode m_lastRenderMode = RenderMode::none;
277 int m_lastPass2Quality = -1;
278 int m_lastPass2SampleCount = -1;
279
280 public:
281 /** @return the AxisAligned bounding box of current region */
282 constexpr const AABBox3f& bounds() const noexcept { return m_box; }
283
284 /**
285 * Mark this region's shape dirty,
286 * i.e. its vertices, triangles, lines and/or color-texture coordinates changed.
287 * <p>
288 * The data will be re-uploaded to the GPU at next {@link GLRegion#draw(com.jogamp.opengl.GL2ES2, com.jogamp.graph.curve.opengl.RegionRenderer) draw(..)}.
289 * </p>
290 * <p>
291 * In 2-pass mode, this implies updating the FBO itself as well.
292 * </p>
293 */
294 void markShapeDirty() noexcept { m_dirty |= DirtyBits::shape; }
295
296 /** Returns true if this region's shape are dirty, see {@link #markShapeDirty()}. */
297 constexpr bool isShapeDirty() const noexcept { return is_set(m_dirty, DirtyBits::shape); }
298
299 /**
300 * Mark this region's render-state dirty, i.e. re-selecting a shader program regarding color-texture and -channel,
301 * and rendering the region into the FBO in 2-pass mode.
302 * <p>
303 * In 1-pass mode, re-selection of the shader-program is based on color-texture and -channel only.
304 * </p>
305 */
306 void markStateDirty() noexcept { m_dirty |= DirtyBits::state; }
307
308 /** Returns true if this region's state is dirty, see {@link #markStateDirty()}. */
309 constexpr bool isStateDirty() const noexcept { return is_set(m_dirty, DirtyBits::state); }
310
311 constexpr DirtyBits dirtyBits() const noexcept { return m_dirty; }
312
313 private:
314 /**
315 * See {@link #markShapeDirty()} and {@link #markStateDirty()}.
316 */
317 void clearDirtyBits(DirtyBits v) { m_dirty &= ~v; }
318
319 public:
320 std::string toString() noexcept {
321 std::string r("Region[");
322 r.append(jau::to_string(this)).append(", ").append(to_string(m_renderMode))
323 .append(", dirty "+to_string(m_dirty)).append(", vertices ").append(std::to_string(m_num_vertices))
324 .append(", indices ").append(std::to_string(m_num_indices))
325 .append(", box ").append(m_box.toString()).append("]");
326 return r;
327 }
328 };
329
330 /**@}*/
331
332} // namespace gamp::graph::gl
333
334#endif // JAU_GAMP_GRAPH_GL_REGION_HPP_
335
static bool DEBUG_MODE
Definition Graph.hpp:24
A Generic shape objects which is defined by a list of Outlines.
std::array< Vertex, 3 > trivert_t
constexpr const Vec3f & texCoord() const noexcept
Definition PrimTypes.hpp:96
constexpr const Vec3f & coord() const noexcept
Definition PrimTypes.hpp:93
constexpr DirtyBits dirtyBits() const noexcept
void draw(GL &gl, GraphRenderer &renderer)
Renders the associated OGL objects specifying current width/hight of window for optional multi pass r...
constexpr bool hasColorChannel() const noexcept
constexpr const AABBox3f & bounds() const noexcept
JAU_MAKE_BITFIELD_ENUM_STRING_MEMBER(DirtyBits, shape, state)
constexpr RenderMode renderMode() const noexcept
constexpr bool hasNormalChannel() const noexcept
void markStateDirty() noexcept
Mark this region's render-state dirty, i.e.
constexpr bool isStateDirty() const noexcept
Returns true if this region's state is dirty, see markStateDirty().
constexpr bool isShapeDirty() const noexcept
Returns true if this region's shape are dirty, see markShapeDirty().
jau::darray< uint32_t, glmemsize_t > u32buffer_t
void addOutlineShape(GL &gl, OutlineShape &shape)
static constexpr int DEFAULT_TWO_PASS_TEXTURE_UNIT
constexpr GLsizei arrayCompsPerElement() const noexcept
void markShapeDirty() noexcept
Mark this region's shape dirty, i.e.
GLsizei vertexCount() const noexcept
void seal(GL &gl, bool seal_)
void addOutlineShape(OutlineShape &shape)
GLsizei indexCount() const noexcept
std::string toString() noexcept
const RenderState & renderState() const noexcept
static constexpr std::string_view gca_Color
Color attribute (optional), USE_COLOR_CHANNEL:
static constexpr std::string_view gca_Vertex
The vertex attribute.
static constexpr std::string_view gca_CurveParam
Curve texture coord attribute.
static constexpr std::string_view gca_Normal
Normal attribute (optional), USE_NORMAL_CHANNEL:
The RenderState is owned by GraphRenderer.
constexpr int aaQuality() const noexcept
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
constexpr int sampleCount() const noexcept
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
Definition darray.hpp:154
constexpr size_type size() const noexcept
Like std::vector::size().
Definition darray.hpp:1115
Axis Aligned Bounding Box.
Definition aabbox3f.hpp:43
Represents a affine 2x3 transformation matrix in column major order (memory layout).
constexpr bool is_set(const E mask, const E bits) noexcept
GLArrayDataServer< float > GLFloatArrayDataServer
GLsizeiptr glmemsize_t
Compatible with ssize_t.
Definition GLBuffers.hpp:26
GLArrayDataServerRef< float > GLFloatArrayDataServerRef
GLArrayDataServer< uint32_t > GLUIntArrayDataServer
GLArrayDataServerRef< uint32_t > GLUIntArrayDataServerRef
constexpr bool hasNormalChannel(RenderMode m) noexcept
jau::darray< Vertex, uint32_t > VertexList
RenderMode
Render mode bits being part of the shader-selection-key.
std::shared_ptr< Triangle > TriangleRef
constexpr bool hasColorChannel(RenderMode m) noexcept
jau::darray< TriangleRef, uint32_t > TriangleRefList
@ none
One pass none rendering either using no AA or underlying full-screen AA (fsaa) nor extra channels nor...
@ msaa
MSAA based Anti-Aliasing, a two pass region rendering, slower and more resource hungry (FBO with samp...
@ vbaa
View based Anti-Aliasing, a two pass region rendering, slower and more resource hungry (FBO),...
@ colorchannel
If set, a color channel attribute per vertex is added to the stream, otherwise static color can being...
Vector4F< float > Vec4f
Definition vec4f.hpp:360
Vector3F< float > Vec3f
Definition vec3f.hpp:422
std::string to_string(const math_error_t v) noexcept
Returns std::string representation of math_error_t.
Author: Sven Gothel sgothel@jausoft.com Copyright Gothel Software e.K.
Definition enum_util.hpp:65
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
Definition debug.cpp:264
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.