Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
RenderState.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_RENDERSTATE_HPP_
12#define JAU_GAMP_GRAPH_GL_RENDERSTATE_HPP_
13
14#include <string>
15#include <string_view>
16
17#include <jau/basic_types.hpp>
19#include <jau/math/vec4f.hpp>
21
26
29
30namespace gamp::graph::gl {
31
32 using namespace gamp::render::gl;
33 using namespace gamp::render::gl::glsl;
34
35 /** \addtogroup Gamp_Graph
36 *
37 * @{
38 */
39
40 /**
41 * The RenderState is owned by GraphRenderer.
42 *
43 * It holds rendering state data like jau::math::util::PMVMat4f, viewport,
44 * but also the current staticColor().
45 */
47 private:
48 constexpr static std::string_view thisKey = "gamp.graph.gl.RenderState" ;
49
50 public:
51 /** Minimum pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa. */
52 constexpr static int MIN_AA_QUALITY = 0;
53 /** Maximum pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa. */
54 constexpr static int MAX_AA_QUALITY = 1;
55 /** Default pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa. */
56 constexpr static int DEFAULT_AA_QUALITY = MAX_AA_QUALITY;
57 /** Returns clipped AA quality value to [MIN_AA_QUALITY..MAX_AA_QUALITY] */
58 constexpr static int clipAAQuality(int v) { return std::min(MAX_AA_QUALITY, std::max(v, MIN_AA_QUALITY)); }
59
60 /** Minimum pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa or RenderMode::msaa. */
61 constexpr static int MIN_AA_SAMPLE_COUNT = 1;
62 /** Maximum pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa or RenderMode::msaa. */
63 constexpr static int MAX_AA_SAMPLE_COUNT = 8;
64 /** Default pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vbaa or RenderMode::msaa. */
65 constexpr static int DEFAULT_AA_SAMPLE_COUNT = 4;
66 /** Returns clipped AA sample-count to [MIN_AA_SAMPLE_COUNT..MAX_AA_SAMPLE_COUNT] */
67 constexpr static int clipAASampleCount(int v) { return std::min(MAX_AA_SAMPLE_COUNT, std::max(v, MIN_AA_SAMPLE_COUNT)); }
68
69 /**
70 * Bitfield hint, {@link #hintBitsSet(int) if set}
71 * stating <i>enabled</i> {@link GL#GL_BLEND}, otherwise <i>disabled</i>.
72 * <p>
73 * Shall be set via {@link #setHintBits(int)} and cleared via {@link #clearHintBits(int)}.
74 * </p>
75 * <p>
76 * If set, {@link GLRegion#draw(GL2ES2, RegionRenderer) GLRegion's draw-method}
77 * will set the proper {@link GL#glBlendFuncSeparate(int, int, int, int) blend-function}
78 * and the clear-color to <i>transparent-black</i> in case of {@link Region#isTwoPass(int) multipass} FBO rendering.
79 * </p>
80 * <p>
81 * Shall be set by custom code, e.g. via {@link RegionRenderer}'s
82 * enable and disable {@link RegionRenderer.GLCallback} as done in
83 * {@link RegionRenderer#defaultBlendEnable} and {@link RegionRenderer#defaultBlendDisable}.
84 * </p>
85 */
86 constexpr static int BITHINT_BLENDING_ENABLED = 1 << 0 ;
87
88 /**
89 * Bitfield hint, {@link #hintBitsSet(int) if set}
90 * stating globally <i>enabled</i> {@link GL#GL_DEPTH_TEST}, otherwise <i>disabled</i>.
91 * <p>
92 * Shall be set via {@link #setHintBits(int)} and cleared via {@link #clearHintBits(int)}.
93 * </p>
94 * <p>
95 * {@link GLRegion#draw(GL2ES2, RegionRenderer) GLRegion's draw-method}
96 * may toggle depth test, and reset it's state according to this hint.
97 * </p>
98 * <p>
99 * Shall be set by custom code, e.g. after {@link RenderState} or {@link RegionRenderer} construction.
100 * </p>
101 */
102 constexpr static int BITHINT_GLOBAL_DEPTH_TEST_ENABLED = 1 << 1 ;
103
104 constexpr static int DEBUG_LINESTRIP = 1 << 0 ;
105
106 /**
107 * Representation of {@link RenderState} data per {@link ShaderProgram}
108 * as {@link GLUniformData}.
109 * <p>
110 * FIXME: Utilize 'ARB_Uniform_Buffer_Object' where available!
111 * </p>
112 */
114 private:
115 RenderState& m_rs;
116 GLUniformSyncPMVMat4fRef gcu_PMVMatrix;
117 GLUniformScalarF32Ref gcu_Weight;
118 GLUniformVec4fRef gcu_StaticColor;
119 int rsId = -1;
120
121 public:
123 : m_rs(rs), gcu_PMVMatrix(rs.gcu_PMVMatrix)
124 {
125 gcu_Weight = GLUniformScalarF32::create(RenderNames::gcu_Weight, m_rs.m_weight);
126 gcu_StaticColor = GLUniformVec4f::create(RenderNames::gcu_StaticColor, m_rs.m_staticColor);
127 }
128
129 constexpr int getRenderStateId() const noexcept { return rsId; }
130
131 /**
132 * <p>
133 * Since {@link RenderState} data is being used in multiple
134 * {@link ShaderProgram}s the data must always be written.
135 * </p>
136 * @param gl
137 * @param updateLocation
138 * @param renderModes
139 * @param setPMVMat01
140 * @param throwOnError
141 * @return true if no error occurred, i.e. all locations found, otherwise false.
142 */
143 bool update(GL& gl, RenderState& rs, bool updateLocation, RenderMode renderMode,
144 bool setPMVMat01, bool pass1, bool throwOnError) {
145 if( rs.m_id != rsId ) {
146 // Assignment of Renderstate buffers to uniforms (no copy, direct reference)
147 gcu_PMVMatrix = rs.gcu_PMVMatrix;
148 gcu_Weight->scalar() = rs.m_weight;
149 gcu_StaticColor->vec4f() = rs.m_staticColor;
150 rsId = rs.m_id;
151 }
152 bool res = true;
153 if( rs.m_sp && rs.m_sp->inUse() ) {
154 if( setPMVMat01 ) {
155 bool r0 = rs.updateUniformDataLoc(gl, updateLocation, true, *gcu_PMVMatrix, throwOnError);
156 res = res && r0;
157 }
158 if( pass1 ) {
159 if( gamp::graph::hasVariableWeight( renderMode ) ) {
160 const bool r0 = rs.updateUniformDataLoc(gl, updateLocation, true, *gcu_Weight, throwOnError);
161 res = res && r0;
162 }
163 {
164 const bool r0 = rs.updateUniformDataLoc(gl, updateLocation, true, *gcu_StaticColor, throwOnError);
165 res = res && r0;
166 }
167 }
168 }
169 return res;
170 }
171
172 std::string toString() {
173 std::string sb("ProgramLocal[rsID ");
174 sb.append(std::to_string(rsId)).append("\n");
175 // pmvMatrix.toString(sb, "%.2f");
176 sb.append(gcu_PMVMatrix->toString()).append(", ").append("\n");
177 sb.append(gcu_StaticColor->toString()).append(", ");
178 sb.append(gcu_Weight->toString()).append("]");
179 return sb;
180 }
181 };
182
183 private:
184 int m_id;
185 GLUniformSyncPMVMat4fRef gcu_PMVMatrix;
186 float m_weight;
187 jau::math::Vec4f m_staticColor;
188 /** Pass2 AA-quality rendering {@value} for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT}. */
189 int m_aaQuality;
190 /** Default pass2 AA sample count {@value} for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT} or {@link Region#MSAA_RENDERING_BIT}. */
191 int m_sampleCount;
192 /** Optional clipping {@link Frustum}, which shall be pre-multiplied with the Mv-matrix. Null if unused. */
193 jau::math::geom::Frustum m_clipFrustum;
194 bool m_useFrustumClipping;
195 int m_hintBits;
196 int m_debugBits;
197 ShaderProgramRef m_sp;
198 static jau::sc_atomic_int nextID;
199
200 static int getNextID() { return nextID++; }
201
202 public:
203 /**
204 * Create a RenderState, a composition of RegionRenderer
205 * @param pmvMat used PMVMatrix4f, could be shared
206 */
208 : m_id( getNextID() ),
209 gcu_PMVMatrix(GLUniformSyncPMVMat4fExt::create(RenderNames::gcu_PMVMatrix, pmvMat, pmvMat.getSyncPMvMviMvit())), // P, Mv, Mvi and Mvit
210 m_weight(1), m_staticColor(1, 1, 1, 1),
211 m_aaQuality(DEFAULT_AA_QUALITY), m_sampleCount(DEFAULT_AA_SAMPLE_COUNT),
212 m_clipFrustum(), m_useFrustumClipping(false),
213 m_hintBits(0), m_debugBits(0), m_sp(nullptr)
214 { }
215
216 constexpr int id() const noexcept { return m_id; }
217
218 /** Return the current {@link ShaderProgram} */
219 constexpr const ShaderProgramRef& shaderProgram() const noexcept { return m_sp; }
220 /** Return the current {@link ShaderProgram} */
221 constexpr ShaderProgramRef& shaderProgram() noexcept { return m_sp; }
222
223 /** Return whether the current {@link ShaderProgram} is {@link ShaderProgram#inUse() in use}. */
224 constexpr bool isShaderProgramInUse() const noexcept { return m_sp ? m_sp->inUse() : false; }
225
226 /**
227 * Sets the current {@link ShaderProgram} and enables it.
228 *
229 * If the given {@link ShaderProgram} is not {@link #getShaderProgram() the current}, method returns true, otherwise false.
230 *
231 * @param gl
232 * @param spNext the next current {@link ShaderProgram} to be set and enabled
233 * @return true if a new shader program is being used and hence external uniform-data and -location,
234 * as well as the attribute-location must be updated, otherwise false.
235 */
237 if( *spNext == *m_sp ) {
238 m_sp->useProgram(gl, true);
239 return false;
240 }
241 if( m_sp ) {
242 m_sp->notifyNotInUse();
243 }
244 m_sp = spNext;
245 m_sp->useProgram(gl, true);
246 return true;
247 }
248
249 const jau::math::util::PMVMat4f& getMatrix() const noexcept { return gcu_PMVMatrix->pmv(); }
250 jau::math::util::PMVMat4f& getMatrix() noexcept { return gcu_PMVMatrix->pmv(); }
251
252 static bool isWeightValid(float v) { return 0.0f <= v && v <= 1.9f ; }
253 float getWeight() { return m_weight; }
254 void setWeight(float v) {
255 if( !isWeightValid(v) ) {
256 throw jau::IllegalArgumentError("Weight out of range", E_FILE_LINE);
257 }
258 m_weight = v;
259 }
260
261 const jau::math::Vec4f& staticColor() const noexcept { return m_staticColor; }
262 jau::math::Vec4f& staticColor() noexcept { return m_staticColor; }
263
264 constexpr float weight() const noexcept { return m_weight; }
265
266 /** Sets pass2 AA-quality rendering value clipped to the range [{@link Region#MIN_AA_QUALITY}..{@link Region#MAX_AA_QUALITY}] for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT}. */
267 int setAAQuality(int v) { int q=clipAAQuality(v); m_aaQuality=q; return q;}
268 /** Returns pass2 AA-quality rendering value for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT}. */
269 constexpr int aaQuality() const noexcept { return m_aaQuality; }
270
271 /** Sets pass2 AA sample count clipped to the range [{@link Region#MIN_AA_SAMPLE_COUNT}..{@link Region#MAX_AA_SAMPLE_COUNT}] for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link #VBAA_RENDERING_BIT} or {@link Region#MSAA_RENDERING_BIT}. */
272 int setSampleCount(int v) { int s=clipAASampleCount(v); m_sampleCount=s; return s;}
273 /** Returns pass2 AA sample count for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link #VBAA_RENDERING_BIT} or {@link Region#MSAA_RENDERING_BIT}. */
274 constexpr int sampleCount() const noexcept { return m_sampleCount; }
275
276 /** Set the optional clipping {@link Frustum}, which shall be pre-multiplied with the Mv-matrix or null to disable. */
278 m_clipFrustum = clipFrustum;
279 m_useFrustumClipping=true;
280 }
281 void disableFrustumClipping() noexcept { m_useFrustumClipping = false; }
282 constexpr bool usesFrustumClipping() const noexcept { return m_useFrustumClipping; }
283
284 /** Returns the optional Mv-premultiplied clipping {@link Frustum} or nullptr if unused. */
285 jau::math::geom::Frustum* clipFrustum() { return m_useFrustumClipping ? &m_clipFrustum : nullptr; }
286
287 constexpr int hintBits() const noexcept { return m_hintBits; }
288 constexpr bool hintBitsSet(int bits) const noexcept { return bits == ( m_hintBits & bits ); }
289 void setHintBits(int bits) noexcept { m_hintBits |= bits; }
290 void clearHintBits(int bits) noexcept { m_hintBits &= ~bits; }
291
292 constexpr int debugBits() const noexcept { return m_debugBits; }
293 constexpr bool debugBitsSet(int mask) const noexcept { return mask == ( m_debugBits & mask ); }
294 void setDebugBits(int mask) noexcept { m_debugBits |= mask; }
295 void clearDebugBits(int mask) noexcept { m_debugBits &= ~mask; }
296
297 /**
298 *
299 * @param gl
300 * @param updateLocation
301 * @param data
302 * @param throwOnError
303 * @return true if no error occured, i.e. all locations found, otherwise false.
304 */
305 bool updateUniformLoc(GL& gl, bool updateLocation, GLUniformData& data, bool throwOnError) {
306 if( m_sp && ( updateLocation || 0 > data.location() ) ) {
307 const bool ok = 0 <= data.setLocation(gl, m_sp->program());
308 if( throwOnError && !ok ) {
309 m_sp->dumpSource();
310 throw RenderException("Could not locate "+data.name()+" in "+m_sp->toString()+", "+data.toString(), E_FILE_LINE);
311 }
312 return ok;
313 } else {
314 return true;
315 }
316 }
317
318 /**
319 *
320 * @param gl
321 * @param updateLocation
322 * @param updateData
323 * @param data
324 * @param throwOnError
325 * @return true if no error occured, i.e. all locations found, otherwise false.
326 */
327 bool updateUniformDataLoc(GL& gl, bool updateLocation, bool updateData, GLUniformData& data, bool throwOnError) {
328 updateLocation = updateLocation || 0 > data.location();
329 if( m_sp && updateLocation ) {
330 updateData = 0 <= data.setLocation(gl, m_sp->program());
331 if( throwOnError && !updateData ) {
332 m_sp->dumpSource();
333 throw RenderException("Could not locate "+data.name()+" in "+m_sp->toString()+", "+data.toString(), E_FILE_LINE);
334 }
335 }
336 if( updateData ){
337 data.send(gl);
338 return true;
339 } else {
340 return !updateLocation;
341 }
342 }
343
344 /**
345 * @param gl
346 * @param data
347 * @param throwOnError
348 * @return true if no error occured, i.e. all locations found, otherwise false.
349 */
350 bool updateAttributeLoc(GL& gl, bool updateLocation, GLArrayData& data, bool throwOnError) {
351 if( m_sp && ( updateLocation || 0 > data.location() ) ) {
352 const bool ok = 0 <= data.setLocation(gl, m_sp->program());
353 if( throwOnError && !ok ) {
354 m_sp->dumpSource();
355 throw RenderException("Could not locate "+data.name()+" in "+m_sp->toString()+", "+data.toString(), E_FILE_LINE);
356 }
357 return ok;
358 } else {
359 return true;
360 }
361 }
362
363 /**
364 * Only nullifies {@link ShaderProgram} reference owned by {@link RegionRenderer}.
365 */
366 /* pp */ void destroy() {
367 m_sp = nullptr; // owned by RegionRenderer
368 }
369
370 std::string toString() {
371 return "RenderState["+(m_sp ? m_sp->toString() : "n/a")+"]";
372 }
373 };
374
375 /**@}*/
376
377} // namespace gamp::graph::gl
378
379#endif // JAU_GAMP_GRAPH_GL_RENDERSTATE_HPP_
380
#define E_FILE_LINE
static constexpr std::string_view gcu_StaticColor
static constexpr std::string_view gcu_Weight
bool update(GL &gl, RenderState &rs, bool updateLocation, RenderMode renderMode, bool setPMVMat01, bool pass1, bool throwOnError)
constexpr int getRenderStateId() const noexcept
static constexpr int MIN_AA_SAMPLE_COUNT
Minimum pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vba...
static constexpr int BITHINT_GLOBAL_DEPTH_TEST_ENABLED
Bitfield hint, if set stating globally enabled GL#GL_DEPTH_TEST, otherwise disabled.
void setHintBits(int bits) noexcept
void disableFrustumClipping() noexcept
static constexpr int MAX_AA_SAMPLE_COUNT
Maximum pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vba...
constexpr int debugBits() const noexcept
constexpr int hintBits() const noexcept
constexpr float weight() const noexcept
bool updateUniformLoc(GL &gl, bool updateLocation, GLUniformData &data, bool throwOnError)
bool updateAttributeLoc(GL &gl, bool updateLocation, GLArrayData &data, bool throwOnError)
void clearHintBits(int bits) noexcept
static constexpr int DEFAULT_AA_SAMPLE_COUNT
Default pass2 AA sample count {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode::vba...
RenderState(jau::math::util::PMVMat4f &pmvMat)
Create a RenderState, a composition of RegionRenderer.
constexpr bool hintBitsSet(int bits) const noexcept
jau::math::geom::Frustum * clipFrustum()
Returns the optional Mv-premultiplied clipping Frustum or nullptr if unused.
jau::math::util::PMVMat4f & getMatrix() noexcept
static constexpr int clipAAQuality(int v)
Returns clipped AA quality value to [MIN_AA_QUALITY..MAX_AA_QUALITY].
constexpr int id() const noexcept
constexpr int aaQuality() const noexcept
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
bool setShaderProgram(GL &gl, ShaderProgramRef &spNext)
Sets the current ShaderProgram and enables it.
static constexpr int MAX_AA_QUALITY
Maximum pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode...
constexpr int sampleCount() const noexcept
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
void clearDebugBits(int mask) noexcept
int setAAQuality(int v)
Sets pass2 AA-quality rendering value clipped to the range [Region#MIN_AA_QUALITY....
static constexpr int MIN_AA_QUALITY
Minimum pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode...
bool updateUniformDataLoc(GL &gl, bool updateLocation, bool updateData, GLUniformData &data, bool throwOnError)
static constexpr int DEFAULT_AA_QUALITY
Default pass2 AA-quality rendering {@value} for Graph Region AA GraphRegion::renderMode(): RenderMode...
void setDebugBits(int mask) noexcept
static constexpr int DEBUG_LINESTRIP
static constexpr int BITHINT_BLENDING_ENABLED
Bitfield hint, if set stating enabled GL#GL_BLEND, otherwise disabled.
constexpr bool debugBitsSet(int mask) const noexcept
constexpr bool isShaderProgramInUse() const noexcept
Return whether the current ShaderProgram is in use.
int setSampleCount(int v)
Sets pass2 AA sample count clipped to the range [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COU...
constexpr ShaderProgramRef & shaderProgram() noexcept
Return the current ShaderProgram.
const jau::math::util::PMVMat4f & getMatrix() const noexcept
jau::math::Vec4f & staticColor() noexcept
constexpr const ShaderProgramRef & shaderProgram() const noexcept
Return the current ShaderProgram.
static bool isWeightValid(float v)
const jau::math::Vec4f & staticColor() const noexcept
constexpr bool usesFrustumClipping() const noexcept
void destroy()
Only nullifies ShaderProgram reference owned by RegionRenderer.
static constexpr int clipAASampleCount(int v)
Returns clipped AA sample-count to [MIN_AA_SAMPLE_COUNT..MAX_AA_SAMPLE_COUNT].
void setFrustumClipping(const jau::math::geom::Frustum &clipFrustum) noexcept
Set the optional clipping Frustum, which shall be pre-multiplied with the Mv-matrix or null to disabl...
Interface for a generic data buffer to be used for OpenGL arrays.
GLSL uniform data wrapper encapsulating data to be uploaded to the GPU as a uniform.
static std::shared_ptr< GLUniformScalarF32 > create(stringview_t name, float v)
static std::shared_ptr< GLUniformVec4f > create(stringview_t name, const jau::math::Vec4f &v)
Providing frustum planes derived by different inputs (P*MV, ..) used to classify objects.
Definition frustum.hpp:78
ordered_atomic< int, std::memory_order_seq_cst > sc_atomic_int
SC atomic integral scalar integer.
std::shared_ptr< GLUniformSyncPMVMat4f > GLUniformSyncPMVMat4fRef
std::shared_ptr< GLUniformScalarF32 > GLUniformScalarF32Ref
std::shared_ptr< GLUniformVec4f > GLUniformVec4fRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
RenderMode
Render mode bits being part of the shader-selection-key.
constexpr bool hasVariableWeight(RenderMode renderMode) noexcept
Vector4F< float > Vec4f
Definition vec4f.hpp:360
PMVMatrix4< float > PMVMat4f
Definition pmvmat4.hpp:1463