From b71f91e67270958bdb2940615a83e4d1ccc9ca0a Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Tue, 25 Mar 2014 06:40:08 +0100
Subject: Bug 801: Elaborate on multisampling performance/quality: Flipquad,
 RGSS, Quincunx

Using poles only as sampling points is not as effective as: flipquad > rgss >> quincunx

Best quality would be 'wholeedge', i.e. average every supersample,
however performance is worse here.

References:
  <http://fileadmin.cs.lth.se/graphics/research/papers/inexp_ms2005/>
  <http://fileadmin.cs.lth.se/graphics/research/papers/masses2003/>
---
 .../graph/curve/opengl/VBORegion2PMSAAES2.java     | 150 +++++++++++----------
 .../graph/curve/opengl/VBORegion2PVBAAES2.java     |   4 +-
 .../shader/curverenderer01-2pass_msaa-weight.fp    |   4 +-
 .../shader/curverenderer01-2pass_vbaa-weight.fp    |  12 +-
 .../opengl/shader/curverenderer01-2pass_vbaa.fp    |  12 +-
 .../curverenderer01-pass2-vbaa_flipquad.glsl       |  42 ++++++
 .../curverenderer01-pass2-vbaa_flipquad2.glsl      |  42 ++++++
 .../curverenderer01-pass2-vbaa_flipquad3.glsl      | 104 ++++++++++++++
 .../curverenderer01-pass2-vbaa_quincunx.glsl       |  29 ++++
 .../shader/curverenderer01-pass2-vbaa_rgss.glsl    |  26 ++++
 10 files changed, 345 insertions(+), 80 deletions(-)
 create mode 100644 src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad.glsl
 create mode 100644 src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad2.glsl
 create mode 100644 src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad3.glsl
 create mode 100644 src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_quincunx.glsl
 create mode 100644 src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_rgss.glsl

(limited to 'src/jogl/classes')

diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
index 79aa3d779..e36f46878 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
@@ -66,6 +66,7 @@ public class VBORegion2PMSAAES2  extends GLRegion {
 
     private int fboWidth = 0;
     private int fboHeight = 0;
+    private boolean fboDirty = true;
     GLUniformData mgl_ActiveTexture;
     GLUniformData mgl_TextureSize;
 
@@ -99,6 +100,7 @@ public class VBORegion2PMSAAES2  extends GLRegion {
             texCoordTxtAttr.seal(gl, false);
             texCoordTxtAttr.rewind();
         }
+        fboDirty = true;
     }
 
     @Override
@@ -174,14 +176,14 @@ public class VBORegion2PMSAAES2  extends GLRegion {
         indicesFbo.enableBuffer(gl, false);
 
         // trigger renderRegion2FBO !
-        fboHeight = 0;
-        fboWidth = 0;
+        fboDirty = true;
         // the buffers were disabled, since due to real/fbo switching and other vbo usage
     }
 
     private final AABBox drawWinBox = new AABBox();
     private final int[] drawView = new int[] { 0, 0, 0, 0 };
     private final float[] drawTmpV3 = new float[3];
+    private final int border = 2; // surrounding border, i.e. width += 2*border, height +=2*border
 
     @Override
     protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) {
@@ -197,35 +199,62 @@ public class VBORegion2PMSAAES2  extends GLRegion {
             }
             return; // inf
         }
