Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GraphRenderer.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_RENDERER_HPP_
12#define JAU_GAMP_GRAPH_GL_RENDERER_HPP_
13
14#include <string_view>
15#include <jau/basic_types.hpp>
16#include <jau/math/recti.hpp>
17
21
25
26namespace gamp::graph::gl {
27
28 using namespace jau::math;
29 using namespace jau::math::geom;
30 using namespace jau::enums;
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 * OpenGL GraphRenderer
42 *
43 * All GraphRegion rendering operations utilize a GraphRenderer.
44 *
45 * The GraphRenderer owns its {@link RenderState}, a composition.
46 *
47 * The GraphRenderer manages and owns all used ShaderProgram instances, a composition.
48 *
49 * At its {@link #destroy(GL2ES2) destruction}, all {@link ShaderProgram}s and its {@link RenderState}
50 * will be destroyed and released.
51 */
53 public:
54 /**
55 * May be passed to
56 * {@link RegionRenderer#create(Vertex.Factory<? extends Vertex>, RenderState, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) RegionRenderer ctor},
57 * e.g.
58 * <ul>
59 * <li>{@link RegionRenderer#defaultBlendEnable}</li>
60 * <li>{@link RegionRenderer#defaultBlendDisable}</li>
61 * </ul>
62 *
63 * @param gl a current GL context
64 * @param renderer GraphRenderer calling this method.
65 */
66 typedef jau::function<bool(GL& gl, GraphRenderer& renderer)> GLCallback;
67
68 /**
69 * Default {@link GL#GL_BLEND} <i>enable</i> {@link GLCallback},
70 * turning-off depth writing via {@link GL#glDepthMask(bool)} if {@link RenderState#BITHINT_GLOBAL_DEPTH_TEST_ENABLED} is set
71 * and turning-on the {@link GL#GL_BLEND} state.
72 * <p>
73 * Implementation also sets {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint},
74 * which will cause {@link GLRegion#draw(GL2ES2, RegionRenderer) GLRegion's draw-method}
75 * to set the proper {@link GL#glBlendFuncSeparate(int, int, int, int) blend-function}
76 * and the clear-color to <i>transparent-black</i> in case of {@link Region#isTwoPass(int) multipass} FBO rendering.
77 * </p>
78 * @see #create(GLCallback, GLCallback)
79 * @see #enable(GL2ES2, bool)
80 */
82
83 /**
84 * Default {@link GL#GL_BLEND} <i>disable</i> {@link GLCallback},
85 * simply turning-off the {@link GL#GL_BLEND} state
86 * and turning-on depth writing via {@link GL#glDepthMask(bool)} if {@link RenderState#BITHINT_GLOBAL_DEPTH_TEST_ENABLED} is set.
87 * <p>
88 * Implementation also clears {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}.
89 * </p>
90 * @see #create(GLCallback, GLCallback)
91 * @see #enable(GL2ES2, bool)
92 */
94
95 static constexpr bool DEBUG_MODE = true;
96 static constexpr std::string_view GLSL_PARAM_COMMENT_START = "\n// Gamp Graph Parameter Start\n";
97 static constexpr std::string_view GLSL_PARAM_COMMENT_END = "// Gamp Graph Parameter End\n\n";
98 static constexpr std::string_view GLSL_USE_COLOR_CHANNEL = "#define USE_COLOR_CHANNEL 1\n";
99 static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL = "#define USE_NORMAL_CHANNEL 1\n";
100 static constexpr std::string_view GLSL_USE_LIGHT0 = "#define USE_LIGHT0 1\n";
101 static constexpr std::string_view GLSL_USE_COLOR_TEXTURE = "#define USE_COLOR_TEXTURE 1\n";
102 static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING = "#define USE_FRUSTUM_CLIPPING 1\n";
103 static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT = "#define SAMPLE_COUNT ";
104 static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT = "const float sample_count = ";
105 static constexpr std::string_view GLSL_MAIN_BEGIN = "void main (void)\n{\n";
106 static constexpr std::string_view gcuTexture2D = "gcuTexture2D";
107 static constexpr std::string_view colTexLookupFuncName = "texture2D";
108 static constexpr std::string_view GLSL_USE_DISCARD = "#define USE_DISCARD 1\n";
109 static constexpr std::string_view shader_basename = "curverenderer01";
110 static constexpr std::string_view source_dir = "impl/graph/glsl";
111 static constexpr std::string_view bin_dir = "impl/graph/glsl/bin";
112
114 : m_rs(pmvMat), m_viewport(),
115 m_initialized(false)
116 {}
117
118 const RenderState& renderState() const noexcept { return m_rs; }
119 RenderState& renderState() noexcept { return m_rs; }
120 const Recti& viewport() const noexcept { return m_viewport; }
121 constexpr bool initialized() const noexcept { return m_initialized; }
122
123 private:
124 //
125 //
126 //
127
128 // FIXME: Really required to have sampler2D def. precision ? If not, we can drop getFragmentShaderPrecision(..) and use default ShaderCode ..
129 static constexpr std::string_view es2_precision_fp = "\nprecision mediump float;\nprecision mediump int;\nprecision mediump sampler2D;\n";
130
131 std::string_view getFragmentShaderPrecision(GL& gl) const noexcept {
132 if( gl.glProfile().isGLES() ) {
133 return es2_precision_fp;
134 }
137 }
138 return "";
139 }
140
141
142 class ShaderModeSelector1 {
143 public:
144 std::string_view tech;
145 std::string_view sub;
146 int sampleCount;
147
148 static ShaderModeSelector1 selectPass1(RenderMode renderMode) {
149 return hasVariableWeight(renderMode) ? PASS1_WEIGHT : PASS1_SIMPLE;
150 }
151
152 static ShaderModeSelector1 selectPass2(RenderMode renderMode, int quality, int sampleCount) {
153 if( isVBAA(renderMode) ) {
154 if( 0 == quality ) {
155 if( sampleCount < 2 ) {
156 return PASS2_VBAA_QUAL0_SAMPLES1;
157 } else if( sampleCount < 4 ) {
158 return PASS2_VBAA_QUAL0_SAMPLES2;
159 } else if( sampleCount < 8 ) {
160 return PASS2_VBAA_QUAL0_SAMPLES4;
161 } else {
162 return PASS2_VBAA_QUAL0_SAMPLES8;
163 }
164 } else {
165 switch( sampleCount ) {
166 case 0: // Fall through intended
167 case 1: return PASS2_VBAA_QUAL1_SAMPLES1;
168 case 2: return PASS2_VBAA_QUAL1_SAMPLES2;
169 case 3: return PASS2_VBAA_QUAL1_SAMPLES3;
170 case 4: return PASS2_VBAA_QUAL1_SAMPLES4;
171 case 5: return PASS2_VBAA_QUAL1_SAMPLES5;
172 case 6: return PASS2_VBAA_QUAL1_SAMPLES6;
173 case 7: return PASS2_VBAA_QUAL1_SAMPLES7;
174 default: return PASS2_VBAA_QUAL1_SAMPLES8;
175 }
176 }
177 } else {
178 return PASS2_MSAA; // Region.isMSAA(renderModes) and default
179 }
180 }
181 };
182 /** Pass-1: Curve Simple */
183 constexpr static ShaderModeSelector1 PASS1_SIMPLE { "curve", "_simple", 0 };
184
185 /** Pass-1: Curve Varying Weight */
186 constexpr static ShaderModeSelector1 PASS1_WEIGHT { "curve", "_weight", 0 };
187 /** Pass-2: MSAA */
188 constexpr static ShaderModeSelector1 PASS2_MSAA { "msaa", "", 0 };
189 /** Pass-2: VBAA Flipquad3, 1 sample */
190 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES1 { "vbaa", "_flipquad3", 1 };
191 /** Pass-2: VBAA Flipquad3, 2 samples */
192 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES2 { "vbaa", "_flipquad3", 2 };
193 /** Pass-2: VBAA Flipquad3, 4 samples */
194 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES4 { "vbaa", "_flipquad3", 4 };
195 /** Pass-2: VBAA Flipquad3, 8 samples */
196 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES8 { "vbaa", "_flipquad3", 8 };
197
198 /** Pass-2: VBAA Brute-Force, Odd, 1 samples */
199 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES1 { "vbaa", "_bforce_odd", 1 };
200 /** Pass-2: VBAA Brute-Force, Even, 2 samples */
201 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES2 { "vbaa", "_bforce_even", 2 };
202 /** Pass-2: VBAA Brute-Force, Odd, 3 samples */
203 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES3 { "vbaa", "_bforce_odd", 3 };
204 /** Pass-2: VBAA Brute-Force, Even, 4 samples */
205 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES4 { "vbaa", "_bforce_even", 4 };
206 /** Pass-2: VBAA Brute-Force, Odd, 5 samples */
207 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES5 { "vbaa", "_bforce_odd", 5 };
208 /** Pass-2: VBAA Brute-Force, Even, 6 samples */
209 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES6 { "vbaa", "_bforce_even", 6 };
210 /** Pass-2: VBAA Brute-Force, Odd, 7 samples */
211 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES7 { "vbaa", "_bforce_odd", 7 };
212 /** Pass-2: VBAA Brute-Force, Even, 8 samples */
213 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES8 { "vbaa", "_bforce_even", 8 };
214
215 class ShaderKey {
216 bool isTwoPass;
217 bool pass1;
218 ShaderModeSelector1 sms;
219 bool hasFrustumClipping; // pass1 or pass2
220 bool hasColorChannel; // pass1 only
221 bool hasColorTexture; // pass1 only
222 std::string_view colorTexSeqID;
223
224 size_t hashValue;
225
226 ShaderKey(bool isTwoPass, bool pass1, ShaderModeSelector1 sms,
227 bool hasFrustumClipping, bool hasColorChannel,
228 bool hasColorTexture, TextureSequence colorTexSeq, int colorTexSeqHash)
229 {
230 this.isTwoPass = isTwoPass;
231 this.pass1 = pass1;
232 this.sms = sms;
233 this.hasFrustumClipping = hasFrustumClipping;
234 this.hasColorChannel = hasColorChannel;
235 this.hasColorTexture = hasColorTexture;
236 if( hasColorTexture ) {
237 this.colorTexSeqID = colorTexSeq.getTextureFragmentShaderHashID();
238 } else {
239 this.colorTexSeqID = "";
240 }
241 hashValue = getShaderKey1(isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms, colorTexSeqHash);
242 }
243 @Override
244 public final int hashCode() { return hashValue; }
245 @Override
246 public bool equals(final Object other) {
247 if( this == other ) { return true; }
248 if( !(other instanceof ShaderKey) ) {
249 return false;
250 }
251 final ShaderKey o = (ShaderKey)other;
252 return isTwoPass == o.isTwoPass &&
253 pass1 == o.pass1 &&
254 // pass2Quality == o.pass2Quality && // included in sms
255 // sampleCount == o.sampleCount && // included in sms
256 sms.ordinal() == o.sms.ordinal() &&
257 hasFrustumClipping == o.hasFrustumClipping &&
258 hasColorChannel == o.hasColorChannel &&
259 hasColorTexture == o.hasColorTexture &&
260 colorTexSeqID.equals(o.colorTexSeqID);
261 }
262 @Override
263 public String toString() {
264 return shaderHashToString(hashValue, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms);
265 }
266 }
267 private static final boolean UseShaderPrograms0 = true;
268 private final LongObjectHashMap shaderPrograms0;
269 private final HashMap<ShaderKey, ShaderProgram> shaderPrograms1;
270
271 private static String shaderHashToString(final int hashCode, final boolean isTwoPass, final boolean pass1,
272 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
273 final ShaderModeSelector1 sms) {
274 return "ShaderHash[hash 0x"+Integer.toHexString(hashCode)+", is2Pass "+isTwoPass+", pass1 "+pass1+
275 ", has[clip "+hasFrustumClipping+", colChan "+hasColorChannel+", colTex "+hasColorTexture+"], "+sms+"]";
276 }
277 private static String shaderKeyToString(final long key, final boolean isTwoPass, final boolean pass1,
278 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
279 final ShaderModeSelector1 sms) {
280 return "ShaderKey[key 0x"+Long.toHexString(key)+", is2Pass "+isTwoPass+", pass1 "+pass1+
281 ", has[clip "+hasFrustumClipping+", colChan "+hasColorChannel+", colTex "+hasColorTexture+"], "+sms+"]";
282 }
283
284 private static long getShaderKey0(final boolean isTwoPass, final boolean pass1,
285 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
286 final ShaderModeSelector1 sms, final long colorTexSeqHash) {
287 // # | s |
288 // 0 | 1 | isTwoPass
289 // 1 | 1 | pass1
290 // 2 | 5 | ShaderModeSelector1
291 // 7 | 1 | hasFrustumClipping
292 // 8 | 1 | hasColorChannel
293 // 9 | 1 | hasColorTexture
294 // 32 | 32 | colorTexSeqHash
295 long hash = isTwoPass ? 1L : 0L;
296 hash |= ( pass1 ? 1L : 0L ) << 1;
297 hash |= (long)( sms.ordinal() & 0b11111 ) << 2; // incl. pass2Quality + sampleCount
298 hash |= ( hasFrustumClipping ? 1L : 0L ) << 7;
299 hash |= ( hasColorChannel ? 1L : 0L ) << 8;
300 hash |= ( hasColorTexture ? 1L : 0L ) << 9;
301 hash |= ( colorTexSeqHash & 0xFFFFFFL ) << 32;
302 return hash;
303 }
304 private static int getShaderKey1(final boolean isTwoPass, final boolean pass1,
305 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
306 final ShaderModeSelector1 sms, final int colorTexSeqHash) {
307 // 31 * x == (x << 5) - x
308 int hash = 31 * ( isTwoPass ? 1 : 0 );
309 hash = ((hash << 5) - hash) + ( pass1 ? 1 : 0 ) ;
310 // hash = ((hash << 5) - hash) + pass2Quality; // included in sms
311 // hash = ((hash << 5) - hash) + sampleCount; // included in sms
312 hash = ((hash << 5) - hash) + sms.ordinal();
313 hash = ((hash << 5) - hash) + ( hasFrustumClipping ? 1 : 0 );
314 hash = ((hash << 5) - hash) + ( hasColorChannel ? 1 : 0 );
315 hash = ((hash << 5) - hash) + ( hasColorTexture ? 1 : 0 );
316 hash = ((hash << 5) - hash) + colorTexSeqHash;
317 return hash;
318 }
319
320 static ShaderProgramRef createShaderProgram(GL& gl, const RenderState& rs, RenderMode renderMode, bool pass1, const jau::fraction_timespec& when) {
321 // jau::fraction_timespec when = jau::getMonotonicTime();
322
323 std::string vertexShaderName, fragmentShaderName;
324 vertexShaderName.append(shader_basename);
325 if( isTwoPass(renderMode) ) {
326 vertexShaderName.append("-pass").append(pass1 ? "1":"2");
327 } else {
328 vertexShaderName.append("-single");
329 }
330 fragmentShaderName.append(shader_basename).append("-segment-head");
331
332 ShaderCodeRef rsVp = ShaderCode::create(gl, GL_VERTEX_SHADER, source_dir, bin_dir, vertexShaderName);
333 ShaderCodeRef rsFp = ShaderCode::create(gl, GL_FRAGMENT_SHADER, source_dir, bin_dir, fragmentShaderName);
334 if( !rsVp || !rsFp ) {
335 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
336 return nullptr;
337 }
338 {
339 size_t posVp = rsVp->defaultShaderCustomization(gl, true, true);
340 size_t posFp = rsFp->defaultShaderCustomization(gl, true, true);
341 if( posVp == std::string::npos || posFp == std::string::npos ) {
342 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
343 return nullptr;
344 }
345
346 // GLSL append from here on
347 posFp = -1;
348
349 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_START);
350 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_START);
351
352 // if( !gl.getContext().hasRendererQuirk(GLRendererQuirks.GLSLBuggyDiscard) ) {
353 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_DISCARD);
354 // }
355
356 if( rs.usesFrustumClipping() ) {
357 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_FRUSTUM_CLIPPING);
358 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_FRUSTUM_CLIPPING);
359 }
360
361 if( hasNormalChannel(renderMode) ) {
362 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_NORMAL_CHANNEL);
363 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_NORMAL_CHANNEL);
364 }
365 if( hasLight0(renderMode) ) {
366 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_LIGHT0);
367 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_LIGHT0);
368 }
369 if( hasColorChannel(renderMode) ) {
370 posVp = rsVp->insertShaderSource(0, posVp, GLSL_USE_COLOR_CHANNEL);
371 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_CHANNEL);
372 }
373 if( hasColorTexture(renderMode) ) {
374 rsVp->insertShaderSource(0, posVp, GLSL_USE_COLOR_TEXTURE);
375 posFp = rsFp->insertShaderSource(0, posFp, GLSL_USE_COLOR_TEXTURE);
376 }
377 /*if( !pass1 ) {
378 posFp = rsFp->insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+sms.sampleCount+"\n");
379 posFp = rsFp->insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+sms.sampleCount+".0;\n");
380 } */
381
382 posVp = rsVp->insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_END);
383 if( posVp == std::string::npos ) {
384 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
385 return nullptr;
386 }
387
388 posFp = rsFp->insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_END);
389
390 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/constants.glsl"));
391 if( posFp == std::string::npos ) {
392 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
393 return nullptr;
394 }
395 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/uniforms.glsl"));
396 if( posFp == std::string::npos ) {
397 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
398 return nullptr;
399 }
400 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/varyings.glsl"));
401 if( posFp == std::string::npos ) {
402 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
403 return nullptr;
404 }
405 if( hasColorTexture(renderMode) || rs.usesFrustumClipping() ) {
406 posFp = rsFp->insertShaderSourceFile(0, posFp, string_t(source_dir).append("/functions.glsl"));
407 if( posFp == std::string::npos ) {
408 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
409 return nullptr;
410 }
411 }
412 /*if( hasColorTexture ) {
413 posFp = rsFp->insertShaderSource(0, posFp, "uniform "+colorTexSeq.getTextureSampler2DType()+" "+UniformNames.gcu_ColorTexUnit+";\n");
414 posFp = rsFp->insertShaderSource(0, posFp, colorTexSeq.getTextureLookupFragmentShaderImpl());
415 }*/
416
417 posFp = rsFp->insertShaderSource(0, posFp, GLSL_MAIN_BEGIN);
418
419 std::string passS = pass1 ? "-pass1-" : "-pass2-";
420 std::string shaderSegment = string_t(source_dir).append("/").append(shader_basename).append(passS).append("curve_simple").append(".glsl"); // sms.tech+sms.sub+".glsl";
421 if(DEBUG_MODE) {
422 jau::PLAIN_PRINT(true, "RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
423 }
424 posFp = rsFp->insertShaderSourceFile(0, posFp, shaderSegment);
425 if( posFp == std::string::npos ) {
426 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
427 return nullptr;
428 }
429 posFp = rsFp->insertShaderSource(0, posFp, "}\n");
430 if( posFp == std::string::npos ) {
431 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
432 return nullptr;
433 }
434 if( hasColorTexture(renderMode) ) {
435 rsFp->replaceInShaderSource(std::string(gcuTexture2D), std::string(colTexLookupFuncName));
436 }
437 }
439 if( !sp0->add(gl, rsVp, true) || !sp0->add(gl, rsFp, true) ) {
440 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
441 sp0->destroy(gl);
442 return nullptr;
443 }
444 sp0->useProgram(gl, true);
445
446 m_initialized = sp0->inUse();
447 if( !m_initialized ) {
448 jau::fprintf_td(when.to_ms(), stdout, "ERROR %s:%d\n", E_FILE_LINE);
449 }
450 return sp0;
451 }
452
453 private:
454 RenderState m_rs;
455 jau::math::Recti m_viewport;
456 bool m_initialized;
457 };
458
459 /**@}*/
460
461} // namespace gamp::graph::gl
462
463#endif // JAU_GAMP_GRAPH_GL_RENDERER_HPP_
464
#define E_FILE_LINE
String getTextureFragmentShaderHashID()
constexpr bool initialized() const noexcept
static constexpr std::string_view GLSL_CONST_SAMPLE_COUNT
static constexpr std::string_view gcuTexture2D
static constexpr std::string_view shader_basename
static constexpr std::string_view GLSL_MAIN_BEGIN
RenderState & renderState() noexcept
static constexpr std::string_view colTexLookupFuncName
static constexpr bool DEBUG_MODE
static constexpr std::string_view GLSL_USE_COLOR_CHANNEL
static constexpr std::string_view GLSL_USE_NORMAL_CHANNEL
static GLCallback defaultBlendEnable
Default GL#GL_BLEND enable GLCallback, turning-off depth writing via GL#glDepthMask(bool) if RenderSt...
jau::function< bool(GL &gl, GraphRenderer &renderer)> GLCallback
May be passed to <?
static constexpr std::string_view GLSL_USE_DISCARD
static constexpr std::string_view GLSL_USE_LIGHT0
static constexpr std::string_view GLSL_USE_COLOR_TEXTURE
const Recti & viewport() const noexcept
const RenderState & renderState() const noexcept
static constexpr std::string_view GLSL_PARAM_COMMENT_START
static GLCallback defaultBlendDisable
Default GL#GL_BLEND disable GLCallback, simply turning-off the GL#GL_BLEND state and turning-on depth...
static constexpr std::string_view GLSL_DEF_SAMPLE_COUNT
static constexpr std::string_view GLSL_PARAM_COMMENT_END
GraphRenderer(jau::math::util::PMVMat4f &pmvMat)
static constexpr std::string_view GLSL_USE_FRUSTUM_CLIPPING
static constexpr std::string_view bin_dir
static constexpr std::string_view source_dir
The RenderState is owned by GraphRenderer.
static constexpr bool requiresGL3DefaultPrecision(const GL &gl) noexcept
Returns true, if GL3 GLSL version requires default precision, i.e.
static constexpr std::string_view gl3_default_precision_fp
Default precision of GLSL ≥ 1.30 as required until < 1.50 for fragment-shader: {@value gl3_default_pr...
static ShaderCodeRef create(GLenum type, size_t count, const source_list_t &sources) noexcept
static ShaderProgramRef create() noexcept
Class template jau::function is a general-purpose static-polymorphic function wrapper.
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
constexpr bool hasLight0(RenderMode m) noexcept
constexpr bool hasNormalChannel(RenderMode m) noexcept
RenderMode
Render mode bits being part of the shader-selection-key.
constexpr bool isTwoPass(RenderMode renderMode) noexcept
Returns true if given renderModes has any of RenderMode::aa_mask set.
constexpr bool hasColorChannel(RenderMode m) noexcept
constexpr bool isVBAA(RenderMode renderMode) noexcept
Returns true if given renderModes has RenderMode::vbaa set.
constexpr bool hasVariableWeight(RenderMode renderMode) noexcept
constexpr bool hasColorTexture(RenderMode renderMode) noexcept
Returns true if render mode has a color texture, i.e.
RectI< int > Recti
Definition recti.hpp:146
PMVMatrix4< float > PMVMat4f
Definition pmvmat4.hpp:1463
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
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
Definition debug.cpp:276
constexpr uint64_t to_ms() const noexcept
Returns time in milliseconds.