JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
RegionRenderer.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.graph.curve.opengl;
29
30import java.io.IOException;
31import java.util.HashMap;
32import java.util.Iterator;
33import java.util.Locale;
34
35import com.jogamp.opengl.GL;
36import com.jogamp.opengl.GL2ES2;
37import com.jogamp.opengl.GLES2;
38import com.jogamp.opengl.GLException;
39
40import jogamp.graph.curve.opengl.shader.AttributeNames;
41import jogamp.graph.curve.opengl.shader.UniformNames;
42
43import com.jogamp.opengl.GLExtensions;
44import com.jogamp.opengl.GLRendererQuirks;
45import com.jogamp.opengl.util.glsl.ShaderCode;
46import com.jogamp.opengl.util.glsl.ShaderProgram;
47import com.jogamp.opengl.util.texture.TextureSequence;
48import com.jogamp.common.os.Platform;
49import com.jogamp.common.util.LongObjectHashMap;
50import com.jogamp.graph.curve.Region;
51import com.jogamp.math.Recti;
52import com.jogamp.math.Vec4f;
53import com.jogamp.math.geom.Frustum;
54import com.jogamp.math.util.PMVMatrix4f;
55
56/**
57 * OpenGL {@link Region} renderer
58 *
59 * All {@link Region} rendering operations utilize a RegionRenderer.
60 *
61 * The RegionRenderer owns its {@link RenderState}, a composition.
62 *
63 * The RegionRenderer manages and own all used {@link ShaderProgram}s, a composition.
64 *
65 * At its {@link #destroy(GL2ES2) destruction}, all {@link ShaderProgram}s and its {@link RenderState}
66 * will be destroyed and released.
67 */
68public final class RegionRenderer {
69 protected static final boolean DEBUG = Region.DEBUG;
70 protected static final boolean DEBUG_ALL_EVENT = Region.DEBUG_ALL_EVENT;
71 protected static final boolean DEBUG_INSTANCE = Region.DEBUG_INSTANCE;
72 private static final boolean DEBUG_SHADER_MAP = DEBUG;
73
74 /**
75 * May be passed to
76 * {@link RegionRenderer#create(Vertex.Factory<? extends Vertex>, RenderState, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) RegionRenderer ctor},
77 * e.g.
78 * <ul>
79 * <li>{@link RegionRenderer#defaultBlendEnable}</li>
80 * <li>{@link RegionRenderer#defaultBlendDisable}</li>
81 * </ul>
82 */
83 public interface GLCallback {
84 /**
85 * @param gl a current GL object
86 * @param renderer {@link RegionRenderer} calling this method.
87 */
88 void run(GL gl, RegionRenderer renderer);
89 }
90
91 /**
92 * Default {@link GL#GL_BLEND} <i>enable</i> {@link GLCallback},
93 * turning-off depth writing via {@link GL#glDepthMask(boolean)} if {@link RenderState#BITHINT_GLOBAL_DEPTH_TEST_ENABLED} is set
94 * and turning-on the {@link GL#GL_BLEND} state.
95 * <p>
96 * Implementation also sets {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint},
97 * which will cause {@link GLRegion#draw(GL2ES2, RegionRenderer) GLRegion's draw-method}
98 * to set the proper {@link GL#glBlendFuncSeparate(int, int, int, int) blend-function}
99 * and the clear-color to <i>transparent-black</i> in case of {@link Region#isTwoPass(int) multipass} FBO rendering.
100 * </p>
101 * @see #create(GLCallback, GLCallback)
102 * @see #enable(GL2ES2, boolean)
103 */
104 public static final GLCallback defaultBlendEnable = new GLCallback() {
105 @Override
106 public void run(final GL gl, final RegionRenderer renderer) {
108 gl.glDepthMask(false);
109 // gl.glDisable(GL.GL_DEPTH_TEST);
110 // gl.glDepthFunc(GL.GL_ALWAYS);
111 }
112 gl.glEnable(GL.GL_BLEND);
113 gl.glBlendEquation(GL.GL_FUNC_ADD); // default
115 }
116 };
117
118 /**
119 * Default {@link GL#GL_BLEND} <i>disable</i> {@link GLCallback},
120 * simply turning-off the {@link GL#GL_BLEND} state
121 * and turning-on depth writing via {@link GL#glDepthMask(boolean)} if {@link RenderState#BITHINT_GLOBAL_DEPTH_TEST_ENABLED} is set.
122 * <p>
123 * Implementation also clears {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}.
124 * </p>
125 * @see #create(GLCallback, GLCallback)
126 * @see #enable(GL2ES2, boolean)
127 */
128 public static final GLCallback defaultBlendDisable = new GLCallback() {
129 @Override
130 public void run(final GL gl, final RegionRenderer renderer) {
134 // gl.glEnable(GL.GL_DEPTH_TEST);
135 // gl.glDepthFunc(GL.GL_LESS);
136 gl.glDepthMask(true);
137 }
138 }
139 };
140
141 /**
142 * Create a hardware accelerated RegionRenderer including its {@link RenderState} composition.
143 * <p>
144 * The optional {@link GLCallback}s <code>enableCallback</code> and <code>disableCallback</code>
145 * maybe used to issue certain tasks at {@link #enable(GL2ES2, boolean)}.<br/>
146 * For example, instances {@link #defaultBlendEnable} and {@link #defaultBlendDisable}
147 * can be utilized to enable and disable {@link GL#GL_BLEND}.
148 * </p>
149 * @return an instance of Region Renderer
150 * @see #enable(GL2ES2, boolean)
151 */
152 public static RegionRenderer create() {
153 return new RegionRenderer(null, null, null);
154 }
155
156 /**
157 * Create a hardware accelerated RegionRenderer including its {@link RenderState} composition.
158 * <p>
159 * The optional {@link GLCallback}s <code>enableCallback</code> and <code>disableCallback</code>
160 * maybe used to issue certain tasks at {@link #enable(GL2ES2, boolean)}.<br/>
161 * For example, instances {@link #defaultBlendEnable} and {@link #defaultBlendDisable}
162 * can be utilized to enable and disable {@link GL#GL_BLEND}.
163 * </p>
164 * @param enableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at
165 * {@link #init(GL2ES2) init(gl)} and {@link #enable(GL2ES2, boolean) enable(gl, true)}.
166 * @param disableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at
167 * {@link #enable(GL2ES2, boolean) enable(gl, false)}.
168 * @return an instance of Region Renderer
169 * @see #enable(GL2ES2, boolean)
170 */
171 public static RegionRenderer create(final GLCallback enableCallback, final GLCallback disableCallback) {
172 return new RegionRenderer(enableCallback, disableCallback);
173 }
174
175 /**
176 * Create a hardware accelerated RegionRenderer including its {@link RenderState} composition.
177 * <p>
178 * The optional {@link GLCallback}s <code>enableCallback</code> and <code>disableCallback</code>
179 * maybe used to issue certain tasks at {@link #enable(GL2ES2, boolean)}.<br/>
180 * For example, instances {@link #defaultBlendEnable} and {@link #defaultBlendDisable}
181 * can be utilized to enable and disable {@link GL#GL_BLEND}.
182 * </p>
183 * @param sharedPMVMatrix optional shared {@link PMVMatrix4f} to be used for the {@link RenderState} composition.
184 * @param enableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at
185 * {@link #init(GL2ES2) init(gl)} and {@link #enable(GL2ES2, boolean) enable(gl, true)}.
186 * @param disableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at
187 * {@link #enable(GL2ES2, boolean) enable(gl, false)}.
188 * @return an instance of Region Renderer
189 * @see #enable(GL2ES2, boolean)
190 */
191 public static RegionRenderer create(final PMVMatrix4f sharedPMVMatrix,
192 final GLCallback enableCallback, final GLCallback disableCallback) {
193 return new RegionRenderer(sharedPMVMatrix, enableCallback, disableCallback);
194 }
195
196 private final RenderState rs;
197
198 private final GLCallback enableCallback;
199 private final GLCallback disableCallback;
200
201 private final Recti viewport = new Recti();
202 private boolean initialized;
203 private boolean vboSupported = false;
204
205 public final boolean isInitialized() { return initialized; }
206
207 /** Copies the current Rect4i viewport in given target and returns it for chaining. */
208 public final Recti getViewport(final Recti target) {
209 target.set(viewport);
210 return target;
211 }
212 /** Borrows the current Rect4i viewport w/o copying. */
213 public final Recti getViewport() {
214 return viewport;
215 }
216 /** Return width of current viewport */
217 public final int getWidth() { return viewport.width(); }
218 /** Return height of current viewport */
219 public final int getHeight() { return viewport.height(); }
220
221 //////////////////////////////////////
222
223 protected RegionRenderer(final GLCallback enableCallback, final GLCallback disableCallback) {
224 this(null, enableCallback, disableCallback);
225 }
226
227 protected RegionRenderer(final PMVMatrix4f sharedPMVMatrix,
228 final GLCallback enableCallback, final GLCallback disableCallback)
229 {
230 this.rs = new RenderState(sharedPMVMatrix);
231 this.enableCallback = enableCallback;
232 this.disableCallback = disableCallback;
233 if( UseShaderPrograms0 ) {
234 shaderPrograms0 = new LongObjectHashMap();
235 shaderPrograms1 = null;
236 } else {
237 shaderPrograms0 = null;
238 shaderPrograms1 = new HashMap<ShaderKey, ShaderProgram>();
239 }
240 }
241
242 public final boolean isVBOSupported() { return vboSupported; }
243
244 /**
245 * Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext
246 * if not initialized yet.
247 * <p>Disables the renderer via {@link #enable(GL2ES2, boolean)} to remove any side-effects, ie ShaderState incl. shader program.</p>
248 * <p>Shall be called once before at initialization before a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region)}</p>
249 *
250 * @param gl referencing the current GLContext to which the ShaderState is bound to
251 * @throws GLException if initialization failed
252 */
253 public final void init(final GL2ES2 gl) throws GLException {
254 if(initialized){
255 return;
256 }
257 vboSupported = gl.isFunctionAvailable("glGenBuffers") &&
258 gl.isFunctionAvailable("glBindBuffer") &&
259 gl.isFunctionAvailable("glBufferData") &&
260 gl.isFunctionAvailable("glDrawElements") &&
261 gl.isFunctionAvailable("glVertexAttribPointer") &&
262 gl.isFunctionAvailable("glDeleteBuffers");
263
264 if(DEBUG) {
265 System.err.println("TextRendererImpl01: VBO Supported = " + isVBOSupported());
266 }
267
268 if(!vboSupported){
269 throw new GLException("VBO not supported");
270 }
271
272 rs.attachTo(gl);
273
274 initialized = true;
275 enable(gl, false);
276 }
277
278 /** Deletes all {@link ShaderProgram}s and nullifies its references including {@link RenderState#destroy(GL2ES2)}. */
279 public final void destroy(final GL2ES2 gl) {
280 if(!initialized){
281 if(DEBUG_INSTANCE) {
282 System.err.println("TextRenderer: Not initialized!");
283 }
284 return;
285 }
286 if( UseShaderPrograms0 ) {
287 for(final Iterator<LongObjectHashMap.Entry> i = shaderPrograms0.iterator(); i.hasNext(); ) {
288 final ShaderProgram sp = (ShaderProgram) i.next().getValue();
289 sp.destroy(gl);
290 }
291 shaderPrograms0.clear();
292 } else {
293 for(final Iterator<ShaderProgram> i = shaderPrograms1.values().iterator(); i.hasNext(); ) {
294 final ShaderProgram sp = i.next();
295 sp.destroy(gl);
296 }
297 shaderPrograms1.clear();
298 }
299 rs.detachFrom(gl);
300 rs.destroy();
301 initialized = false;
302 }
303
304 /** Return the {@link RenderState} composition. */
305 public final RenderState getRenderState() { return rs; }
306
307 //
308 // RenderState forwards
309 //
310
311 /** Borrow the current {@link PMVMatrix4f}. */
312 public final PMVMatrix4f getMatrix() { return rs.getMatrix(); }
313
314 public final float getWeight() { return rs.getWeight(); }
315
316 public final void setWeight(final float v) { rs.setWeight(v); }
317
318 public final Vec4f getColorStatic(final Vec4f rgbaColor) { return rs.getColorStatic(rgbaColor); }
319
320 public final void setColorStatic(final Vec4f rgbaColor){ rs.setColorStatic(rgbaColor); }
321
322 public final void setColorStatic(final float r, final float g, final float b, final float a){ rs.setColorStatic(r, g, b, a); }
323
324 /** 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}. */
325 public final int setAAQuality(final int v) { return rs.setAAQuality(v); }
326 /** Returns pass2 AA-quality rendering value for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT}. */
327 public final int getAAQuality() { return rs.getAAQuality(); }
328
329 /** 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}. */
330 public final int setSampleCount(final int v) { return rs.setSampleCount(v); }
331 /** Returns pass2 AA sample count for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link #VBAA_RENDERING_BIT} or {@link Region#MSAA_RENDERING_BIT}. */
332 public final int getSampleCount() { return rs.getSampleCount(); }
333
334 /** Set the optional clipping {@link Frustum}, which shall be pre-multiplied with the Mv-matrix or null to disable. */
335 public final void setClipFrustum(final Frustum clipFrustum) { rs.setClipFrustum(clipFrustum); }
336 /** Returns the optional Mv-premultiplied clipping {@link Frustum} or null if unused. */
337 public final Frustum getClipFrustum() { return rs.getClipFrustum(); }
338
339 public final boolean hintBitsSet(final int mask) { return rs.hintBitsSet(mask); }
340
341 public final void setHintBits(final int mask) { rs.setHintBits(mask); }
342
343 public final void clearHintBits(final int mask) { rs.clearHintBits(mask); }
344
345 /**
346 * Enabling or disabling the {@link #getRenderState() RenderState}'s
347 * current {@link RenderState#getShaderProgram() shader program}.
348 * <p>
349 * {@link #useShaderProgram(GL2ES2, int, boolean, TextureSequence)}
350 * generates, selects and caches the desired Curve-Graph {@link ShaderProgram}
351 * and {@link RenderState#setShaderProgram(GL2ES2, ShaderProgram) sets it current} in the {@link RenderState} composition.
352 * </p>
353 * <p>
354 * In case enable and disable {@link GLCallback}s are setup via {@link #create(Vertex.Factory<? extends Vertex>, RenderState, GLCallback, GLCallback)},
355 * they will be called before toggling the shader program.
356 * </p>
357 * @param gl current GL object
358 * @param enable if true enable the current {@link ShaderProgram}, otherwise disable.
359 * @see #create(Vertex.Factory<? extends Vertex>, RenderState, GLCallback, GLCallback)
360 * @see #useShaderProgram(GL2ES2, int, boolean, TextureSequence)
361 * @see RenderState#setShaderProgram(GL2ES2, ShaderProgram)
362 * @see RenderState#getShaderProgram()
363 */
364 public final void enable(final GL2ES2 gl, final boolean enable) {
365 enable(gl, enable, enableCallback, disableCallback);
366 }
367
368 /**
369 * Same as {@link #enable(GL2ES2, boolean)} but allowing to force {@link GLCallback}s off.
370 * @param gl current GL object
371 * @param enable if true enable the current {@link ShaderProgram}, otherwise disable.
372 * @param enableCB explicit {@link GLCallback} for enable
373 * @param disableCB explicit {@link GLCallback} for disable
374 * @see #enable(GL2ES2, boolean)
375 */
376 public final void enable(final GL2ES2 gl, final boolean enable, final GLCallback enableCB, final GLCallback disableCB) {
377 if( enable ) {
378 if( null != enableCB ) {
379 enableCB.run(gl, this);
380 }
381 } else {
382 if( null != disableCB ) {
383 disableCB.run(gl, this);
384 }
385 final ShaderProgram sp = rs.getShaderProgram();
386 if( null != sp ) {
387 sp.useProgram(gl, false);
388 }
389 }
390 }
391
392 /**
393 * No PMVMatrix4f operation is performed here.
394 */
395 public final void reshapeNotify(final int x, final int y, final int width, final int height) {
396 viewport.set(x, y, width, height);
397 }
398
399 /**
400 * Perspective projection, method also calls {@link #reshapeNotify(int, int, int, int)}.
401 * @param angle_rad perspective angle in radians
402 * @param width viewport width
403 * @param height viewport height
404 * @param near projection z-near
405 * @param far projection z-far
406 */
407 public final void reshapePerspective(final float angle_rad, final int width, final int height, final float near, final float far) {
408 reshapeNotify(0, 0, width, height);
409 final float ratio = (float)width/(float)height;
410 final PMVMatrix4f p = getMatrix();
411 p.loadPIdentity();
412 p.perspectiveP(angle_rad, ratio, near, far);
413 }
414
415 /**
416 * Orthogonal projection, method also calls {@link #reshapeNotify(int, int, int, int)}.
417 * @param width viewport width
418 * @param height viewport height
419 * @param near projection z-near
420 * @param far projection z-far
421 */
422 public final void reshapeOrtho(final int width, final int height, final float near, final float far) {
423 reshapeNotify(0, 0, width, height);
424 final PMVMatrix4f p = getMatrix();
425 p.loadPIdentity();
426 p.orthoP(0, width, 0, height, near, far);
427 }
428
429 //
430 // Shader Management
431 //
432
433 private static final String SHADER_SRC_SUB = "";
434 private static final String SHADER_BIN_SUB = "bin";
435 private static final String GLSL_PARAM_COMMENT_START = "\n// JogAmp Graph Parameter Start\n";
436 private static final String GLSL_PARAM_COMMENT_END = "// JogAmp Graph Parameter End\n\n";
437 private static final String GLSL_USE_COLOR_CHANNEL = "#define USE_COLOR_CHANNEL 1\n";
438 private static final String GLSL_USE_COLOR_TEXTURE = "#define USE_COLOR_TEXTURE 1\n";
439 private static final String GLSL_USE_FRUSTUM_CLIPPING = "#define USE_FRUSTUM_CLIPPING 1\n";
440 private static final String GLSL_DEF_SAMPLE_COUNT = "#define SAMPLE_COUNT ";
441 private static final String GLSL_CONST_SAMPLE_COUNT = "const float sample_count = ";
442 private static final String GLSL_MAIN_BEGIN = "void main (void)\n{\n";
443 private static final String gcuTexture2D = "gcuTexture2D";
444 private static final String GLSL_USE_DISCARD = "#define USE_DISCARD 1\n";
445
446 private String getVersionedShaderName() {
447 return "curverenderer01";
448 }
449
450 // FIXME: Really required to have sampler2D def. precision ? If not, we can drop getFragmentShaderPrecision(..) and use default ShaderCode ..
451 private static final String es2_precision_fp = "\nprecision mediump float;\nprecision mediump int;\nprecision mediump sampler2D;\n";
452
453 private final String getFragmentShaderPrecision(final GL2ES2 gl) {
454 if( gl.isGLES() ) {
455 return es2_precision_fp;
456 }
457 if( ShaderCode.requiresGL3DefaultPrecision(gl) ) {
458 return ShaderCode.gl3_default_precision_fp;
459 }
460 return null;
461 }
462
463 private static enum ShaderModeSelector1 {
464 /** Pass-1: Curve Simple */
465 PASS1_SIMPLE("curve", "_simple", 0),
466 /** Pass-1: Curve Varying Weight */
467 PASS1_WEIGHT("curve", "_weight", 0),
468 /** Pass-2: MSAA */
469 PASS2_MSAA("msaa", "", 0),
470 /** Pass-2: VBAA Flipquad3, 1 sample */
471 PASS2_VBAA_QUAL0_SAMPLES1("vbaa", "_flipquad3", 1),
472 /** Pass-2: VBAA Flipquad3, 2 samples */
473 PASS2_VBAA_QUAL0_SAMPLES2("vbaa", "_flipquad3", 2),
474 /** Pass-2: VBAA Flipquad3, 4 samples */
475 PASS2_VBAA_QUAL0_SAMPLES4("vbaa", "_flipquad3", 4),
476 /** Pass-2: VBAA Flipquad3, 8 samples */
477 PASS2_VBAA_QUAL0_SAMPLES8("vbaa", "_flipquad3", 8),
478
479 /** Pass-2: VBAA Brute-Force, Odd, 1 samples */
480 PASS2_VBAA_QUAL1_SAMPLES1("vbaa", "_bforce_odd", 1),
481 /** Pass-2: VBAA Brute-Force, Even, 2 samples */
482 PASS2_VBAA_QUAL1_SAMPLES2("vbaa", "_bforce_even", 2),
483 /** Pass-2: VBAA Brute-Force, Odd, 3 samples */
484 PASS2_VBAA_QUAL1_SAMPLES3("vbaa", "_bforce_odd", 3),
485 /** Pass-2: VBAA Brute-Force, Even, 4 samples */
486 PASS2_VBAA_QUAL1_SAMPLES4("vbaa", "_bforce_even", 4),
487 /** Pass-2: VBAA Brute-Force, Odd, 5 samples */
488 PASS2_VBAA_QUAL1_SAMPLES5("vbaa", "_bforce_odd", 5),
489 /** Pass-2: VBAA Brute-Force, Even, 6 samples */
490 PASS2_VBAA_QUAL1_SAMPLES6("vbaa", "_bforce_even", 6),
491 /** Pass-2: VBAA Brute-Force, Odd, 7 samples */
492 PASS2_VBAA_QUAL1_SAMPLES7("vbaa", "_bforce_odd", 7),
493 /** Pass-2: VBAA Brute-Force, Even, 8 samples */
494 PASS2_VBAA_QUAL1_SAMPLES8("vbaa", "_bforce_even", 8);
495
496 public final String tech;
497 public final String sub;
498 public final int sampleCount;
499
500 ShaderModeSelector1(final String tech, final String sub, final int sampleCount) {
501 this.tech = tech;
502 this.sub= sub;
503 this.sampleCount = sampleCount;
504 }
505
506 public static ShaderModeSelector1 selectPass1(final int renderModes) {
507 return Region.hasVariableWeight(renderModes) ? PASS1_WEIGHT : PASS1_SIMPLE;
508 }
509
510 public static ShaderModeSelector1 selectPass2(final int renderModes, final int quality, final int sampleCount) {
511 if( Region.isVBAA(renderModes) ) {
512 if( 0 == quality ) {
513 if( sampleCount < 2 ) {
514 return PASS2_VBAA_QUAL0_SAMPLES1;
515 } else if( sampleCount < 4 ) {
516 return PASS2_VBAA_QUAL0_SAMPLES2;
517 } else if( sampleCount < 8 ) {
518 return PASS2_VBAA_QUAL0_SAMPLES4;
519 } else {
520 return PASS2_VBAA_QUAL0_SAMPLES8;
521 }
522 } else {
523 switch( sampleCount ) {
524 case 0: // Fall through intended
525 case 1: return PASS2_VBAA_QUAL1_SAMPLES1;
526 case 2: return PASS2_VBAA_QUAL1_SAMPLES2;
527 case 3: return PASS2_VBAA_QUAL1_SAMPLES3;
528 case 4: return PASS2_VBAA_QUAL1_SAMPLES4;
529 case 5: return PASS2_VBAA_QUAL1_SAMPLES5;
530 case 6: return PASS2_VBAA_QUAL1_SAMPLES6;
531 case 7: return PASS2_VBAA_QUAL1_SAMPLES7;
532 default: return PASS2_VBAA_QUAL1_SAMPLES8;
533 }
534 }
535 } else {
536 return PASS2_MSAA; // Region.isMSAA(renderModes) and default
537 }
538 }
539 }
540
541 private static class ShaderKey {
542 final boolean isTwoPass;
543 final boolean pass1;
544 final ShaderModeSelector1 sms;
545 final boolean hasFrustumClipping; // pass1 or pass2
546 final boolean hasColorChannel; // pass1 only
547 final boolean hasColorTexture; // pass1 only
548 final String colorTexSeqID;
549
550 final int hashValue;
551
552 ShaderKey(final boolean isTwoPass, final boolean pass1, final ShaderModeSelector1 sms,
553 final boolean hasFrustumClipping, final boolean hasColorChannel,
554 final boolean hasColorTexture, final TextureSequence colorTexSeq, final int colorTexSeqHash)
555 {
556 this.isTwoPass = isTwoPass;
557 this.pass1 = pass1;
558 this.sms = sms;
559 this.hasFrustumClipping = hasFrustumClipping;
560 this.hasColorChannel = hasColorChannel;
561 this.hasColorTexture = hasColorTexture;
562 if( hasColorTexture ) {
563 this.colorTexSeqID = colorTexSeq.getTextureFragmentShaderHashID();
564 } else {
565 this.colorTexSeqID = "";
566 }
567 hashValue = getShaderKey1(isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms, colorTexSeqHash);
568 }
569 @Override
570 public final int hashCode() { return hashValue; }
571 @Override
572 public final boolean equals(final Object other) {
573 if( this == other ) { return true; }
574 if( !(other instanceof ShaderKey) ) {
575 return false;
576 }
577 final ShaderKey o = (ShaderKey)other;
578 return isTwoPass == o.isTwoPass &&
579 pass1 == o.pass1 &&
580 // pass2Quality == o.pass2Quality && // included in sms
581 // sampleCount == o.sampleCount && // included in sms
582 sms.ordinal() == o.sms.ordinal() &&
583 hasFrustumClipping == o.hasFrustumClipping &&
584 hasColorChannel == o.hasColorChannel &&
585 hasColorTexture == o.hasColorTexture &&
586 colorTexSeqID.equals(o.colorTexSeqID);
587 }
588 @Override
589 public String toString() {
590 return shaderHashToString(hashValue, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms);
591 }
592 }
593 private static final boolean UseShaderPrograms0 = true;
594 private final LongObjectHashMap shaderPrograms0;
595 private final HashMap<ShaderKey, ShaderProgram> shaderPrograms1;
596
597 private static String shaderHashToString(final int hashCode, final boolean isTwoPass, final boolean pass1,
598 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
599 final ShaderModeSelector1 sms) {
600 return "ShaderHash[hash 0x"+Integer.toHexString(hashCode)+", is2Pass "+isTwoPass+", pass1 "+pass1+
601 ", has[clip "+hasFrustumClipping+", colChan "+hasColorChannel+", colTex "+hasColorTexture+"], "+sms+"]";
602 }
603 private static String shaderKeyToString(final long key, final boolean isTwoPass, final boolean pass1,
604 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
605 final ShaderModeSelector1 sms) {
606 return "ShaderKey[key 0x"+Long.toHexString(key)+", is2Pass "+isTwoPass+", pass1 "+pass1+
607 ", has[clip "+hasFrustumClipping+", colChan "+hasColorChannel+", colTex "+hasColorTexture+"], "+sms+"]";
608 }
609
610 private static long getShaderKey0(final boolean isTwoPass, final boolean pass1,
611 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
612 final ShaderModeSelector1 sms, final long colorTexSeqHash) {
613 // # | s |
614 // 0 | 1 | isTwoPass
615 // 1 | 1 | pass1
616 // 2 | 5 | ShaderModeSelector1
617 // 7 | 1 | hasFrustumClipping
618 // 8 | 1 | hasColorChannel
619 // 9 | 1 | hasColorTexture
620 // 32 | 32 | colorTexSeqHash
621 long hash = isTwoPass ? 1L : 0L;
622 hash |= ( pass1 ? 1L : 0L ) << 1;
623 hash |= (long)( sms.ordinal() & 0b11111 ) << 2; // incl. pass2Quality + sampleCount
624 hash |= ( hasFrustumClipping ? 1L : 0L ) << 7;
625 hash |= ( hasColorChannel ? 1L : 0L ) << 8;
626 hash |= ( hasColorTexture ? 1L : 0L ) << 9;
627 hash |= ( colorTexSeqHash & 0xFFFFFFL ) << 32;
628 return hash;
629 }
630 private static int getShaderKey1(final boolean isTwoPass, final boolean pass1,
631 final boolean hasFrustumClipping, final boolean hasColorChannel, final boolean hasColorTexture,
632 final ShaderModeSelector1 sms, final int colorTexSeqHash) {
633 // 31 * x == (x << 5) - x
634 int hash = 31 * ( isTwoPass ? 1 : 0 );
635 hash = ((hash << 5) - hash) + ( pass1 ? 1 : 0 ) ;
636 // hash = ((hash << 5) - hash) + pass2Quality; // included in sms
637 // hash = ((hash << 5) - hash) + sampleCount; // included in sms
638 hash = ((hash << 5) - hash) + sms.ordinal();
639 hash = ((hash << 5) - hash) + ( hasFrustumClipping ? 1 : 0 );
640 hash = ((hash << 5) - hash) + ( hasColorChannel ? 1 : 0 );
641 hash = ((hash << 5) - hash) + ( hasColorTexture ? 1 : 0 );
642 hash = ((hash << 5) - hash) + colorTexSeqHash;
643 return hash;
644 }
645
646 /**
647 * Generate, selects and caches the desired Curve-Graph {@link ShaderProgram} according to the given parameters.
648 *
649 * The newly generated or cached {@link ShaderProgram} is {@link RenderState#setShaderProgram(GL2ES2, ShaderProgram) set current} in the {@link RenderState} composition
650 * and can be retrieved via {@link RenderState#getShaderProgram()}.
651 *
652 * @param gl
653 * @param renderModes
654 * @param pass1
655 * @param colorTexSeq
656 * @return true if a new shader program is being used and hence external uniform-data and -location,
657 * as well as the attribute-location must be updated, otherwise false.
658 * @see #enable(GL2ES2, boolean)
659 * @see RenderState#setShaderProgram(GL2ES2, ShaderProgram)
660 * @see RenderState#getShaderProgram()
661 */
662 public final boolean useShaderProgram(final GL2ES2 gl, final int renderModes, final boolean pass1, final TextureSequence colorTexSeq) {
663 final boolean isTwoPass = Region.isTwoPass( renderModes );
664 final ShaderModeSelector1 sms = pass1 ? ShaderModeSelector1.selectPass1(renderModes) :
665 ShaderModeSelector1.selectPass2(renderModes, getAAQuality(), getSampleCount());
666 final boolean hasFrustumClipping = ( null != getClipFrustum() ) && ( ( !isTwoPass && pass1 ) || ( isTwoPass && !pass1 ) );
667 final boolean hasColorChannel = pass1 && Region.hasColorChannel( renderModes );
668 final boolean hasColorTexture = pass1 && Region.hasColorTexture( renderModes ) && null != colorTexSeq;
669 final int colorTexSeqHash;
670 final String colTexLookupFuncName;
671 if( hasColorTexture ) {
672 colTexLookupFuncName = colorTexSeq.setTextureLookupFunctionName(gcuTexture2D);
673 colorTexSeqHash = colorTexSeq.getTextureFragmentShaderHashCode();
674 } else {
675 colTexLookupFuncName = "";
676 colorTexSeqHash = 0;
677 }
678
679 if( UseShaderPrograms0 ) {
680 return useShaderProgram0(gl, renderModes, isTwoPass, pass1, sms, hasFrustumClipping, hasColorChannel,
681 hasColorTexture, colorTexSeq, colTexLookupFuncName, colorTexSeqHash);
682 } else {
683 return useShaderProgram1(gl, renderModes, isTwoPass, pass1, sms, hasFrustumClipping, hasColorChannel,
684 hasColorTexture, colorTexSeq, colTexLookupFuncName, colorTexSeqHash);
685 }
686 }
687 private final boolean useShaderProgram0(final GL2ES2 gl, final int renderModes,
688 final boolean isTwoPass, final boolean pass1, final ShaderModeSelector1 sms,
689 final boolean hasFrustumClipping, final boolean hasColorChannel,
690 final boolean hasColorTexture, final TextureSequence colorTexSeq,
691 final String colTexLookupFuncName, final int colorTexSeqHash)
692 {
693 final long shaderKey = getShaderKey0(isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms, colorTexSeqHash);
694 /**
695 if(DEBUG) {
696 System.err.println("XXX "+Region.getRenderModeString(renderModes, getAAQuality(), getSampleCount(), 0)+", "+
697 shaderKeyToString(shaderHashCode, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms));
698 } */
699
700 ShaderProgram sp = (ShaderProgram) shaderPrograms0.get( shaderKey );
701 if( null != sp ) {
702 final boolean spChanged = rs.setShaderProgram(gl, sp);
703 if( DEBUG_SHADER_MAP ) {
704 if( spChanged ) {
705 System.err.printf("RegionRenderer.useShaderProgram0.X1: GOT renderModes %s, %s -> sp %d / %d (changed)%n",
706 Region.getRenderModeString(renderModes),
707 shaderKeyToString(shaderKey, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms), sp.program(), sp.id());
708 } else if( DEBUG_ALL_EVENT ) {
709 System.err.printf("RegionRenderer.useShaderProgram0.X1: GOT renderModes %s, %s -> sp %d / %d (keep)%n",
710 Region.getRenderModeString(renderModes),
711 shaderKeyToString(shaderKey, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms), sp.program(), sp.id());
712 }
713 }
714 return spChanged;
715 }
716 sp = createShaderProgram(gl, renderModes, isTwoPass, pass1, sms, hasFrustumClipping, hasColorChannel,
717 hasColorTexture, colorTexSeq, colTexLookupFuncName, colorTexSeqHash);
718 rs.setShaderProgram(gl, sp);
719
720 if( DEBUG_SHADER_MAP ) {
721 System.err.printf("RegionRenderer.useShaderProgram0.X2: NEW renderModes %s, %s -> sp %d / %d (new)%n",
722 Region.getRenderModeString(renderModes),
723 shaderKeyToString(shaderKey, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms), sp.program(), sp.id());
724 // sp.dumpSource(System.err);
725 }
726 final ShaderProgram spOld = (ShaderProgram) shaderPrograms0.put(shaderKey, sp);
727 if( null != spOld ) {
728 // COLLISION!
729 final String msg = String.format((Locale)null,
730 "RegionRenderer.useShaderProgram0: WARNING Shader-HashCode Collision: hash 0x%s: %s, %s -> sp %d / %d (new)%n",
731 Long.toHexString(shaderKey), Region.getRenderModeString(renderModes),
732 shaderKeyToString(shaderKey, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms), sp.program(), sp.id());
733 throw new RuntimeException(msg);
734 }
735 return true;
736 }
737 private final boolean useShaderProgram1(final GL2ES2 gl, final int renderModes,
738 final boolean isTwoPass, final boolean pass1, final ShaderModeSelector1 sms,
739 final boolean hasFrustumClipping, final boolean hasColorChannel,
740 final boolean hasColorTexture, final TextureSequence colorTexSeq,
741 final String colTexLookupFuncName, final int colorTexSeqHash) {
742 final ShaderKey shaderKey = new ShaderKey(isTwoPass, pass1, sms, hasFrustumClipping, hasColorChannel,
743 hasColorTexture, colorTexSeq, colorTexSeqHash);
744 /**
745 if(DEBUG) {
746 System.err.println("XXX "+Region.getRenderModeString(renderModes, getAAQuality(), getSampleCount(), 0)+", "+shaderKey);
747 } */
748
749 ShaderProgram sp = shaderPrograms1.get( shaderKey );
750 if( null != sp ) {
751 final boolean spChanged = rs.setShaderProgram(gl, sp);
752 if( DEBUG_SHADER_MAP ) {
753 if( spChanged ) {
754 System.err.printf("RegionRenderer.useShaderProgram1.X1: GOT renderModes %s, %s -> sp %d / %d (changed)%n",
755 Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
756 } else if( DEBUG_ALL_EVENT ) {
757 System.err.printf("RegionRenderer.useShaderProgram1.X1: GOT renderModes %s, %s -> sp %d / %d (keep)%n",
758 Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
759 }
760 }
761 return spChanged;
762 }
763 sp = createShaderProgram(gl, renderModes, isTwoPass, pass1, sms, hasFrustumClipping, hasColorChannel,
764 hasColorTexture, colorTexSeq, colTexLookupFuncName, colorTexSeqHash);
765 rs.setShaderProgram(gl, sp);
766
767 if( DEBUG_SHADER_MAP ) {
768 System.err.printf("RegionRenderer.useShaderProgram1.X2: NEW renderModes %s, %s -> sp %d / %d (new)%n",
769 Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
770 // sp.dumpSource(System.err);
771 }
772
773 shaderPrograms1.put(shaderKey, sp);
774 return true;
775 }
776 @SuppressWarnings("unused")
777 private final ShaderProgram createShaderProgram(final GL2ES2 gl, final int renderModes,
778 final boolean isTwoPass, final boolean pass1, final ShaderModeSelector1 sms,
779 final boolean hasFrustumClipping, final boolean hasColorChannel,
780 final boolean hasColorTexture, final TextureSequence colorTexSeq,
781 final String colTexLookupFuncName, final int colorTexSeqHash)
782 {
783 final String versionedBaseName = getVersionedShaderName();
784 final String vertexShaderName;
785 if( isTwoPass ) {
786 vertexShaderName = versionedBaseName+"-pass"+(pass1?1:2);
787 } else {
788 vertexShaderName = versionedBaseName+"-single";
789 }
790 final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, AttributeNames.class, SHADER_SRC_SUB, SHADER_BIN_SUB, vertexShaderName, true);
791 final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, AttributeNames.class, SHADER_SRC_SUB, SHADER_BIN_SUB, versionedBaseName+"-segment-head", true);
792
793 if( hasColorTexture && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
794 if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
795 throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
796 }
797 }
798 boolean preludeGLSLVersion = true;
799 if( hasColorTexture && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
800 if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
801 // Bug on Nexus 10, ES3 - Android 4.3, where
802 // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
803 // P0003: Extension 'GL_OES_EGL_image_external' not supported
804 preludeGLSLVersion = false;
805 }
806 }
807 //
808 // GLSL customization at top
809 //
810 int posVp = rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
811 // rsFp.defaultShaderCustomization(gl, true, true);
812 int posFp = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
813 if( hasColorTexture ) {
814 posFp = rsFp.insertShaderSource(0, posFp, colorTexSeq.getRequiredExtensionsShaderStub());
815 }
816 if( pass1 && !preludeGLSLVersion || ( gl.isGLES2() && !gl.isGLES3() ) ) {
817 posFp = rsFp.insertShaderSource(0, posFp, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE));
818 }
819 if( false ) {
820 final String rsFpDefPrecision = getFragmentShaderPrecision(gl);
821 if( null != rsFpDefPrecision ) {
822 posFp = rsFp.insertShaderSource(0, posFp, rsFpDefPrecision);
823 }
824 } else {
825 posFp = rsFp.addDefaultShaderPrecision(gl, posFp);
826 }
827
828 //
829 // GLSL append from here on
830 posFp = -1;
831
832 posVp = rsVp.insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_START);
833 posFp = rsFp.insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_START);
834
835 if( !gl.getContext().hasRendererQuirk(GLRendererQuirks.GLSLBuggyDiscard) ) {
836 posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_DISCARD);
837 }
838
839 if( hasFrustumClipping ) {
840 posVp = rsVp.insertShaderSource(0, posVp, GLSL_USE_FRUSTUM_CLIPPING);
841 posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_FRUSTUM_CLIPPING);
842 }
843
844 if( hasColorChannel ) {
845 posVp = rsVp.insertShaderSource(0, posVp, GLSL_USE_COLOR_CHANNEL);
846 posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_COLOR_CHANNEL);
847 }
848 if( hasColorTexture ) {
849 rsVp.insertShaderSource(0, posVp, GLSL_USE_COLOR_TEXTURE);
850 posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_COLOR_TEXTURE);
851 }
852 if( !pass1 ) {
853 posFp = rsFp.insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+sms.sampleCount+"\n");
854 posFp = rsFp.insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+sms.sampleCount+".0;\n");
855 }
856
857 posVp = rsVp.insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_END);
858 posFp = rsFp.insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_END);
859
860 try {
861 posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "uniforms.glsl");
862 posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "varyings.glsl");
863 if( hasColorTexture || hasFrustumClipping ) {
864 posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "functions.glsl");
865 }
866 } catch (final IOException ioe) {
867 throw new RuntimeException("Failed to read: includes", ioe);
868 }
869 if( 0 > posFp ) {
870 throw new RuntimeException("Failed to read: includes");
871 }
872
873 if( hasColorTexture ) {
874 posFp = rsFp.insertShaderSource(0, posFp, "uniform "+colorTexSeq.getTextureSampler2DType()+" "+UniformNames.gcu_ColorTexUnit+";\n");
875 posFp = rsFp.insertShaderSource(0, posFp, colorTexSeq.getTextureLookupFragmentShaderImpl());
876 }
877
878 posFp = rsFp.insertShaderSource(0, posFp, GLSL_MAIN_BEGIN);
879
880 final String passS = pass1 ? "-pass1-" : "-pass2-";
881 final String shaderSegment = versionedBaseName+passS+sms.tech+sms.sub+".glsl";
882 if(DEBUG) {
883 System.err.printf("RegionRenderer.createShaderProgram.1: segment %s%n", shaderSegment);
884 }
885 try {
886 posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, shaderSegment);
887 } catch (final IOException ioe) {
888 throw new RuntimeException("Failed to read: "+shaderSegment, ioe);
889 }
890 if( 0 > posFp ) {
891 throw new RuntimeException("Failed to read: "+shaderSegment);
892 }
893 posFp = rsFp.insertShaderSource(0, posFp, "}\n");
894
895 if( hasColorTexture ) {
896 rsFp.replaceInShaderSource(gcuTexture2D, colTexLookupFuncName);
897 }
898
899 final ShaderProgram sp = new ShaderProgram();
900 sp.add(rsVp);
901 sp.add(rsFp);
902
903 if( !sp.init(gl) ) {
904 throw new GLException("RegionRenderer: Couldn't init program: "+sp);
905 }
906
907 if( !sp.link(gl, System.err) ) {
908 throw new GLException("could not link program: "+sp);
909 }
910 return sp;
911 }
912}
913
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
static boolean isTwoPass(final int renderModes)
Returns true if given renderModes has any of Region#AA_RENDERING_MASK set.
Definition: Region.java:213
static final boolean DEBUG_ALL_EVENT
Definition: Region.java:64
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
static final boolean DEBUG_INSTANCE
Definition: Region.java:65
static boolean hasColorChannel(final int renderModes)
Returns true if render mode has a color channel, i.e.
Definition: Region.java:231
static final boolean DEBUG
Debug flag for [com.
Definition: Region.java:68
static boolean hasColorTexture(final int renderModes)
Returns true if render mode has a color texture, i.e.
Definition: Region.java:240
final void setColorStatic(final float r, final float g, final float b, final float a)
final RenderState getRenderState()
Return the RenderState composition.
static RegionRenderer create(final PMVMatrix4f sharedPMVMatrix, final GLCallback enableCallback, final GLCallback disableCallback)
Create a hardware accelerated RegionRenderer including its RenderState composition.
final void enable(final GL2ES2 gl, final boolean enable)
Enabling or disabling the RenderState's current shader program.
final int getAAQuality()
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
final int getHeight()
Return height of current viewport.
final void reshapeOrtho(final int width, final int height, final float near, final float far)
Orthogonal projection, method also calls reshapeNotify(int, int, int, int).
static RegionRenderer create(final GLCallback enableCallback, final GLCallback disableCallback)
Create a hardware accelerated RegionRenderer including its RenderState composition.
final boolean useShaderProgram(final GL2ES2 gl, final int renderModes, final boolean pass1, final TextureSequence colorTexSeq)
Generate, selects and caches the desired Curve-Graph ShaderProgram according to the given parameters.
final void setColorStatic(final Vec4f rgbaColor)
final PMVMatrix4f getMatrix()
Borrow the current PMVMatrix4f.
RegionRenderer(final PMVMatrix4f sharedPMVMatrix, final GLCallback enableCallback, final GLCallback disableCallback)
final void setClipFrustum(final Frustum clipFrustum)
Set the optional clipping Frustum, which shall be pre-multiplied with the Mv-matrix or null to disabl...
RegionRenderer(final GLCallback enableCallback, final GLCallback disableCallback)
final void reshapeNotify(final int x, final int y, final int width, final int height)
No PMVMatrix4f operation is performed here.
final int getWidth()
Return width of current viewport.
final int setSampleCount(final int v)
Sets pass2 AA sample count clipped to the range [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COU...
static final GLCallback defaultBlendDisable
Default GL#GL_BLEND disable GLCallback, simply turning-off the GL#GL_BLEND state and turning-on depth...
final Vec4f getColorStatic(final Vec4f rgbaColor)
final int setAAQuality(final int v)
Sets pass2 AA-quality rendering value clipped to the range [Region#MIN_AA_QUALITY....
final boolean hintBitsSet(final int mask)
static final GLCallback defaultBlendEnable
Default GL#GL_BLEND enable GLCallback, turning-off depth writing via GL#glDepthMask(boolean) if Rende...
final void init(final GL2ES2 gl)
Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext if no...
final int getSampleCount()
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
static RegionRenderer create()
Create a hardware accelerated RegionRenderer including its RenderState composition.
final void reshapePerspective(final float angle_rad, final int width, final int height, final float near, final float far)
Perspective projection, method also calls reshapeNotify(int, int, int, int).
final Recti getViewport(final Recti target)
Copies the current Rect4i viewport in given target and returns it for chaining.
final Recti getViewport()
Borrows the current Rect4i viewport w/o copying.
final Frustum getClipFrustum()
Returns the optional Mv-premultiplied clipping Frustum or null if unused.
final void enable(final GL2ES2 gl, final boolean enable, final GLCallback enableCB, final GLCallback disableCB)
Same as enable(GL2ES2, boolean) but allowing to force GLCallbacks off.
final void destroy(final GL2ES2 gl)
Deletes all ShaderPrograms and nullifies its references including RenderState#destroy(GL2ES2).
The RenderState is owned by RegionRenderer.
final Frustum getClipFrustum()
Returns the optional Mv-premultiplied clipping Frustum or null if unused.
final boolean hintBitsSet(final int mask)
final Vec4f getColorStatic(final Vec4f rgbaColor)
final RenderState attachTo(final GL2ES2 gl)
static final int BITHINT_BLENDING_ENABLED
Bitfield hint, if set stating enabled GL#GL_BLEND, otherwise disabled.
final void setColorStatic(final Vec4f rgbaColor)
static final int BITHINT_GLOBAL_DEPTH_TEST_ENABLED
Bitfield hint, if set stating globally enabled GL#GL_DEPTH_TEST, otherwise disabled.
final int getSampleCount()
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
final boolean detachFrom(final GL2ES2 gl)
final PMVMatrix4f getMatrix()
Borrow the current PMVMatrix4f.
final void clearHintBits(final int mask)
final int setSampleCount(final int v)
Sets pass2 AA sample count clipped to the range [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COU...
final void setHintBits(final int mask)
final boolean setShaderProgram(final GL2ES2 gl, final ShaderProgram spNext)
Sets the current ShaderProgram and enables it.
final int getAAQuality()
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
final void setClipFrustum(final Frustum clipFrustum)
Set the optional clipping Frustum, which shall be pre-multiplied with the Mv-matrix or null to disabl...
final ShaderProgram getShaderProgram()
Return the current ShaderProgram.
final int setAAQuality(final int v)
Sets pass2 AA-quality rendering value clipped to the range [Region#MIN_AA_QUALITY....
Rectangle with x, y, width and height integer components.
Definition: Recti.java:34
void set(final Recti o)
this = o, returns this.
Definition: Recti.java:59
4D Vector based upon four float components.
Definition: Vec4f.java:37
Providing frustum planes derived by different inputs (P*MV, ..) used to classify objects.
Definition: Frustum.java:81
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final PMVMatrix4f perspectiveP(final float fovy_rad, final float aspect, final float zNear, final float zFar)
Multiply the projection matrix with the perspective/frustum matrix.
final void orthoP(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar)
Multiply the projection matrix with the orthogonal matrix.
final PMVMatrix4f loadPIdentity()
Load the projection matrix with the values of the given Matrix4f.
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
int program()
Returns the shader program name, which is non zero if valid.
synchronized void destroy(final GL2ES2 gl)
Detaches all shader codes and deletes the program.
synchronized void useProgram(final GL2ES2 gl, boolean on)
May be passed to RegionRenderer ctor, e.g.
void run(GL gl, RegionRenderer renderer)
void glBlendEquation(int mode)
Entry point to C language function: void {@native glBlendEquation}(GLenum mode) Part of GL_ES_VERS...
void glDisable(int cap)
Entry point to C language function: void {@native glDisable}(GLenum cap) Part of GL_ES_VERSION_2_0...
void glEnable(int cap)
Entry point to C language function: void {@native glEnable}(GLenum cap) Part of GL_ES_VERSION_2_0,...
static final int GL_BLEND
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_BLEND" with expressio...
Definition: GL.java:704
void glDepthMask(boolean flag)
Entry point to C language function: void {@native glDepthMask}(GLboolean flag) Part of GL_ES_VERSI...
static final int GL_FUNC_ADD
GL_ARB_imaging, GL_ES_VERSION_2_0, GL_VERSION_1_4, GL_EXT_blend_minmax, GL_OES_blend_subtract Alias f...
Definition: GL.java:428
Protocol for texture sequences, like animations, movies, etc.
int getTextureFragmentShaderHashCode()
Returns the hash code of the string getTextureFragmentShaderHashID().
String setTextureLookupFunctionName(String texLookupFuncName)
Set the desired shader code's texture lookup function name.