-        final int width = renderer.getWidth();
-        final int height = renderer.getHeight();
-        if(width <=0 || height <= 0 || null==sampleCount || sampleCount[0] <= 0){
+        final int vpWidth = renderer.getWidth();
+        final int vpHeight = renderer.getHeight();
+        if(vpWidth <=0 || vpHeight <= 0 || null==sampleCount || sampleCount[0] <= 0){
             renderRegion(gl);
         } else {
             if(0 > maxTexSize[0]) {
                 gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxTexSize, 0);
             }
             final RenderState rs = renderer.getRenderState();
-            float renderFboWidth, renderFboHeight;
+            final float winWidth, winHeight;
+
+            final float ratioObjWinWidth, ratioObjWinHeight;
+            final float diffObjWidth, diffObjHeight;
+            final float diffObjBorderWidth, diffObjBorderHeight;
             int targetFboWidth, targetFboHeight;
-            float diffWidth, diffHeight;
             {
+                final float diffWinWidth, diffWinHeight;
+                final int targetWinWidth, targetWinHeight;
+
                 // Calculate perspective pixel width/height for FBO,
                 // considering the sampleCount.
-                drawView[2] = width;
-                drawView[3] = height;
+                drawView[2] = vpWidth;
+                drawView[3] = vpHeight;
                 box.mapToWindow(drawWinBox, renderer.getMatrix(), drawView, true /* useCenterZ */, drawTmpV3);
-                renderFboWidth = drawWinBox.getWidth();
-                renderFboHeight = drawWinBox.getHeight();
-                targetFboWidth = (int)Math.ceil(renderFboWidth);
-                targetFboHeight = (int)Math.ceil(renderFboHeight);
-                diffWidth = targetFboWidth-renderFboWidth;
-                diffHeight = targetFboHeight-renderFboHeight;
+                winWidth = drawWinBox.getWidth();
+                winHeight = drawWinBox.getHeight();
+                targetWinWidth = (int)Math.ceil(winWidth);
+                targetWinHeight = (int)Math.ceil(winHeight);
+                diffWinWidth = targetWinWidth-winWidth;
+                diffWinHeight = targetWinHeight-winHeight;
+
+                ratioObjWinWidth = box.getWidth() / winWidth;
+                ratioObjWinHeight= box.getHeight() / winHeight;
+                diffObjWidth = diffWinWidth * ratioObjWinWidth;
+                diffObjHeight = diffWinHeight * ratioObjWinHeight;
+                diffObjBorderWidth = border * ratioObjWinWidth;
+                diffObjBorderHeight = border * ratioObjWinHeight;
+
+                targetFboWidth = targetWinWidth+2*border;
+                targetFboHeight = targetWinHeight+2*border;
+
                 if( DEBUG_FBO_2 ) {
-                    System.err.printf("XXX.MinMax view[%d, %d]: FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n",
+                    final float ratioWinWidth, ratioWinHeight;
+                    ratioWinWidth = winWidth/targetWinWidth;
+                    ratioWinHeight = winHeight/targetWinHeight;
+
+                    System.err.printf("XXX.MinMax obj %s%n", box.toString());
+                    System.err.printf("XXX.MinMax obj d[%.3f, %.3f], r[%f, %f], b[%f, %f]%n",
+                            diffObjWidth, diffObjHeight, ratioObjWinWidth, ratioObjWinWidth, diffObjBorderWidth, diffObjBorderHeight);
+                    System.err.printf("XXX.MinMax win %s%n", drawWinBox.toString());
+                    System.err.printf("XXX.MinMax view[%d, %d] -> win[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], r[%f, %f]: FBO i[%d x %d], samples %d%n",
                             drawView[2], drawView[3],
-                            renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight,
-                            diffWidth, diffHeight, sampleCount[0]);
+                            winWidth, winHeight, targetWinWidth, targetWinHeight, diffWinWidth,
+                            diffWinHeight, ratioWinWidth, ratioWinHeight,
+                            targetFboWidth, targetFboHeight,
+                            sampleCount[0]);
                 }
             }
             if( 0 >= targetFboWidth || 0 >= targetFboHeight ) {
@@ -234,85 +263,61 @@ public class VBORegion2PMSAAES2  extends GLRegion {
             }
             final int deltaFboWidth = Math.abs(targetFboWidth-fboWidth);
             final int deltaFboHeight = Math.abs(targetFboHeight-fboHeight);
-            final int maxDeltaFbo, maxLengthFbo;
-            if( deltaFboWidth >= deltaFboHeight ) {
-                maxDeltaFbo = deltaFboWidth;
-                maxLengthFbo = fboWidth > 0 ? fboWidth : 1;
-            } else {
-                maxDeltaFbo = deltaFboHeight;
-                maxLengthFbo = fboHeight > 0 ? fboHeight : 1;
-            }
-            final float pctFboDelta = (float)maxDeltaFbo / (float)maxLengthFbo;
+            final boolean hasDelta = 0!=deltaFboWidth || 0!=deltaFboHeight;
             if( DEBUG_FBO_2 ) {
-                System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta);
+                System.err.printf("XXX.maxDelta: hasDelta %b: %d / %d,  %.3f, %.3f%n",
+                        hasDelta, deltaFboWidth, deltaFboHeight, (float)deltaFboWidth/fboWidth, (float)deltaFboHeight/fboHeight);
+                System.err.printf("XXX.Scale %d * [%f x %f]: %d x %d%n",
+                        sampleCount[0], winWidth, winHeight, targetFboWidth, targetFboHeight);
             }
-            if( pctFboDelta > 0.1f || ( fbo != null && fbo.getNumSamples() != sampleCount[0] ) ) { // more than 10% !
-                if( DEBUG_FBO_1 ) {
-                    System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta);
-                    System.err.printf("XXX.MSAA %d, %d x %d%n",
-                            sampleCount[0], targetFboWidth, targetFboHeight);
-                }
-                // FIXME: maxTexSize test not correct
-                boolean rescale = false;
-                if( targetFboWidth > maxTexSize[0] ) {
-                    targetFboWidth = maxTexSize[0];
-                    renderFboWidth = targetFboWidth;
-                    rescale = true;
-                }
-                if( targetFboHeight > maxTexSize[0] ) {
-                    targetFboHeight = maxTexSize[0];
-                    renderFboHeight = targetFboHeight;
-                    rescale = true;
-                }
-                if(rescale) {
-                    diffWidth = targetFboWidth-renderFboWidth;
-                    diffHeight = targetFboHeight-renderFboHeight;
-                    if( DEBUG_FBO_1 ) {
-                        System.err.printf("XXX.Rescale (MAX): FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n",
-                                renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight,
-                                diffWidth, diffHeight, sampleCount[0]);
-                    }
-                }
+            if( hasDelta || fboDirty || null == fbo || ( fbo != null && fbo.getNumSamples() != sampleCount[0] ) ) {
+                // FIXME: rescale
+
+                final float minX = box.getMinX()-diffObjBorderWidth;
+                final float minY = box.getMinY()-diffObjBorderHeight;
+                final float maxX = box.getMaxX()+diffObjBorderWidth+diffObjWidth;
+                final float maxY = box.getMaxY()+diffObjBorderHeight+diffObjHeight;
                 verticeFboAttr.seal(false);
-                verticeFboAttr.rewind();
-                verticeFboAttr.putf(box.getMinX());           verticeFboAttr.putf(box.getMinY());            verticeFboAttr.putf(box.getMinZ());
-                verticeFboAttr.putf(box.getMinX());           verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ());
-                verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ());
-                verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMinY());            verticeFboAttr.putf(box.getMinZ());
+                {
+                    final FloatBuffer fb = (FloatBuffer)verticeFboAttr.getBuffer();
+                    fb.put(0, minX); fb.put( 1, minY);
+                    fb.put(3, minX); fb.put( 4, maxY);
+                    fb.put(6, maxX); fb.put( 7, maxY);
+                    fb.put(9, maxX); fb.put(10, minY);
+                }
                 verticeFboAttr.seal(true);
                 fboPMVMatrix.glLoadIdentity();
