aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-14 04:19:10 +0100
committerSven Göthel <[email protected]>2024-01-14 04:19:10 +0100
commit6363ae5fb6975a6f2e7c1093ce81f25b699e3e61 (patch)
treee19fb3347ea0562972c87b6b6fbbf771933646ae /src/jogl/classes/com/jogamp
parent3062f72c7b83cef71d8e6d471846449aba66d861 (diff)
Graph/GraphUI: Revise Graph Region ShaderMapping, fix AABBox-Clipping for Pass2-AA, revise Pass2 AA Quality parameter ..
Misc: - Graph VBORegion2PVBAAES2: Drop unused FBO rescale - Move MIN/MAX QUALITY/SAMPLE from GraphUI Scene -> Graph Region +++ Quality -> Pass2 AA Quality - Drop quality field in region - Pass quality to GLRegion.draw(..) similar to sampleCount for dynamic shader and switch - TODO: Pass quality parameter in TextRegionUtil's functions Fix RegionRenderer Shader Mapping - Use ShaderKey class to properly implement the hash value and equals method - For this, TextureSequence.getTextureFragmentShaderHashID() has been added to provide actual shader-snippet for the equals function - All required criterias are included in the hash value and equals method Fix AABBox Clipping for Pass-2 AA - Clipping in pass2-AA must happen in pass2 on actual gcu_PMVMatrix01 (not ortho) +++ GraphUI GraphShape - Rename: [get,set]{->AA}Quality() GraphUI Scene - Rename: mark{All->}ShapesDirty(), set{AllShapes->}Sharpness(), set{AllShapes->AA}Quality() - Fix setSampleCount(..), i.e. markStatesDirty() not markShapesDirty() - Fix setAAQuality(), markShapesDirty() and markStatesDirty(): Use forAll(..) to traverse through all shapes and groups. GraphUI Group - Add setFixedSize() - Add setClipOnBox() - Document setRelayoutOnDirtyShapes(), isShapeDirty()
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/Region.java56
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java14
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java186
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java10
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java21
7 files changed, 208 insertions, 99 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java
index 5b0f0a53b..f70dacbbc 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/Region.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java
@@ -72,6 +72,9 @@ public abstract class Region {
* <p>
* One pass `norm` rendering either using no AA or underlying full-screen AA (fsaa).
* </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
*/
public static final int NORM_RENDERING_BIT = 0;
@@ -79,9 +82,15 @@ public abstract class Region {
* Rendering-Mode bit for {@link #getRenderModes() Region}
* <p>
* MSAA based Anti-Aliasing, a two pass region rendering, slower and more
- * resource hungry (FBO), but providing fast MSAA in case
+ * resource hungry (FBO with sample buffer), but providing fast MSAA in case
* the whole scene is not rendered with MSAA.
* </p>
+ * <p>
+ * In case sample count is 1, no FBO sample buffer is used but a simple bilinear texture filter.
+ * </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
*/
public static final int MSAA_RENDERING_BIT = 1 << 0;
@@ -92,6 +101,16 @@ public abstract class Region {
* resource hungry (FBO), but AA is perfect. Otherwise the default fast one
* pass MSAA region rendering is being used.
* </p>
+ * <p>
+ * In case sample count is 1, no FBO supersampling is performed but a simple bilinear texture filter used.
+ * </p>
+ * <p>
+ * Depending on AA-quality, {@link #MAX_AA_QUALITY} denotes full 4x billinear filtering per sample
+ * and {@code 0} denotes 1x flipquad filtering per sample.
+ * </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
*/
public static final int VBAA_RENDERING_BIT = 1 << 1;
@@ -105,6 +124,9 @@ public abstract class Region {
* Otherwise the default weight 1.0 for uniform curve region rendering is
* being applied.
* </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
*/
public static final int VARWEIGHT_RENDERING_BIT = 1 << 8;
@@ -115,6 +137,9 @@ public abstract class Region {
* otherwise {@link com.jogamp.graph.curve.opengl.RegionRenderer#setColorStatic(com.jogamp.opengl.GL2ES2, float, float, float, float) static color}
* can being used for a monotonic color.
* </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
* @see #getRenderModes()
* @see #hasColorChannel()
* @see #addOutlineShape(OutlineShape, AffineTransform, float[])
@@ -127,6 +152,9 @@ public abstract class Region {
* <p>
* If set, a color texture is used to determine the color.
* </p>
+ * <p>
+ * This mode-bit is a shader-key.
+ * </p>
* @see #COLORTEXTURE_LETTERBOX_RENDERING_BIT
*/
public static final int COLORTEXTURE_RENDERING_BIT = 1 << 10;
@@ -137,13 +165,23 @@ public abstract class Region {
* If set, a used {@link #COLORTEXTURE_RENDERING_BIT} color texture is added letter-box space to match aspect-ratio, otherwise it will be zoomed in.
* </p>
* <p>
+ * This mode-bit is not a shader-key.
+ * </p>
+ * <p>
* Note that {@link #COLORTEXTURE_RENDERING_BIT} must also be set to even enable color texture.
* </p>
*/
public static final int COLORTEXTURE_LETTERBOX_RENDERING_BIT = 1 << 11;
- /** Default maximum {@link #getQuality() quality}, {@value}. */
- public static final int MAX_QUALITY = 1;
+ /** Minimum pass2 AA-quality rendering {@value} (default) for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link #VBAA_RENDERING_BIT}. */
+ public static final int MIN_AA_QUALITY = 0;
+ /** Maximum pass2 AA-quality rendering {@value} (default) for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link #VBAA_RENDERING_BIT}. */
+ public static final int MAX_AA_QUALITY = 1;
+
+ /** Minimum 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}. */
+ public static final int MIN_AA_SAMPLE_COUNT = 1;
+ /** Maximum 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}. */
+ public static final int MAX_AA_SAMPLE_COUNT = 8;
public static final int DEFAULT_TWO_PASS_TEXTURE_UNIT = 0;
@@ -153,7 +191,6 @@ public abstract class Region {
private final int renderModes;
private final boolean use_int32_idx;
private final int max_indices;
- private int quality;
private int dirty = DIRTY_SHAPE | DIRTY_STATE;
private int numVertices = 0;
protected final AABBox box = new AABBox();
@@ -265,7 +302,6 @@ public abstract class Region {
} else {
this.max_indices = GL_UINT16_MAX;
}
- this.quality = MAX_QUALITY;
}
/** Print implementation buffer stats like detailed and total size and capacity in bytes etc */
@@ -316,12 +352,6 @@ public abstract class Region {
*/
public final int getRenderModes() { return renderModes; }
- /** See {@link #MAX_QUALITY} */
- public final int getQuality() { return quality; }
-
- /** See {@link #MAX_QUALITY} */
- public final void setQuality(final int q) { quality=q; }
-
protected final void clearImpl() {
dirty = DIRTY_SHAPE | DIRTY_STATE;
numVertices = 0;
@@ -760,7 +790,7 @@ public abstract class Region {
* Mark this region's shape dirty,
* i.e. its vertices, triangles, lines and/or color-texture coordinates changed.
* <p>
- * The data will be re-uploaded to the GPU at next {@link GLRegion#draw(com.jogamp.opengl.GL2ES2, com.jogamp.graph.curve.opengl.RegionRenderer, int[]) draw(..)}.
+ * The data will be re-uploaded to the GPU at next {@link GLRegion#draw(com.jogamp.opengl.GL2ES2, com.jogamp.graph.curve.opengl.RegionRenderer, int, int[]) draw(..)}.
* </p>
* <p>
* In 2-pass mode, this implies updating the FBO itself as well.
@@ -798,6 +828,6 @@ public abstract class Region {
@Override
public String toString() {
- return "Region[0x"+Integer.toHexString(hashCode())+", "+getRenderModeString(this.renderModes)+", q "+quality+", dirty "+dirty+", vertices "+numVertices+", box "+box+"]";
+ return "Region[0x"+Integer.toHexString(hashCode())+", "+getRenderModeString(this.renderModes)+", dirty "+dirty+", vertices "+numVertices+", box "+box+"]";
}
} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
index af8a54177..5849a8581 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
@@ -511,14 +511,15 @@ public abstract class GLRegion extends Region {
* </p>
* @param gl current {@link GL2ES2}.
* @param renderer the {@link RegionRenderer} to be used
- * @param sampleCount desired multisampling sample count for vbaa- or msaa-rendering.
+ * @param pass2Quality pass2 AA-quality selector in 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}
+ * @param sampleCount desired pass2 AA-multisampling sample count in the typical range [{@link Region#MIN_AA_SAMPLE_COUNT}..{@link Region#MAX_AA_SAMPLE_COUNT}] for Graph Region AA {@link Region#getRenderModes() render-modes}: {@link Region#VBAA_RENDERING_BIT}, {@link Region#MSAA_RENDERING_BIT}
* Use -1 for glSelect mode, pass1 w/o any color texture nor channel, use static select color only.
* The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched.
* @see RegionRenderer#enable(GL2ES2, boolean)
*/
- public final void draw(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) {
+ public final void draw(final GL2ES2 gl, final RegionRenderer renderer, final int pass2Quality, final int[/*1*/] sampleCount) {
final int curRenderModes;
- if( null == sampleCount || 0 == sampleCount[0] ) {
+ if( 0 == sampleCount[0] ) {
// no sampling, reduce to pass1
curRenderModes = getRenderModes() & ~( VBAA_RENDERING_BIT | MSAA_RENDERING_BIT );
} else if( 0 > sampleCount[0] ) {
@@ -528,6 +529,9 @@ public abstract class GLRegion extends Region {
// normal 2-pass sampling
curRenderModes = getRenderModes();
}
+ // System.err.println("XXX.0 "+Region.getRenderModeString(getRenderModes(), sampleCount[0], 0)+": "+
+ // Region.getRenderModeString(lastRenderModes, sampleCount[0], 0)+" -> "+Region.getRenderModeString(curRenderModes, sampleCount[0], 0));
+
if( lastRenderModes != curRenderModes ) {
markShapeDirty();
markStateDirty();
@@ -535,7 +539,7 @@ public abstract class GLRegion extends Region {
if( isShapeDirty() ) {
updateImpl(gl, renderer, curRenderModes);
}
- drawImpl(gl, renderer, curRenderModes, sampleCount);
+ drawImpl(gl, renderer, curRenderModes, pass2Quality, sampleCount);
clearDirtyBits(DIRTY_SHAPE|DIRTY_STATE);
lastRenderModes = curRenderModes;
}
@@ -549,5 +553,5 @@ public abstract class GLRegion extends Region {
*/
protected abstract void updateImpl(final GL2ES2 gl, final RegionRenderer renderer, final int curRenderModes);
- protected abstract void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int curRenderModes, final int[/*1*/] sampleCount);
+ protected abstract void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int curRenderModes, int pass2Quality, final int[/*1*/] sampleCount);
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
index c43dc7913..cf9ac637b 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -28,6 +28,7 @@
package com.jogamp.graph.curve.opengl;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Iterator;
import com.jogamp.opengl.GL;
@@ -44,7 +45,6 @@ import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.graph.curve.Region;
import com.jogamp.math.Recti;
import com.jogamp.math.Vec4f;
@@ -67,6 +67,7 @@ public final class RegionRenderer {
protected static final boolean DEBUG = Region.DEBUG;
protected static final boolean DEBUG_ALL_EVENT = Region.DEBUG_ALL_EVENT;
protected static final boolean DEBUG_INSTANCE = Region.DEBUG_INSTANCE;
+ private static final boolean DEBUG_SHADER_MAP = DEBUG;
/**
* May be passed to
@@ -91,7 +92,7 @@ public final class RegionRenderer {
* and turning-on the {@link GL#GL_BLEND} state.
* <p>
* Implementation also sets {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint},
- * which will cause {@link GLRegion#draw(GL2ES2, RegionRenderer, int[]) GLRegion's draw-method}
+ * which will cause {@link GLRegion#draw(GL2ES2, RegionRenderer, int, int[]) GLRegion's draw-method}
* to set the proper {@link GL#glBlendFuncSeparate(int, int, int, int) blend-function}
* and the clear-color to <i>transparent-black</i> in case of {@link Region#isTwoPass(int) multipass} FBO rendering.
* </p>
@@ -235,7 +236,7 @@ public final class RegionRenderer {
* Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext
* if not initialized yet.
* <p>Disables the renderer via {@link #enable(GL2ES2, boolean)} to remove any side-effects, ie ShaderState incl. shader program.</p>
- * <p>Shall be called once before at initialization before a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region, int)}</p>
+ * <p>Shall be called once before at initialization before a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region, int, int)}</p>
*
* @param gl referencing the current GLContext to which the ShaderState is bound to
* @throws GLException if initialization failed
@@ -273,8 +274,8 @@ public final class RegionRenderer {
}
return;
}
- for(final Iterator<IntObjectHashMap.Entry> i = shaderPrograms.iterator(); i.hasNext(); ) {
- final ShaderProgram sp = (ShaderProgram) i.next().getValue();
+ for(final Iterator<ShaderProgram> i = shaderPrograms.values().iterator(); i.hasNext(); ) {
+ final ShaderProgram sp = i.next();
sp.destroy(gl);
}
shaderPrograms.clear();
@@ -404,6 +405,8 @@ public final class RegionRenderer {
private static final String SHADER_SRC_SUB = "";
private static final String SHADER_BIN_SUB = "bin";
+ private static final String GLSL_PARAM_COMMENT_START = "\n// JogAmp Graph Parameter Start\n";
+ private static final String GLSL_PARAM_COMMENT_END = "// JogAmp Graph Parameter End\n\n";
private static final String GLSL_USE_COLOR_CHANNEL = "#define USE_COLOR_CHANNEL 1\n";
private static final String GLSL_USE_COLOR_TEXTURE = "#define USE_COLOR_TEXTURE 1\n";
private static final String GLSL_USE_AABBOX_CLIPPING = "#define USE_AABBOX_CLIPPING 1\n";
@@ -478,9 +481,7 @@ public final class RegionRenderer {
}
public static ShaderModeSelector1 selectPass2(final int renderModes, final int quality, final int sampleCount) {
- if( Region.isMSAA(renderModes) ) {
- return PASS2_MSAA;
- } else if( Region.isVBAA(renderModes) ) {
+ if( Region.isVBAA(renderModes) ) {
if( 0 == quality ) {
if( sampleCount < 2 ) {
return PASS2_VBAA_QUAL0_SAMPLES1;
@@ -505,14 +506,81 @@ public final class RegionRenderer {
}
}
} else {
- return null;
+ return PASS2_MSAA; // Region.isMSAA(renderModes) and default
}
}
}
- private final IntObjectHashMap shaderPrograms = new IntObjectHashMap();
- private static final int HIGH_MASK = Region.COLORCHANNEL_RENDERING_BIT | Region.COLORTEXTURE_RENDERING_BIT;
- private static final int TWO_PASS_BIT = 1 << 31;
+ private static class ShaderKey {
+ final boolean isTwoPass;
+ final boolean pass1;
+ final ShaderModeSelector1 sms;
+ final boolean hasAABBoxClipping; // pass1 or pass2
+ final boolean hasColorChannel; // pass1 only
+ final boolean hasColorTexture; // pass1 only
+ final String colorTexSeqID;
+ final int colorTexSeqHash;
+
+ final String texLookupFuncName;
+ final int hashValue;
+
+ ShaderKey(final int renderModes, final boolean pass1_, final int pass2Quality, final int sampleCount, final TextureSequence colorTexSeq, final boolean hasClipBBox) {
+ isTwoPass = Region.isTwoPass( renderModes );
+ pass1 = pass1_;
+ sms = pass1 ? ShaderModeSelector1.selectPass1(renderModes) :
+ ShaderModeSelector1.selectPass2(renderModes, pass2Quality, sampleCount);
+ hasAABBoxClipping = hasClipBBox && ( ( !isTwoPass && pass1 ) || ( isTwoPass && !pass1 ) );
+ hasColorChannel = pass1 && Region.hasColorChannel( renderModes );
+ hasColorTexture = pass1 && Region.hasColorTexture( renderModes ) && null != colorTexSeq;
+ if( hasColorTexture ) {
+ texLookupFuncName = colorTexSeq.setTextureLookupFunctionName(gcuTexture2D);
+ colorTexSeqID = colorTexSeq.getTextureFragmentShaderHashID();
+ colorTexSeqHash = colorTexSeq.getTextureFragmentShaderHashCode();
+ } else {
+ texLookupFuncName = null;
+ colorTexSeqID = "";
+ colorTexSeqHash = 0;
+ }
+ {
+ // 31 * x == (x << 5) - x
+ int hash = 31 * ( isTwoPass ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( pass1 ? 1 : 0 ) ;
+ // hash = ((hash << 5) - hash) + pass2Quality; // included in sms
+ // hash = ((hash << 5) - hash) + sampleCount; // included in sms
+ hash = ((hash << 5) - hash) + sms.ordinal();
+ hash = ((hash << 5) - hash) + ( hasAABBoxClipping ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( hasColorChannel ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( hasColorTexture ? 1 : 0 );
+ hash = ((hash << 5) - hash) + colorTexSeqHash;
+ hashValue = hash;
+ }
+ }
+ @Override
+ public final int hashCode() { return hashValue; }
+ @Override
+ public final boolean equals(final Object other) {
+ if( this == other ) { return true; }
+ if( !(other instanceof ShaderKey) ) {
+ return false;
+ }
+ final ShaderKey o = (ShaderKey)other;
+ return isTwoPass == o.isTwoPass &&
+ pass1 == o.pass1 &&
+ // pass2Quality == o.pass2Quality && // included in sms
+ // sampleCount == o.sampleCount && // included in sms
+ sms.ordinal() == o.sms.ordinal() &&
+ hasAABBoxClipping == o.hasAABBoxClipping &&
+ hasColorChannel == o.hasColorChannel &&
+ hasColorTexture == o.hasColorTexture &&
+ colorTexSeqID.equals(o.colorTexSeqID);
+ }
+ @Override
+ public String toString() {
+ return "ShaderKey[hash 0x"+Integer.toHexString(hashValue)+", is2Pass "+isTwoPass+", pass1 "+pass1+
+ ", has[clip "+hasAABBoxClipping+", colChan "+hasColorChannel+", colTex "+hasColorTexture+"], "+sms+"]";
+ }
+ }
+ private final HashMap<ShaderKey, ShaderProgram> shaderPrograms = new HashMap<ShaderKey, ShaderProgram>();
/**
* Generate, selects and caches the desired Curve-Graph {@link ShaderProgram} according to the given parameters.
@@ -523,7 +591,7 @@ public final class RegionRenderer {
* @param gl
* @param renderModes
* @param pass1
- * @param quality
+ * @param pass2Quality
* @param sampleCount
* @param colorTexSeq
* @return true if a new shader program is being used and hence external uniform-data and -location,
@@ -533,55 +601,31 @@ public final class RegionRenderer {
* @see RenderState#getShaderProgram()
*/
public final boolean useShaderProgram(final GL2ES2 gl, final int renderModes,
- final boolean pass1, final int quality, final int sampleCount, final TextureSequence colorTexSeq) {
- final ShaderModeSelector1 sel1 = pass1 ? ShaderModeSelector1.selectPass1(renderModes) :
- ShaderModeSelector1.selectPass2(renderModes, quality, sampleCount);
- final boolean hasAABBoxClipping = null != getClipBBox();
- final boolean isTwoPass = Region.isTwoPass( renderModes );
- final boolean hasColorChannel = Region.hasColorChannel( renderModes );
- final boolean hasColorTexture = Region.hasColorTexture( renderModes ) && null != colorTexSeq;
- final boolean isPass1ColorTexSeq = pass1 && hasColorTexture;
- final int colorTexSeqHash;
- final String texLookupFuncName;
- if( isPass1ColorTexSeq ) {
- texLookupFuncName = colorTexSeq.setTextureLookupFunctionName(gcuTexture2D);
- colorTexSeqHash = colorTexSeq.getTextureFragmentShaderHashCode();
- } else {
- texLookupFuncName = null;
- colorTexSeqHash = 0;
- }
- final int shaderKey;
- {
- // 31 * x == (x << 5) - x
- int hash = 31 + colorTexSeqHash;
- hash = ((hash << 5) - hash) + sel1.ordinal();
- hash = ((hash << 5) - hash) + ( HIGH_MASK & renderModes );
- hash = ((hash << 5) - hash) + ( hasAABBoxClipping ? 1 : 0 );
- hash = ((hash << 5) - hash) + ( isTwoPass ? TWO_PASS_BIT : 0 );
- shaderKey = hash;
- }
+ final boolean pass1, final int pass2Quality, final int sampleCount, final TextureSequence colorTexSeq) {
+ final ShaderKey shaderKey = new ShaderKey(renderModes, pass1, pass2Quality, sampleCount, colorTexSeq, null != getClipBBox());
/**
if(DEBUG) {
- System.err.printf("RegionRendererImpl01.useShaderProgram.0: renderModes %s, sel1 %s, key 0x%X (pass1 %b, q %d, samples %d) - Thread %s%n",
- Region.getRenderModeString(renderModes), sel1, shaderKey, pass1, quality, sampleCount, Thread.currentThread());
+ System.err.println("XXX "+Region.getRenderModeString(renderModes, sampleCount, 0)+", "+shaderKey);
} */
- ShaderProgram sp = (ShaderProgram) shaderPrograms.get( shaderKey );
+ ShaderProgram sp = shaderPrograms.get( shaderKey );
if( null != sp ) {
final boolean spChanged = rs.setShaderProgram(gl, sp);
- if( DEBUG ) {
+ if( DEBUG_SHADER_MAP ) {
if( spChanged ) {
- System.err.printf("RegionRendererImpl01.useShaderProgram.X1: GOT renderModes %s, sel1 %s, key 0x%X -> sp %d / %d (changed)%n", Region.getRenderModeString(renderModes), sel1, shaderKey, sp.program(), sp.id());
+ System.err.printf("RegionRenderer.useShaderProgram.X1: GOT renderModes %s, %s -> sp %d / %d (changed)%n",
+ Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
} else if( DEBUG_ALL_EVENT ) {
- System.err.printf("RegionRendererImpl01.useShaderProgram.X1: GOT renderModes %s, sel1 %s, key 0x%X -> sp %d / %d (keep)%n", Region.getRenderModeString(renderModes), sel1, shaderKey, sp.program(), sp.id());
+ System.err.printf("RegionRenderer.useShaderProgram.X1: GOT renderModes %s, %s -> sp %d / %d (keep)%n",
+ Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
}
}
return spChanged;
}
final String versionedBaseName = getVersionedShaderName();
final String vertexShaderName;
- if( isTwoPass ) {
+ if( shaderKey.isTwoPass ) {
vertexShaderName = versionedBaseName+"-pass"+(pass1?1:2);
} else {
vertexShaderName = versionedBaseName+"-single";
@@ -589,30 +633,30 @@ public final class RegionRenderer {
final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, AttributeNames.class, SHADER_SRC_SUB, SHADER_BIN_SUB, vertexShaderName, true);
final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, AttributeNames.class, SHADER_SRC_SUB, SHADER_BIN_SUB, versionedBaseName+"-segment-head", true);
- if( isPass1ColorTexSeq && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
+ if( shaderKey.hasColorTexture && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
}
}
- boolean supressGLSLVersionES30 = false;
- if( isPass1ColorTexSeq && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
+ boolean preludeGLSLVersion = true;
+ if( shaderKey.hasColorTexture && GLES2.GL_TEXTURE_EXTERNAL_OES == colorTexSeq.getTextureTarget() ) {
if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
// Bug on Nexus 10, ES3 - Android 4.3, where
// GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
// P0003: Extension 'GL_OES_EGL_image_external' not supported
- supressGLSLVersionES30 = true;
+ preludeGLSLVersion = false;
}
}
//
// GLSL customization at top
//
- int posVp = rsVp.defaultShaderCustomization(gl, !supressGLSLVersionES30, true);
+ int posVp = rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
// rsFp.defaultShaderCustomization(gl, true, true);
- int posFp = supressGLSLVersionES30 ? 0 : rsFp.addGLSLVersion(gl);
- if( isPass1ColorTexSeq ) {
+ int posFp = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
+ if( shaderKey.hasColorTexture ) {
posFp = rsFp.insertShaderSource(0, posFp, colorTexSeq.getRequiredExtensionsShaderStub());
}
- if( pass1 && supressGLSLVersionES30 || ( gl.isGLES2() && !gl.isGLES3() ) ) {
+ if( pass1 && !preludeGLSLVersion || ( gl.isGLES2() && !gl.isGLES3() ) ) {
posFp = rsFp.insertShaderSource(0, posFp, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE));
}
if( false ) {
@@ -628,30 +672,36 @@ public final class RegionRenderer {
// GLSL append from here on
posFp = -1;
+ posVp = rsVp.insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_START);
+ posFp = rsFp.insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_START);
+
if( !gl.getContext().hasRendererQuirk(GLRendererQuirks.GLSLBuggyDiscard) ) {
posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_DISCARD);
}
- if( hasAABBoxClipping ) {
+ if( shaderKey.hasAABBoxClipping ) {
posVp = rsVp.insertShaderSource(0, posVp, GLSL_USE_AABBOX_CLIPPING);
posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_AABBOX_CLIPPING);
}
- if( hasColorChannel ) {
+ if( shaderKey.hasColorChannel ) {
posVp = rsVp.insertShaderSource(0, posVp, GLSL_USE_COLOR_CHANNEL);
posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_COLOR_CHANNEL);
}
- if( isPass1ColorTexSeq ) {
+ if( shaderKey.hasColorTexture ) {
rsVp.insertShaderSource(0, posVp, GLSL_USE_COLOR_TEXTURE);
posFp = rsFp.insertShaderSource(0, posFp, GLSL_USE_COLOR_TEXTURE);
}
if( !pass1 ) {
- posFp = rsFp.insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+sel1.sampleCount+"\n");
- posFp = rsFp.insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+sel1.sampleCount+".0;\n");
+ posFp = rsFp.insertShaderSource(0, posFp, GLSL_DEF_SAMPLE_COUNT+shaderKey.sms.sampleCount+"\n");
+ posFp = rsFp.insertShaderSource(0, posFp, GLSL_CONST_SAMPLE_COUNT+shaderKey.sms.sampleCount+".0;\n");
}
+ posVp = rsVp.insertShaderSource(0, posVp, GLSL_PARAM_COMMENT_END);
+ posFp = rsFp.insertShaderSource(0, posFp, GLSL_PARAM_COMMENT_END);
+
try {
- if( isPass1ColorTexSeq || hasAABBoxClipping ) {
+ if( shaderKey.hasColorTexture || shaderKey.hasAABBoxClipping ) {
posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "functions.glsl");
}
posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "uniforms.glsl");
@@ -663,7 +713,7 @@ public final class RegionRenderer {
throw new RuntimeException("Failed to read: includes");
}
- if( isPass1ColorTexSeq ) {
+ if( shaderKey.hasColorTexture ) {
posFp = rsFp.insertShaderSource(0, posFp, "uniform "+colorTexSeq.getTextureSampler2DType()+" "+UniformNames.gcu_ColorTexUnit+";\n");
posFp = rsFp.insertShaderSource(0, posFp, colorTexSeq.getTextureLookupFragmentShaderImpl());
}
@@ -671,7 +721,7 @@ public final class RegionRenderer {
posFp = rsFp.insertShaderSource(0, posFp, GLSL_MAIN_BEGIN);
final String passS = pass1 ? "-pass1-" : "-pass2-";
- final String shaderSegment = versionedBaseName+passS+sel1.tech+sel1.sub+".glsl";
+ final String shaderSegment = versionedBaseName+passS+shaderKey.sms.tech+shaderKey.sms.sub+".glsl";
if(DEBUG) {
System.err.printf("RegionRendererImpl01.useShaderProgram.1: segment %s%n", shaderSegment);
}
@@ -685,8 +735,8 @@ public final class RegionRenderer {
}
posFp = rsFp.insertShaderSource(0, posFp, "}\n");
- if( isPass1ColorTexSeq ) {
- rsFp.replaceInShaderSource(gcuTexture2D, texLookupFuncName);
+ if( shaderKey.hasColorTexture ) {
+ rsFp.replaceInShaderSource(gcuTexture2D, shaderKey.texLookupFuncName);
}
sp = new ShaderProgram();
@@ -703,9 +753,9 @@ public final class RegionRenderer {
rs.setShaderProgram(gl, sp);
shaderPrograms.put(shaderKey, sp);
- if( DEBUG ) {
- System.err.printf("RegionRendererImpl01.useShaderProgram.X1: PUT renderModes %s, sel1 %s, key 0x%X -> sp %d / %d (changed, new)%n",
- Region.getRenderModeString(renderModes), sel1, shaderKey, sp.program(), sp.id());
+ if( DEBUG_SHADER_MAP ) {
+ System.err.printf("RegionRenderer.useShaderProgram.X1: PUT renderModes %s, %s -> sp %d / %d (changed, new)%n",
+ Region.getRenderModeString(renderModes), shaderKey, sp.program(), sp.id());
// rsFp.dumpShaderSource(System.err);
}
return true;
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
index ed4bc2585..24cab1b85 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
@@ -60,7 +60,7 @@ public class RenderState {
* Shall be set via {@link #setHintMask(int)} and cleared via {@link #clearHintMask(int)}.
* </p>
* <p>
- * If set, {@link GLRegion#draw(GL2ES2, RegionRenderer, int[]) GLRegion's draw-method}
+ * If set, {@link GLRegion#draw(GL2ES2, RegionRenderer, int, int[]) GLRegion's draw-method}
* will set the proper {@link GL#glBlendFuncSeparate(int, int, int, int) blend-function}
* and the clear-color to <i>transparent-black</i> in case of {@link Region#isTwoPass(int) multipass} FBO rendering.
* </p>
@@ -79,7 +79,7 @@ public class RenderState {
* Shall be set via {@link #setHintMask(int)} and cleared via {@link #clearHintMask(int)}.
* </p>
* <p>
- * {@link GLRegion#draw(GL2ES2, RegionRenderer, int[]) GLRegion's draw-method}
+ * {@link GLRegion#draw(GL2ES2, RegionRenderer, int, int[]) GLRegion's draw-method}
* may toggle depth test, and reset it's state according to this hint.
* </p>
* <p>
@@ -137,10 +137,12 @@ public class RenderState {
* @param gl
* @param updateLocation
* @param renderModes
+ * @param setPMVMat01 TODO
* @param throwOnError TODO
* @return true if no error occurred, i.e. all locations found, otherwise false.
*/
- public final boolean update(final GL2ES2 gl, final RenderState rs, final boolean updateLocation, final int renderModes, final boolean pass1, final boolean throwOnError) {
+ public final boolean update(final GL2ES2 gl, final RenderState rs, final boolean updateLocation, final int renderModes,
+ final boolean setPMVMat01, final boolean pass1, final boolean throwOnError) {
if( rs.id() != rsId ) {
// Assignment of Renderstate buffers to uniforms (no copy, direct reference)
gcu_PMVMatrix01.setData(rs.pmvMatrix.getSyncPMv());
@@ -150,7 +152,7 @@ public class RenderState {
}
boolean res = true;
if( null != rs.sp && rs.sp.inUse() ) {
- if( !Region.isTwoPass(renderModes) || !pass1 ) {
+ if( setPMVMat01 ) {
final boolean r0 = rs.updateUniformDataLoc(gl, updateLocation, true, gcu_PMVMatrix01, throwOnError);
res = res && r0;
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
index e6e4f3e0c..a0e342acd 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
@@ -231,7 +231,7 @@ public class TextRegionUtil {
} else {
renderer.setColorStatic(1, 1, 1, 1);
}
- region.draw(gl, renderer, sampleCount);
+ region.draw(gl, renderer, Region.MAX_AA_QUALITY, sampleCount);
return res;
}
@@ -293,7 +293,7 @@ public class TextRegionUtil {
} else {
renderer.setColorStatic(1, 1, 1, 1);
}
- region.draw(gl, renderer, sampleCount);
+ region.draw(gl, renderer, Region.MAX_AA_QUALITY, sampleCount);
region.destroy(gl);
return res;
}
@@ -352,7 +352,7 @@ public class TextRegionUtil {
} else {
renderer.setColorStatic(1, 1, 1, 1);
}
- region.draw(gl, renderer, sampleCount);
+ region.draw(gl, renderer, Region.MAX_AA_QUALITY, sampleCount);
return res;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
index 2da2dcbfc..99704ced0 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java
@@ -159,6 +159,7 @@ public class ImageSequence implements TextureSequence {
} else if(null != texLookupFuncName && texLookupFuncName.length()>0) {
textureLookupFunctionName = texLookupFuncName;
}
+ textureFragmentShaderHashCode = 0;
return textureLookupFunctionName;
}
@@ -180,13 +181,22 @@ public class ImageSequence implements TextureSequence {
}
@Override
+ public String getTextureFragmentShaderHashID() {
+ // return getTextureSampler2DType()+";"+getTextureLookupFunctionName()+";"+getTextureLookupFragmentShaderImpl();
+ if( useBuildInTexLookup ) {
+ return getTextureSampler2DType()+";"+getTextureLookupFunctionName();
+ } else {
+ return getTextureLookupFragmentShaderImpl();
+ }
+ }
+
+ @Override
public int getTextureFragmentShaderHashCode() {
if( !isTextureAvailable() ) {
textureFragmentShaderHashCode = 0;
return 0;
} else if( 0 == textureFragmentShaderHashCode ) {
- int hash = 31 + getTextureLookupFragmentShaderImpl().hashCode();
- hash = ((hash << 5) - hash) + getTextureSampler2DType().hashCode();
+ final int hash = getTextureFragmentShaderHashID().hashCode();
textureFragmentShaderHashCode = hash;
}
return textureFragmentShaderHashCode;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 8376f0fa5..6aa70f014 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -274,19 +274,31 @@ public interface TextureSequence {
* @throws IllegalStateException if instance is not initialized
* @see #getTextureLookupFunctionName()
* @see #setTextureLookupFunctionName(String)
+ * @see #getTextureFragmentShaderHashID()
* @see #getTextureFragmentShaderHashCode()
* @see #getTextureSampler2DType()
*/
public String getTextureLookupFragmentShaderImpl() throws IllegalStateException;
/**
- * Returns the hash code of the strings:
+ * Returns the concatenated string representing the following values
+ * utilized for {@link #getTextureFragmentShaderHashCode()}.
* <ul>
+ * <li>{@link #getTextureSampler2DType()}</li>
* <li>{@link #getTextureLookupFunctionName()}</li>
* <li>{@link #getTextureLookupFragmentShaderImpl()}</li>
- * <li>{@link #getTextureSampler2DType()}</li>
* </ul>
* <p>
+ * To reduce string concatenating, implementation may simply return {@link #getTextureLookupFragmentShaderImpl()},
+ * if it covers {@link #getTextureSampler2DType()} and {@link #getTextureLookupFunctionName()}.
+ * </p>
+ * @see #getTextureFragmentShaderHashCode()
+ */
+ public String getTextureFragmentShaderHashID();
+
+ /**
+ * Returns the hash code of the string {@link #getTextureFragmentShaderHashID()}.
+ * <p>
* User shall call {@link #setTextureLookupFunctionName(String)} first if intended.
* </p>
* <p>
@@ -296,12 +308,13 @@ public interface TextureSequence {
* <p>
* </p>
* <p>
- * Implementation caches the resulting hash code,
- * which must be reset to zero if {@link #isTextureAvailable() texture is not available}.
+ * Implementation caches the resulting hash code, which is reset by {@link #setTextureLookupFunctionName(String)}
+ * and this method if {@link #isTextureAvailable() texture is not available}.
* </p>
* @see #setTextureLookupFunctionName(String)
* @see #getTextureLookupFunctionName()
* @see #getTextureLookupFragmentShaderImpl()
+ * @see #getTextureFragmentShaderHashID()
*/
public int getTextureFragmentShaderHashCode();