-                fboPMVMatrix.glOrthof(box.getMinX(), box.getMaxX()+diffWidth,
-                                      box.getMinY(), box.getMaxY()+diffHeight, -1, 1);
-                renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, sampleCount);
+                fboPMVMatrix.glOrthof(minX, maxX, minY, maxY, -1, 1);
+                renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, vpWidth, vpHeight, sampleCount);
             } else {
                 texCoordFboAttr.setVBOWritten(false);
             }
             // System.out.println("Scale: " + matrix.glGetMatrixf().get(1+4*3) +" " + matrix.glGetMatrixf().get(2+4*3));
-            renderFBO(gl, rs, width, height);
+            renderFBO(gl, rs, vpWidth, vpHeight, sampleCount[0]);
         }
     }
-    private void setTexSize(final GL2ES2 gl, final ShaderState st, boolean firstPass) {
+    private void setTexSize(final GL2ES2 gl, final ShaderState st, final boolean firstPass, final int width, final int height, final int sampleCount) {
         if(null == mgl_TextureSize) {
             mgl_TextureSize = new GLUniformData(UniformNames.gcu_TextureSize, 3, Buffers.newDirectFloatBuffer(3));
         }
         final FloatBuffer texSize = (FloatBuffer) mgl_TextureSize.getBuffer();
+        texSize.put(0, width);
+        texSize.put(1, height);
         if( firstPass ) {
             texSize.put(2, 0f);
         } else {
-            texSize.put(0, fboWidth);
-            texSize.put(1, fboHeight);
-            texSize.put(2, 1f);
+            texSize.put(2, 1f+sampleCount);
         }
         st.uniform(gl, mgl_TextureSize);
     }
 
-    private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int height) {
+    private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int height, final int sampleCount) {
         final ShaderState st = rs.getShaderState();
 
         gl.glViewport(0, 0, width, height);
         st.uniform(gl, mgl_ActiveTexture);
         gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
-        setTexSize(gl, st, false);
+        setTexSize(gl, st, false, fboWidth, fboHeight, sampleCount);
 
         fbo.use(gl, fbo.getSamplingSink());
         verticeFboAttr.enableBuffer(gl, true);
@@ -329,7 +334,8 @@ public class VBORegion2PMSAAES2  extends GLRegion {
         // setback: gl.glActiveTexture(currentActiveTextureEngine[0]);
     }
 
-    private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight, int[] sampleCount) {
+    private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight,
+                                  final int vpWidth, final int vpHeight, final int[] sampleCount) {
         final ShaderState st = rs.getShaderState();
 
         if( 0 >= targetFboWidth || 0 >= targetFboHeight ) {
@@ -367,7 +373,7 @@ public class VBORegion2PMSAAES2  extends GLRegion {
             fboHeight  = targetFboHeight;
         }
         fbo.bind(gl);
-        setTexSize(gl, st, true);
+        setTexSize(gl, st, true, vpWidth, vpHeight, sampleCount[0]);
 
         //render texture
         gl.glViewport(0, 0, fboWidth, fboHeight);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
index e8c0a6b66..4a12ed8d9 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
@@ -403,7 +403,7 @@ public class VBORegion2PVBAAES2  extends GLRegion {
             renderFBO(gl, rs, targetFboWidth, targetFboHeight, vpWidth, vpHeight, sampleCount[0]);
         }
     }
-    private void setTexSize(final GL2ES2 gl, final ShaderState st, boolean firstPass, int width, int height, int sampleCount) {
+    private void setTexSize(final GL2ES2 gl, final ShaderState st, final boolean firstPass, final int width, final int height, final int sampleCount) {
         if(null == mgl_TextureSize) {
             mgl_TextureSize = new GLUniformData(UniformNames.gcu_TextureSize, 3, Buffers.newDirectFloatBuffer(3));
         }
@@ -419,7 +419,7 @@ public class VBORegion2PVBAAES2  extends GLRegion {
     }
 
     private void renderFBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight,
-                           final int vpWidth, final int vpHeight, int sampleCount) {
+                           final int vpWidth, final int vpHeight, final int sampleCount) {
         final ShaderState st = rs.getShaderState();
 
         gl.glViewport(0, 0, vpWidth, vpHeight);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp
index 1c5688880..0d49c2a7f 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp
@@ -31,12 +31,12 @@ void main (void)
         }
         #endif
 
-        c = t.rgb;   
+        color = t.rgb;   
         alpha = gcu_Alpha * t.a;
     } else {
 
 #include curverenderer01-pass1-curve-weight.glsl
 
     }
-    mgl_FragColor = vec4(c, alpha);
+    mgl_FragColor = vec4(color, alpha);
 }
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp
index 36767b658..bc443061e 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp
@@ -17,6 +17,8 @@
 
 const vec3 zero3 = vec3(0);
 
+#define GetSample(texUnit, texCoord, psize, cx, cy, offX, offY) texture2D(texUnit, texCoord + psize *  vec2(cx+offX, cy+offY))
+
 void main (void)
 {
     vec3 color;
@@ -26,9 +28,15 @@ void main (void)
     
     if( 0 < gcu_TextureSize.z ) {
 
-// 1st Choice VBAA
-#include curverenderer01-pass2-vbaa_poles_equalweight.glsl
+// Quality: wholeedge > [flipquad,rgss, quincunx] > poles
+#include curverenderer01-pass2-vbaa_flipquad3.glsl
+
+// #include curverenderer01-pass2-vbaa_flipquad2.glsl
+// #include curverenderer01-pass2-vbaa_flipquad.glsl
+// #include curverenderer01-pass2-vbaa_rgss.glsl
+// #include curverenderer01-pass2-vbaa_quincunx.glsl
 
+// #include curverenderer01-pass2-vbaa_poles_equalweight.glsl
 // #include curverenderer01-pass2-vbaa_poles_bilin1.glsl
 // #include curverenderer01-pass2-vbaa_poles_propweight1.glsl
 // #include curverenderer01-pass2-vbaa_wholeedge_propweight1.glsl
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp
index 89a193501..6836b3ee0 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp
@@ -17,6 +17,8 @@
 
 const vec3 zero3 = vec3(0);
 
+#define GetSample(texUnit, texCoord, psize, cx, cy, offX, offY) texture2D(texUnit, texCoord + psize *  vec2(cx+offX, cy+offY))
+
 void main (void)
 {
     vec3 color;
@@ -26,9 +28,15 @@ void main (void)
     
     if( 0 < gcu_TextureSize.z ) {
 
-// 1st Choice VBAA
-#include curverenderer01-pass2-vbaa_poles_equalweight.glsl
+// Quality: wholeedge > [flipquad,rgss, quincunx] > poles
+#include curverenderer01-pass2-vbaa_flipquad3.glsl
+
+// #include curverenderer01-pass2-vbaa_flipquad2.glsl
+// #include curverenderer01-pass2-vbaa_flipquad.glsl
+// #include curverenderer01-pass2-vbaa_rgss.glsl
+// #include curverenderer01-pass2-vbaa_quincunx.glsl
 
+// #include curverenderer01-pass2-vbaa_poles_equalweight.glsl
 // #include curverenderer01-pass2-vbaa_poles_bilin1.glsl
 // #include curverenderer01-pass2-vbaa_poles_propweight1.glsl
 // #include curverenderer01-pass2-vbaa_wholeedge_propweight1.glsl
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad.glsl
new file mode 100644
index 000000000..1ee29de77
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad.glsl
@@ -0,0 +1,42 @@
+
+        // Pass-2: AA on Texture
+        // Note: gcv_TexCoord is in center of sample pixels, origin is bottom left!
+
+        const float sampleCount = gcu_TextureSize.z;
+        const vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+        // Just poles (NW, SW, ..)
+        const float edge1H = sampleCount / 2.0;
+        const float edge1T = sampleCount / 3.0;
+        const float edgeTH = edge1H-edge1T;
+
+        const vec2 normFragCoord = gl_FragCoord.xy - vec2(0.5, 0.5); // normalize center 0.5/0.5 -> 0/0
+        const vec2 modPos = mod(normFragCoord, 2.0);
+        const float orient = mod(modPos.x + modPos.y, 2.0); // mirrored on all odd columns, alternating each row (checker-board pattern)
+
+        const vec2 texCoord = gcv_TexCoord.st;
+        vec4 t = vec4(0);
+
+        if( 0 == orient ) {
+                                                                                               // SWIPE LEFT -> RIGHT
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edge1H,  edgeTH, 0.0, 0.0)*0.25; // upper-left  [p1]
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeTH, -edge1H, 0.0, 0.0)*0.25; // lower-left  [p3]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeTH,  edge1H, 0.0, 0.0)*0.25; // upper-right [p2]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edge1H, -edgeTH, 0.0, 0.0)*0.25; // lower-right [p4]
+        } else {
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edge1H, -edgeTH, 0.0, 0.0)*0.25; // lower-left  [p4]
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeTH,  edge1H, 0.0, 0.0)*0.25; // upper-left  [p3]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeTH, -edge1H, 0.0, 0.0)*0.25; // lower-right [p2]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edge1H,  edgeTH, 0.0, 0.0)*0.25; // upper-right [p1]
+        }
+
+
+        #if 0
+        if(t.w == 0.0){
+            discard; // discard freezes NV tegra2 compiler
+        }
+        #endif
+        
+        color = t.rgb;
+        alpha = gcu_Alpha * t.a;
+
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad2.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad2.glsl
new file mode 100644
index 000000000..279269ed6
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad2.glsl
@@ -0,0 +1,42 @@
+
+        // Pass-2: AA on Texture
+        // Note: gcv_TexCoord is in center of sample pixels, origin is bottom left!
+        // 
+        // Same as flipquad - but w/ rgss coordinates
+
+        const float sampleCount = gcu_TextureSize.z;
+        const vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+        const vec2 normFragCoord = gl_FragCoord.xy - vec2(0.5, 0.5); // normalize center 0.5/0.5 -> 0/0
+        const vec2 modPos = mod(normFragCoord, 2.0);
+        const float orient = mod(modPos.x + modPos.y, 2.0); // mirrored on all odd columns, alternating each row (checker-board pattern)
+
+        const vec2 texCoord = gcv_TexCoord.st;
+        const float edge1Q = ( sampleCount / 2.0 ) - 1.0;
+
+        vec4 t = vec4(0);
+
+// #define GetSample(texUnit, texCoord, psize, cx, cy, offX, offY) texture2D(texUnit, texCoord + psize *  vec2(cx+offX, cy+offY))
+
+        if( 0 == orient ) {
+                                                                                               // SWIPE LEFT -> RIGHT
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edge1Q,     0.0, -0.5,  0.5)*0.25; // upper-left  [p1]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0, -edge1Q, -0.5, -0.5)*0.25; // lower-left  [p3]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0,  edge1Q,  0.5,  0.5)*0.25; // upper-right [p2]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edge1Q,     0.0,  0.5, -0.5)*0.25; // lower-right [p4]
+        } else {
+            t += GetSample(gcu_TextureUnit, texCoord, psize, -edge1Q,     0.0, -0.5, -0.5)*0.25; // lower-left  [p4]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0,  edge1Q, -0.5,  0.5)*0.25; // upper-left  [p3]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0, -edge1Q,  0.5, -0.5)*0.25; // lower-right [p2]
+            t += GetSample(gcu_TextureUnit, texCoord, psize,  edge1Q,     0.0,  0.5,  0.5)*0.25; // upper-right [p1]
+        }
+
+        #if 0
+        if(t.w == 0.0){
+            discard; // discard freezes NV tegra2 compiler
+        }
+        #endif
+        
+        color = t.rgb;
+        alpha = gcu_Alpha * t.a;
+
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad3.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad3.glsl
new file mode 100644
index 000000000..2882db4de
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_flipquad3.glsl
@@ -0,0 +1,104 @@
+
+        // Pass-2: AA on Texture
+        // Note: gcv_TexCoord is in center of sample pixels, origin is bottom left!
+        // 
+        // Same as flipquad - but w/ rgss coordinates
+
+        const float sampleCount = gcu_TextureSize.z;
+        const vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+        const vec2 normFragCoord = gl_FragCoord.xy - vec2(0.5, 0.5); // normalize center 0.5/0.5 -> 0/0
+        const vec2 modPos = mod(normFragCoord, 2.0);
+        const float orient = mod(modPos.x + modPos.y, 2.0); // mirrored on all odd columns, alternating each row (checker-board pattern)
+
+        const vec2 texCoord = gcv_TexCoord.st;
+        vec4 t;
+
+// #define GetSample(texUnit, texCoord, psize, cx, cy, offX, offY) texture2D(texUnit, texCoord + psize *  vec2(cx+offX, cy+offY))
+
+        if( 1 == sampleCount ) {
+            t = texture2D(gcu_TextureUnit, texCoord);
+
+        } else if( 4 > sampleCount ) {
+            // SampleCount 2 -> 2p 
+            const float weight = 1.0 / 2.0;
+            const float edge = ( sampleCount / 2.0 ) - 1.0;
+
+            t  = GetSample(gcu_TextureUnit, texCoord, psize,      -edge,       edge, -0.5,  0.5)*weight;  // center
+            t += GetSample(gcu_TextureUnit, texCoord, psize,       edge,      -edge,  0.5, -0.5)*weight;  // center
+
+        } else if( 8 > sampleCount ) {
+            // SampleCount 4 -> 4p
+            const float weight = 1.0 / 4.0;
+            const float edgeS4_1Q = ( sampleCount / 2.0 ) - 1.0;
+
+            if( 0 == orient ) {
+                                                                                                           // SWIPE LEFT -> RIGHT
+                t  = GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -0.5,  0.5)*weight; // upper-left  [p1]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q, -0.5, -0.5)*weight; // lower-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q,  0.5,  0.5)*weight; // upper-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  0.5, -0.5)*weight; // lower-right [p4]
+            } else {
+                t  = GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -0.5, -0.5)*weight; // lower-left  [p4]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q, -0.5,  0.5)*weight; // upper-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q,  0.5, -0.5)*weight; // lower-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  0.5,  0.5)*weight; // upper-right [p1]
+            }
+        } else {
+            // SampleCount 8 -> 16p
+            const float weight = 1.0 / 16.0;
+            const float edgeS4_1Q = 1.0;
+
+            if( 0 == orient ) {
+                                                                                                           // SWIPE LEFT -> RIGHT
+                t  = GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -2.0-0.5, -2.0+0.5)*weight; // upper-left  [p1]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q, -2.0-0.5, -2.0-0.5)*weight; // lower-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q, -2.0-0.5, -2.0-0.5)*weight; // upper-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0, -2.0-0.5, -2.0-0.5)*weight; // lower-right [p4]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -2.0-0.5,  2.0-0.5)*weight; // lower-left  [p4]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q, -2.0-0.5,  2.0+0.5)*weight; // upper-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q, -2.0+0.5,  2.0-0.5)*weight; // lower-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0, -2.0+0.5,  2.0+0.5)*weight; // upper-right [p1]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0,  2.0-0.5, -2.0-0.5)*weight; // lower-left  [p4]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q,  2.0-0.5, -2.0+0.5)*weight; // upper-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q,  2.0+0.5, -2.0-0.5)*weight; // lower-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  2.0+0.5, -2.0+0.5)*weight; // upper-right [p1]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0,  2.0-0.5,  2.0+0.5)*weight; // upper-left  [p1]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q,  2.0-0.5,  2.0-0.5)*weight; // lower-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q,  2.0-0.5,  2.0-0.5)*weight; // upper-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  2.0-0.5,  2.0-0.5)*weight; // lower-right [p4]
+            } else {
+                t  = GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -2.0-0.5, -2.0-0.5)*weight; // lower-left  [p4]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q, -2.0-0.5, -2.0+0.5)*weight; // upper-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q, -2.0+0.5, -2.0-0.5)*weight; // lower-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0, -2.0+0.5, -2.0+0.5)*weight; // upper-right [p1]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0, -2.0-0.5,  2.0+0.5)*weight; // upper-left  [p1]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q, -2.0-0.5,  2.0-0.5)*weight; // lower-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q, -2.0-0.5,  2.0-0.5)*weight; // upper-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0, -2.0-0.5,  2.0-0.5)*weight; // lower-right [p4]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0,  2.0-0.5, -2.0+0.5)*weight; // upper-left  [p1]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q,  2.0-0.5, -2.0-0.5)*weight; // lower-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q,  2.0-0.5, -2.0-0.5)*weight; // upper-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  2.0-0.5, -2.0-0.5)*weight; // lower-right [p4]
+
+                t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeS4_1Q,        0.0,  2.0-0.5,  2.0-0.5)*weight; // lower-left  [p4]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0,  edgeS4_1Q,  2.0-0.5,  2.0+0.5)*weight; // upper-left  [p3]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,        0.0, -edgeS4_1Q,  2.0+0.5,  2.0-0.5)*weight; // lower-right [p2]
+                t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeS4_1Q,        0.0,  2.0+0.5,  2.0+0.5)*weight; // upper-right [p1]
+            }
+        }
+
+        #if 0
+        if(t.w == 0.0){
+            discard; // discard freezes NV tegra2 compiler
+        }
+        #endif
+        
+        color = t.rgb;
+        alpha = gcu_Alpha * t.a;
+
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_quincunx.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_quincunx.glsl
new file mode 100644
index 000000000..2fe4faaff
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_quincunx.glsl
@@ -0,0 +1,29 @@
+
+        // Pass-2: AA on Texture
+        // Note: gcv_TexCoord is in center of sample pixels, origin is bottom left!
+
+        const float sampleCount = gcu_TextureSize.z;
+        const vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+        // Just poles (NW, SW, ..)
+        const float edgeH = sampleCount / 2.0;
+
+        const vec2 texCoord = gcv_TexCoord.st;
+
+        vec4 t = vec4(0);
+
+        t += GetSample(gcu_TextureUnit, texCoord, psize,    0.0,    0.0, 0.0, 0.0)*0.5;   // w1 - center
+        t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeH, -edgeH, 0.0, 0.0)*0.125; // w2 - sharing
+        t += GetSample(gcu_TextureUnit, texCoord, psize, -edgeH,  edgeH, 0.0, 0.0)*0.125; // w3 - edges
+        t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeH, -edgeH, 0.0, 0.0)*0.125; // w4 - w/ all pixels
+        t += GetSample(gcu_TextureUnit, texCoord, psize,  edgeH,  edgeH, 0.0, 0.0)*0.125; // w5
+
+        #if 0
+        if(t.w == 0.0){
+            discard; // discard freezes NV tegra2 compiler
+        }
+        #endif
+        
+        color = t.rgb;
+        alpha = gcu_Alpha * t.a;
+
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_rgss.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_rgss.glsl
new file mode 100644
index 000000000..fc847e08f
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass2-vbaa_rgss.glsl
@@ -0,0 +1,26 @@
+
+        // Pass-2: AA on Texture
+        // Note: gcv_TexCoord is in center of sample pixels, origin is bottom left!
+
+        const float sampleCount = gcu_TextureSize.z;
+        const vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+        const vec2 texCoord = gcv_TexCoord.st;
+        const float edge1Q = ( sampleCount / 2.0 ) - 1.0;
+
+        vec4 t = vec4(0);
+                                                                                           // SWIPE LEFT -> RIGHT
+        t += GetSample(gcu_TextureUnit, texCoord, psize, -edge1Q,     0.0, -0.5,  0.5)*0.25; // upper-left  [p1]
+        t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0, -edge1Q, -0.5, -0.5)*0.25; // lower-left  [p3]
+        t += GetSample(gcu_TextureUnit, texCoord, psize,     0.0,  edge1Q,  0.5,  0.5)*0.25; // upper-right [p2]
+        t += GetSample(gcu_TextureUnit, texCoord, psize,  edge1Q,     0.0,  0.5, -0.5)*0.25; // lower-right [p4]
+
+        #if 0
+        if(t.w == 0.0){
+            discard; // discard freezes NV tegra2 compiler
+        }
+        #endif
+        
+        color = t.rgb;
+        alpha = gcu_Alpha * t.a;
+
-- 
cgit v1.2.3