diff options
author | Sven Gothel <[email protected]> | 2014-03-02 00:19:35 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-02 00:19:35 +0100 |
commit | 7b1a0c17fe5471557ab5e0db0334bed34edb553a (patch) | |
tree | c6242b548f4f9cbe2411c8cb4bc6dd6924437e8b /src | |
parent | c1218a7bcf42ae64b41e3d30bb1ee39c44b20a9f (diff) |
Bug 801: Add MSAA_RENDERING_BIT ; VBAA: Uses GL_NEAREST (good result) ; Demos: Use local GLRegion for uncached text (perf.) ..
Diffstat (limited to 'src')
22 files changed, 793 insertions, 88 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index 9d6e339f2..8e68b7913 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -30,7 +30,8 @@ package com.jogamp.graph.curve; import java.util.ArrayList; import java.util.List; -import jogamp.graph.curve.opengl.VBORegion2PES2; +import jogamp.graph.curve.opengl.VBORegion2PVBAAES2; +import jogamp.graph.curve.opengl.VBORegion2PMSAAES2; import jogamp.graph.curve.opengl.VBORegionSPES2; import jogamp.graph.geom.plane.AffineTransform; import jogamp.opengl.Debug; @@ -52,18 +53,25 @@ public abstract class Region { public static final boolean DEBUG_INSTANCE = Debug.debug("graph.curve.instance"); /** - * View based Anti-Aliasing, A Two pass region rendering, slower and more + * MSAA based Anti-Aliasing, a two pass region rendering, slower and more + * resource hungry (FBO), but providing fast MSAA in case + * the whole scene is not rendered with MSAA. + */ + public static final int MSAA_RENDERING_BIT = 1 << 0; + + /** + * View based Anti-Aliasing, a two pass region rendering, slower and more * resource hungry (FBO), but AA is perfect. Otherwise the default fast one * pass MSAA region rendering is being used. */ - public static final int VBAA_RENDERING_BIT = 1 << 0; + public static final int VBAA_RENDERING_BIT = 1 << 1; /** * Use non uniform weights [0.0 .. 1.9] for curve region rendering. * Otherwise the default weight 1.0 for uniform curve region rendering is * being applied. */ - public static final int VARIABLE_CURVE_WEIGHT_BIT = 1 << 1; + public static final int VARIABLE_CURVE_WEIGHT_BIT = 1 << 8; public static final int TWO_PASS_DEFAULT_TEXTURE_UNIT = 0; @@ -75,6 +83,18 @@ public abstract class Region { public static boolean isVBAA(int renderModes) { return 0 != (renderModes & Region.VBAA_RENDERING_BIT); } + public static boolean isMSAA(int renderModes) { + return 0 != (renderModes & Region.MSAA_RENDERING_BIT); + } + public static String getRenderModeString(int renderModes) { + if( Region.isVBAA(renderModes) ) { + return "vbaa"; + } else if( Region.isMSAA(renderModes) ) { + return "msaa"; + } else { + return "norm" ; + } + } /** * Check if render mode capable of non uniform weights @@ -98,10 +118,11 @@ public abstract class Region { * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} */ public static GLRegion create(int renderModes) { - if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){ - return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT); - } - else{ + if( isVBAA(renderModes) ) { + return new VBORegion2PVBAAES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT); + } else if( isMSAA(renderModes) ) { + return new VBORegion2PMSAAES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT); + } else { return new VBORegionSPES2(renderModes); } } @@ -136,6 +157,13 @@ public abstract class Region { } /** + * Return true if capable of two pass rendering - MSAA, otherwise false. + */ + public final boolean isMSAA() { + return isMSAA(renderModes); + } + + /** * Return true if capable of nonuniform weights, otherwise false. */ public final boolean isNonUniformWeight() { 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 92fa084cd..7e0c17eb9 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -294,7 +294,14 @@ public abstract class RegionRenderer { protected String getFragmentShaderName() { final String version = getImplVersion(); - final String pass = Region.isVBAA(renderModes) ? "-2pass" : "-1pass" ; + final String pass; + if( Region.isVBAA(renderModes) ) { + pass = "-2pass_vbaa"; + } else if( Region.isMSAA(renderModes) ) { + pass = "-2pass_msaa"; + } else { + pass = "-1pass_norm" ; + } final String weight = Region.isNonUniformWeight(renderModes) ? "-weight" : "" ; return "curverenderer" + version + pass + weight; } diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java index 90a8dc073..33751eab9 100644 --- a/src/jogl/classes/com/jogamp/opengl/FBObject.java +++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java @@ -2316,8 +2316,8 @@ public class FBObject { return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+ ", samples "+samples+"/"+maxSamples+", depth "+depth+", stencil "+stencil+ ", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+ - ": "+caps+", msaa-sink "+samplingSinkTexture+", hasSamplesSink "+(null != samplingSink)+ - ", state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]"; + ": "+caps+", msaa["+samplingSinkTexture+", hasSink "+(null != samplingSink)+ + ", dirty "+samplingSinkDirty+"], state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]"; } private final void updateStatus(GL gl) { diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java new file mode 100644 index 000000000..cac55f6db --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -0,0 +1,366 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.graph.curve.opengl; + +import javax.media.opengl.GL2ES2; +// FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER ! +import javax.media.opengl.GL; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import jogamp.graph.curve.opengl.shader.AttributeNames; +import jogamp.graph.curve.opengl.shader.UniformNames; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.GLRegion; +import com.jogamp.graph.curve.opengl.RegionRenderer; +import com.jogamp.graph.curve.opengl.RenderState; +import com.jogamp.opengl.FBObject; +import com.jogamp.opengl.FBObject.Attachment; +import com.jogamp.opengl.util.GLArrayDataServer; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class VBORegion2PMSAAES2 extends GLRegion { + private static final boolean DEBUG_FBO_1 = false; + private static final boolean DEBUG_FBO_2 = false; + private GLArrayDataServer verticeTxtAttr; + private GLArrayDataServer texCoordTxtAttr; + private GLArrayDataServer indicesTxtBuffer; + private GLArrayDataServer verticeFboAttr; + private GLArrayDataServer texCoordFboAttr; + private GLArrayDataServer indicesFbo; + + private FBObject fbo; + private final PMVMatrix fboPMVMatrix; + GLUniformData mgl_fboPMVMatrix; + + private int fboWidth = 0; + private int fboHeight = 0; + GLUniformData mgl_ActiveTexture; + GLUniformData mgl_TextureSize; // if GLSL < 1.30 + + final int[] maxTexSize = new int[] { -1 } ; + + public VBORegion2PMSAAES2(final int renderModes, final int textureUnit) { + super(renderModes); + final int initialElementCount = 256; + fboPMVMatrix = new PMVMatrix(); + mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf()); + mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureUnit); + + indicesTxtBuffer = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + verticeTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); + texCoordTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); + } + + @Override + protected final void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) { + indicesTxtBuffer.seal(gl, false); + indicesTxtBuffer.rewind(); + verticeTxtAttr.seal(gl, false); + verticeTxtAttr.rewind(); + texCoordTxtAttr.seal(gl, false); + texCoordTxtAttr.rewind(); + } + + @Override + protected final void pushVertex(float[] coords, float[] texParams) { + verticeTxtAttr.putf(coords[0]); + verticeTxtAttr.putf(coords[1]); + verticeTxtAttr.putf(coords[2]); + + texCoordTxtAttr.putf(texParams[0]); + texCoordTxtAttr.putf(texParams[1]); + } + + @Override + protected final void pushIndex(int idx) { + indicesTxtBuffer.puts((short)idx); + } + + @Override + protected void update(final GL2ES2 gl, final RegionRenderer renderer) { + if(null == indicesFbo) { + final ShaderState st = renderer.getShaderState(); + + indicesFbo = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesFbo.puts((short) 0); indicesFbo.puts((short) 1); indicesFbo.puts((short) 3); + indicesFbo.puts((short) 1); indicesFbo.puts((short) 2); indicesFbo.puts((short) 3); + indicesFbo.seal(true); + + texCoordFboAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, + false, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(texCoordFboAttr, true); + texCoordFboAttr.putf(5); texCoordFboAttr.putf(5); + texCoordFboAttr.putf(5); texCoordFboAttr.putf(6); + texCoordFboAttr.putf(6); texCoordFboAttr.putf(6); + texCoordFboAttr.putf(6); texCoordFboAttr.putf(5); + texCoordFboAttr.seal(true); + + verticeFboAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(verticeFboAttr, true); + + st.ownAttribute(verticeTxtAttr, true); + st.ownAttribute(texCoordTxtAttr, true); + + if(Region.DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Create: " + this); + } + } + // seal buffers + indicesTxtBuffer.seal(gl, true); + indicesTxtBuffer.enableBuffer(gl, false); + texCoordTxtAttr.seal(gl, true); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.seal(gl, true); + verticeTxtAttr.enableBuffer(gl, false); + + // update all bbox related data + verticeFboAttr.seal(gl, false); + verticeFboAttr.rewind(); + verticeFboAttr.putf(box.getLow()[0]); verticeFboAttr.putf(box.getLow()[1]); verticeFboAttr.putf(box.getLow()[2]); + verticeFboAttr.putf(box.getLow()[0]); verticeFboAttr.putf(box.getHigh()[1]); verticeFboAttr.putf(box.getLow()[2]); + verticeFboAttr.putf(box.getHigh()[0]); verticeFboAttr.putf(box.getHigh()[1]); verticeFboAttr.putf(box.getLow()[2]); + verticeFboAttr.putf(box.getHigh()[0]); verticeFboAttr.putf(box.getLow()[1]); verticeFboAttr.putf(box.getLow()[2]); + verticeFboAttr.seal(gl, true); + verticeFboAttr.enableBuffer(gl, false); + + fboPMVMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + fboPMVMatrix.glLoadIdentity(); + fboPMVMatrix.glOrthof(box.getLow()[0], box.getHigh()[0], box.getLow()[1], box.getHigh()[1], -1, 1); + + // push data 2 GPU .. + indicesFbo.seal(gl, true); + indicesFbo.enableBuffer(gl, false); + + // trigger renderRegion2FBO ! + fboHeight = 0; + fboWidth = 0; + // the buffers were disabled, since due to real/fbo switching and other vbo usage + } + + @Override + protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + final int width = renderer.getWidth(); + final int height = renderer.getHeight(); + if(width <=0 || height <= 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(); + int targetFboWidth, targetFboHeight; + { + // Calculate perspective pixel width/height for FBO, + // considering the sampleCount. + final int[] view = new int[] { 0, 0, width, height }; + final float objZ = 0f; + + final float[] winPosSzMin = new float[3]; + final float[] winPosSzMax = new float[3]; + final PMVMatrix pmv = renderer.getMatrix(); + pmv.gluProject(box.getMinX(), box.getMinY(), objZ, view, 0, winPosSzMin, 0); + pmv.gluProject(box.getMaxX(), box.getMaxY(), objZ, view, 0, winPosSzMax, 0); + targetFboWidth = Math.round(Math.abs(winPosSzMax[0] - winPosSzMin[0])); + targetFboHeight = Math.round(Math.abs(winPosSzMax[1] - winPosSzMin[1])); + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.MinMax1 min [%.1f, %.1f -> %.3f, %.3f, %.3f]"+ + ", max [%.1f, %.1f -> %.3f, %.3f, %.3f], view[%d, %d] -> [%d x %d], msaa %d%n", + box.getMinX(), box.getMinY(), winPosSzMin[0], winPosSzMin[1], winPosSzMin[2], + box.getMaxX(), box.getMaxY(), winPosSzMax[0], winPosSzMax[1], winPosSzMax[2], + view[2], view[3], targetFboWidth, targetFboHeight, sampleCount[0]); + } + } + 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; + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); + } + 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 + if( targetFboWidth > maxTexSize[0] ) { + targetFboWidth = maxTexSize[0]; + } + if( targetFboHeight > maxTexSize[0] ) { + targetFboHeight = maxTexSize[0]; + } + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.Rescale (MAX): %d %d x %d%n", + sampleCount[0], targetFboWidth, targetFboHeight); + } + renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, sampleCount); + } + // System.out.println("Scale: " + matrix.glGetMatrixf().get(1+4*3) +" " + matrix.glGetMatrixf().get(2+4*3)); + renderFBO(gl, rs, width, height); + } + } + + private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int hight) { + final ShaderState st = rs.getShaderState(); + + gl.glViewport(0, 0, width, hight); + st.uniform(gl, mgl_ActiveTexture); + gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue()); + + fbo.use(gl, fbo.getSamplingSink()); + verticeFboAttr.enableBuffer(gl, true); + texCoordFboAttr.enableBuffer(gl, true); + indicesFbo.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesFbo.bindBuffer(gl, false); + texCoordFboAttr.enableBuffer(gl, false); + verticeFboAttr.enableBuffer(gl, false); + fbo.unuse(gl); + + // setback: gl.glActiveTexture(currentActiveTextureEngine[0]); + } + + private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight, int[] sampleCount) { + final ShaderState st = rs.getShaderState(); + + if( 0 >= targetFboWidth || 0 >= targetFboHeight ) { + throw new IllegalArgumentException("fboSize must be greater than 0: "+targetFboWidth+"x"+targetFboHeight); + } + + if(null == fbo) { + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + fbo = new FBObject(); + fbo.reset(gl, fboWidth, fboHeight, sampleCount[0], false); + sampleCount[0] = fbo.getNumSamples(); + fbo.attachColorbuffer(gl, 0, true); + fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + final FBObject ssink = new FBObject(); + { + ssink.reset(gl, fboWidth, fboHeight); + // FIXME: shall not use bilinear (GL_LINEAR), due to MSAA ??? + // ssink.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + ssink.attachTexture2D(gl, 0, true, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + ssink.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + } + fbo.setSamplingSink(ssink); + fbo.resetSamplingSink(gl); // validate + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.createFBO: %dx%d%n%s%n", fboWidth, fboHeight, fbo.toString()); + } + } else if( targetFboWidth != fboWidth || targetFboHeight != fboHeight || fbo.getNumSamples() != sampleCount[0] ) { + fbo.reset(gl, targetFboWidth, targetFboHeight, sampleCount[0], true /* resetSamplingSink */); + sampleCount[0] = fbo.getNumSamples(); + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.resetFBO: %dx%d -> %dx%d%n%s%n", fboWidth, fboHeight, targetFboWidth, targetFboHeight, fbo ); + } + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + } + fbo.bind(gl); + + //render texture + gl.glViewport(0, 0, fboWidth, fboHeight); + st.uniform(gl, mgl_fboPMVMatrix); // use orthogonal matrix + + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT); + renderRegion(gl); + fbo.unbind(gl); + + st.uniform(gl, rs.getPMVMatrix()); // switch back to real PMV matrix + } + + private void renderRegion(final GL2ES2 gl) { + verticeTxtAttr.enableBuffer(gl, true); + texCoordTxtAttr.enableBuffer(gl, true); + indicesTxtBuffer.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxtBuffer.getElementCount() * indicesTxtBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesTxtBuffer.bindBuffer(gl, false); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.enableBuffer(gl, false); + } + + @Override + protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { + if(DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Destroy: " + this); + } + final ShaderState st = renderer.getShaderState(); + if(null != fbo) { + fbo.destroy(gl); + fbo = null; + } + if(null != verticeTxtAttr) { + st.ownAttribute(verticeTxtAttr, false); + verticeTxtAttr.destroy(gl); + verticeTxtAttr = null; + } + if(null != texCoordTxtAttr) { + st.ownAttribute(texCoordTxtAttr, false); + texCoordTxtAttr.destroy(gl); + texCoordTxtAttr = null; + } + if(null != indicesTxtBuffer) { + indicesTxtBuffer.destroy(gl); + indicesTxtBuffer = null; + } + if(null != verticeFboAttr) { + st.ownAttribute(verticeFboAttr, false); + verticeFboAttr.destroy(gl); + verticeFboAttr = null; + } + if(null != texCoordFboAttr) { + st.ownAttribute(texCoordFboAttr, false); + texCoordFboAttr.destroy(gl); + texCoordFboAttr = null; + } + if(null != indicesFbo) { + indicesFbo.destroy(gl); + indicesFbo = null; + } + } +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java index 11309290d..aeb8501ec 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -50,7 +50,7 @@ import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderState; -public class VBORegion2PES2 extends GLRegion { +public class VBORegion2PVBAAES2 extends GLRegion { private static final boolean DEBUG_FBO_1 = false; private static final boolean DEBUG_FBO_2 = false; private GLArrayDataServer verticeTxtAttr; @@ -72,7 +72,7 @@ public class VBORegion2PES2 extends GLRegion { final int[] maxTexSize = new int[] { -1 } ; - public VBORegion2PES2(final int renderModes, final int textureUnit) { + public VBORegion2PVBAAES2(final int renderModes, final int textureUnit) { super(renderModes); final int initialElementCount = 256; fboPMVMatrix = new PMVMatrix(); @@ -227,7 +227,7 @@ public class VBORegion2PES2 extends GLRegion { if( pctFboDelta > 0.1f ) { // more than 10% ! if( DEBUG_FBO_1 ) { System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); - System.err.printf("XXX.Scale %d * [%f x %f]: %dx%d%n", + System.err.printf("XXX.Scale %d * [%f x %f]: %d x %d%n", sampleCount[0], winWidth, winHeight, targetFboWidth, targetFboHeight); } final int maxLength = Math.max(targetFboWidth, targetFboHeight); @@ -240,9 +240,14 @@ public class VBORegion2PES2 extends GLRegion { targetFboWidth = Math.round(winWidth*sampleCount[0]); targetFboHeight= Math.round(winHeight*sampleCount[0]); if( DEBUG_FBO_1 ) { - System.err.printf("XXX.Rescale (MAX): %d * [%f x %f]: %dx%d%n", + System.err.printf("XXX.Rescale (MAX): %d * [%f x %f]: %d x %d%n", sampleCount[0], winWidth, winHeight, targetFboWidth, targetFboHeight); } + if( sampleCount[0] <= 0 ) { + // Last way out! + renderRegion(gl); + return; + } } renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight); } @@ -286,9 +291,9 @@ public class VBORegion2PES2 extends GLRegion { fboHeight = targetFboHeight; fbo = new FBObject(); fbo.reset(gl, fboWidth, fboHeight); - // FIXME: shall not use bilinear, due to own AA ? However, w/o bilinear result is not smooth - texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); - // texA = fbo.attachTexture2D(gl, 0, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + // FIXME: shall not use bilinear (GL_LINEAR), due to own VBAA. Seems result is smooth w/o it now! + // texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); if( DEBUG_FBO_1 ) { System.err.printf("XXX.createFBO: %dx%d%n%s%n", fboWidth, fboHeight, fbo.toString()); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm-weight.fp index 2248792cb..2248792cb 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass-weight.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm-weight.fp diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm.fp index 94e551832..94e551832 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm.fp 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 new file mode 100644 index 000000000..a4c547939 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp @@ -0,0 +1,69 @@ +//Copyright 2010 JogAmp Community. All rights reserved.
+
+//
+// 2-pass shader w/ weight
+//
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+#include uniforms.glsl
+#include varyings.glsl
+
+void main (void)
+{
+ vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y));
+ vec3 c = gcu_ColorStatic.rgb;
+
+ float alpha = 0.0;
+
+ if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) {
+ alpha = gcu_Alpha;
+ }
+ else if((gcv_TexCoord.x >= 5.0)) {
+ rtex -= 5.0;
+ vec4 t = texture2D(gcu_TextureUnit, rtex);
+
+ #if 0
+ if(t.w == 0.0) {
+ discard; // discard freezes NV tegra2 compiler
+ }
+ #endif
+
+ c = t.xyz;
+ alpha = gcu_Alpha * t.w;
+ }
+ ///////////////////////////////////////////////////////////
+ else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) {
+ rtex.y -= 0.1;
+
+ if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) {
+ // discard; // freezes NV tegra2 compiler
+ alpha = 0.0;
+ } else {
+ rtex.y = max(rtex.y, 0.0);
+
+ vec2 dtx = dFdx(rtex);
+ vec2 dty = dFdy(rtex);
+
+ float w = gcu_Weight;
+ float pd = ((2.0 - (2.0*w))*rtex.x*rtex.x) + 2.0*(w-1.0)*rtex.x + 1.0;
+ float position = rtex.y - ((w*rtex.x*(1.0 - rtex.x))/pd);
+
+ float aph = 2.0 - 2.0*w;
+
+ float gd = (aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0)*(aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0);
+ vec2 f = vec2((dtx.y - (w*dtx.x*(1.0 - 2.0*rtex.x))/gd), (dty.y - (w*dty.x*(1.0 - 2.0*rtex.x))/gd));
+
+ float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
+ alpha = gcu_Alpha * a;
+ }
+ }
+
+ mgl_FragColor = vec4(c, alpha);
+}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp new file mode 100644 index 000000000..21cd9de71 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp @@ -0,0 +1,62 @@ +//Copyright 2010 JogAmp Community. All rights reserved. + +// +// 2-pass shader w/o weight +// + +#if __VERSION__ >= 130 + #define varying in + out vec4 mgl_FragColor; + #define texture2D texture +#else + #define mgl_FragColor gl_FragColor +#endif + +#include uniforms.glsl +#include varyings.glsl + +void main (void) +{ + vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); + vec3 c = gcu_ColorStatic.rgb; + + float alpha = 0.0; + + if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) { + alpha = gcu_Alpha; + } + else if((gcv_TexCoord.x >= 5.0)) { + rtex -= 5.0; + vec4 t = texture2D(gcu_TextureUnit, rtex); + + #if 0 + if(t.w == 0.0) { + discard; // discard freezes NV tegra2 compiler + } + #endif + + c = t.xyz; + alpha = gcu_Alpha * t.w; + } + else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) { + rtex.y -= 0.1; + + if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) { + // discard; // freezes NV tegra2 compiler + alpha = 0.0; + } else { + rtex.y = max(rtex.y, 0.0); + + vec2 dtx = dFdx(rtex); + vec2 dty = dFdy(rtex); + + vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); + float position = rtex.y - (rtex.x * (1.0 - rtex.x)); + + float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); + alpha = gcu_Alpha * a; + } + } + + mgl_FragColor = vec4(c, alpha); +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp index e60556bc6..c048254df 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp @@ -28,9 +28,6 @@ void main (void) alpha = gcu_Alpha;
}
else if((gcv_TexCoord.x >= 5.0)) {
- vec2 dfx = dFdx(gcv_TexCoord);
- vec2 dfy = dFdy(gcv_TexCoord);
-
vec2 size = 1.0/gcu_TextureSize;
rtex -= 5.0;
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp index 0cf4cf88f..0e590a102 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp @@ -23,15 +23,11 @@ void main (void) vec3 c = gcu_ColorStatic.rgb; float alpha = 0.0; - float enable = 1.0; if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) { alpha = gcu_Alpha; } else if((gcv_TexCoord.x >= 5.0)) { - vec2 dfx = dFdx(gcv_TexCoord); - vec2 dfy = dFdy(gcv_TexCoord); - vec2 size = 1.0/gcu_TextureSize; rtex -= 5.0; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java index 0377739fe..0a1fa7ec9 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java @@ -41,8 +41,8 @@ import javax.media.opengl.GLProfile; import javax.media.opengl.GLRunnable; import org.junit.Assert; -import org.junit.Test; import org.junit.FixMethodOrder; +import org.junit.Test; import org.junit.runners.MethodSorters; import com.jogamp.common.os.Platform; @@ -69,8 +69,9 @@ public class TestTextRendererNEWT00 extends UITestCase { static long Duration = 2000; // ms static boolean WaitStartEnd = false; static boolean TextAnim = false; - static int MSAASamples = 4; - static int VBAASamples = 4; + static int SceneMSAASamples = 4; + static int GraphVBAASamples = 4; + static int GraphMSAASamples = 4; static int SwapInterval = 0; static String fontFileName = null; @@ -105,14 +106,21 @@ public class TestTextRendererNEWT00 extends UITestCase { } else if(args[i].equals("-fontSize")) { i++; fontSizeFixed = atoi(args[i]); - } else if(args[i].equals("-msaa")) { + } else if(args[i].equals("-smsaa")) { + i++; + SceneMSAASamples = atoi(args[i]); + GraphMSAASamples = 0; + GraphVBAASamples = 0; + } else if(args[i].equals("-gmsaa")) { i++; - MSAASamples = atoi(args[i]); - VBAASamples = 0; - } else if(args[i].equals("-vbaa")) { + SceneMSAASamples = 0; + GraphMSAASamples = atoi(args[i]); + GraphVBAASamples = 0; + } else if(args[i].equals("-gvbaa")) { i++; - VBAASamples = atoi(args[i]); - MSAASamples = 0; + SceneMSAASamples = 0; + GraphMSAASamples = 0; + GraphVBAASamples = atoi(args[i]); } else if(args[i].equals("-textAnim")) { TextAnim = true; } else if(args[i].equals("-vsync")) { @@ -123,8 +131,9 @@ public class TestTextRendererNEWT00 extends UITestCase { } } System.err.println("Font [set "+fontSet+", family "+fontFamily+", style "+fontStylebits+", size "+fontSizeFixed+"], fontFileName "+fontFileName); - System.err.println("msaaSamples "+MSAASamples); - System.err.println("vbaaSamples "+VBAASamples); + System.err.println("Scene MSAA Samples "+SceneMSAASamples); + System.err.println("Graph MSAA Samples "+GraphMSAASamples); + System.err.println("Graph VBAA Samples "+GraphVBAASamples); System.err.println("swapInterval "+SwapInterval); String tstname = TestTextRendererNEWT00.class.getName(); org.junit.runner.JUnitCore.main(tstname); @@ -157,29 +166,35 @@ public class TestTextRendererNEWT00 extends UITestCase { } @Test - public void testTextRendererMSAA01() throws InterruptedException { - if( MSAASamples > 0 ) { - testTextRendererImpl(MSAASamples, 0); + public void test01SceneMSAA01() throws InterruptedException { + if( SceneMSAASamples > 0 ) { + testImpl(SceneMSAASamples, 0, 0); } } @Test - public void testTextRendererVBAA01() throws InterruptedException { - if( VBAASamples > 0 ) { - testTextRendererImpl(0, VBAASamples); + public void test02GraphMSAA01() throws InterruptedException { + if( GraphMSAASamples > 0 ) { + testImpl(0, GraphMSAASamples, 0); + } + } + @Test + public void test03GraphVBAA01() throws InterruptedException { + if( GraphVBAASamples > 0 ) { + testImpl(0, 0, GraphVBAASamples); } } - public void testTextRendererImpl(final int msaaSamples, final int vbaaSampleCount) throws InterruptedException { + public void testImpl(final int sceneMSAASamples, final int graphMSAASamples, final int graphVBAASamples) throws InterruptedException { GLProfile glp = GLProfile.get(GLProfile.GL2ES2); GLCapabilities caps = new GLCapabilities(glp); caps.setAlphaBits(4); - if( 0 < msaaSamples ) { + if( 0 < sceneMSAASamples ) { caps.setSampleBuffers(true); - caps.setNumSamples(msaaSamples); + caps.setNumSamples(sceneMSAASamples); } - System.err.println("Requested: "+caps+", vbaaSamples "+vbaaSampleCount); + System.err.println("Requested: "+caps+", graph[msaaSamples "+graphMSAASamples+", vbaaSamples "+graphVBAASamples+"]"); - GLWindow window = createWindow("text-vbaa"+vbaaSampleCount+"-msaa"+msaaSamples, caps, 1024, 640); + GLWindow window = createWindow("text-gvbaa"+graphVBAASamples+"-gmsaa"+graphMSAASamples+"-smsaa"+sceneMSAASamples, caps, 1024, 640); window.display(); System.err.println("Chosen: "+window.getChosenGLCapabilities()); if( WaitStartEnd ) { @@ -187,7 +202,18 @@ public class TestTextRendererNEWT00 extends UITestCase { } final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); - final TextRendererGLEL textGLListener = new TextRendererGLEL(rs, vbaaSampleCount>0 ? Region.VBAA_RENDERING_BIT:0, vbaaSampleCount); + final int rendererMode, sampleCount; + if( graphVBAASamples > 0 ) { + rendererMode = Region.VBAA_RENDERING_BIT; + sampleCount = graphVBAASamples; + } else if ( graphMSAASamples > 0 ) { + rendererMode = Region.MSAA_RENDERING_BIT; + sampleCount = graphMSAASamples; + } else { + rendererMode = 0; + sampleCount = 0; + } + final TextRendererGLEL textGLListener = new TextRendererGLEL(rs, rendererMode, sampleCount); System.err.println(textGLListener.getFontInfo()); window.addGLEventListener(textGLListener); @@ -280,6 +306,8 @@ public class TestTextRendererNEWT00 extends UITestCase { System.err.println(getFontInfo()); System.err.println("fontSize "+fontSizeFixed+", dotsPerMM "+pixelsPerMM[0]+"x"+pixelsPerMM[1]+", dpi "+dotsPerInch[0]+"x"+dotsPerInch[1]+", pixelSize "+font.getPixelSize(fontSizeFixed, dotsPerInch[1] /* dpi display */)); } + + @Override public void dispose(GLAutoDrawable drawable) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); screenshot.dispose(gl); @@ -289,9 +317,10 @@ public class TestTextRendererNEWT00 extends UITestCase { } public void printScreen(GLAutoDrawable drawable, String dir, String objName, boolean exportAlpha) throws GLException, IOException { - final String bname = String.format("%s-msaa%02d-fontsz%02.1f-%03dx%03d-T%04d", objName, + final String modeS = Region.getRenderModeString(renderer.getRenderModes()); + final String bname = String.format("%s-msaa%02d-fontsz%02.1f-%03dx%03d-%s%04d", objName, drawable.getChosenGLCapabilities().getNumSamples(), - TestTextRendererNEWT00.fontSizeFixed, drawable.getWidth(), drawable.getHeight(), vbaaSampleCount[0]); + TestTextRendererNEWT00.fontSizeFixed, drawable.getWidth(), drawable.getHeight(), modeS, vbaaSampleCount[0]); final String filename = dir + bname +".png"; if(screenshot.readPixels(drawable.getGL(), false)) { screenshot.write(new File(filename)); @@ -332,17 +361,18 @@ public class TestTextRendererNEWT00 extends UITestCase { final float pixelSize = font.getPixelSize(fontSizeFixed, dpiH); final float pixelSizeAnim = font.getPixelSize(fontSizeAnim, dpiH); - final String text1 = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, vba-samples %d", + final String modeS = Region.getRenderModeString(renderer.getRenderModes()); + final String text1 = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, %s-samples %d", lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0, fontSizeFixed, - drawable.getChosenGLCapabilities().getNumSamples(), vbaaSampleCount[0]); - final String text1A = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, vba-samples %d", + drawable.getChosenGLCapabilities().getNumSamples(), modeS, vbaaSampleCount[0]); + final String text1A = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, %s-samples %d", lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0, fontSizeAnim, - drawable.getChosenGLCapabilities().getNumSamples(), vbaaSampleCount[0]); + drawable.getChosenGLCapabilities().getNumSamples(), modeS, vbaaSampleCount[0]); if( false ) { - renderString(drawable, font, pixelSize, getFontInfo(), 0, 0, 0, 0, -1000f, true); - renderString(drawable, font, pixelSize, textX2, 0, 0, 0, -1000f, true); - renderString(drawable, font, pixelSize, text1, 0, 0, 0, -1000f, false); // no-cache + // renderString(drawable, font, pixelSize, getFontInfo(), 0, 0, 0, 0, -1000f, true); + renderString(drawable, font, pixelSize, textX2, 0, 0, 0, 0, -1000f, true); + // renderString(drawable, font, pixelSize, text1, 0, 0, 0, -1000f, regionFPS); // no-cache } else { renderString(drawable, font, pixelSize, getFontInfo(), 0, 0, 0, 0, -1000, true); renderString(drawable, font, pixelSize, "012345678901234567890123456789", 0, 0, 0, -1000, true); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java index d002de5e9..075d8c5e8 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java @@ -42,6 +42,7 @@ import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.font.FontSet; import com.jogamp.graph.geom.SVertex; +import com.jogamp.newt.Window; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderState; @@ -68,6 +69,9 @@ public abstract class TextRendererGLELBase implements GLEventListener { /** scale pixel, default is 1f */ protected float pixelScale = 1.0f; + /** dpi display resolution, queried at {@link #init(GLAutoDrawable)} if NEWT, otherwise 96. */ + protected float dpiH = 96; + boolean flipVerticalInGLOrientation = false; /** @@ -126,6 +130,13 @@ public abstract class TextRendererGLELBase implements GLEventListener { renderer.setColorStatic(gl, staticRGBAColor[0], staticRGBAColor[1], staticRGBAColor[2]); final ShaderState st = rs.getShaderState(); st.useProgram(gl, false); + + final Object upObj = drawable.getUpstreamWidget(); + if( upObj instanceof Window ) { + final float[] pixelsPerMM = new float[2]; + ((Window)upObj).getMainMonitor().getPixelsPerMM(pixelsPerMM); + dpiH = pixelsPerMM[1]*25.4f; + } } @Override diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java index 8520b6dfd..701a6fd92 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java @@ -285,7 +285,8 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { @Override public boolean run(GLAutoDrawable drawable) { try { - final String type = Region.isVBAA(renderModes) ? "vbaa0-msaa1" : "vbaa1-msaa0" + ( Region.isNonUniformWeight(renderModes) ? "-vc" : "-uc" ) ; + final String modeS = Region.getRenderModeString(renderer.getRenderModes()); + final String type = modeS + ( Region.isNonUniformWeight(renderModes) ? "-vc" : "-uc" ) ; printScreen(drawable, "./", "demo-"+type, "snap"+screenshot_num, false); screenshot_num++; } catch (GLException e) { diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java index 3253b3bc2..d39a80eb9 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java @@ -56,7 +56,7 @@ public class GPUTextNewtDemo01 { final GLWindow window = GLWindow.create(caps); window.setPosition(10, 10); window.setSize(800, 400); - window.setTitle("GPU Text Newt Demo 01 - vbaa0 msaa1"); + window.setTitle("GPU Text Newt Demo 01 - smsaa1"); final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); GPUTextGLListener0A textGLListener = new GPUTextGLListener0A(rs, 0, 0, DEBUG, TRACE); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java index 7b8839d29..25635314f 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java @@ -66,7 +66,7 @@ public class GPUTextNewtDemo02 { window.setPosition(10, 10); window.setSize(800, 400); - window.setTitle("GPU Text Newt Demo 02 - vbaa1 msaa0"); + window.setTitle("GPU Text Newt Demo 02 - gvbaa4 gmsaa0"); RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); GPUTextGLListener0A textGLListener = new GPUTextGLListener0A(rs, Region.VBAA_RENDERING_BIT, 4, DEBUG, TRACE); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo03.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo03.java new file mode 100644 index 000000000..97334311a --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo03.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.graph.demos; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.RenderState; +import com.jogamp.graph.geom.SVertex; +import com.jogamp.newt.event.KeyAdapter; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class GPUTextNewtDemo03 { + /** + * FIXME: + * + * If DEBUG is enabled: + * + * Caused by: javax.media.opengl.GLException: Thread[main-Display-X11_:0.0-1-EDT-1,5,main] glGetError() returned the following error codes after a call to glFramebufferRenderbuffer(<int> 0x8D40, <int> 0x1902, <int> 0x8D41, <int> 0x1): GL_INVALID_ENUM ( 1280 0x500), + * at javax.media.opengl.DebugGL4bc.checkGLGetError(DebugGL4bc.java:33961) + * at javax.media.opengl.DebugGL4bc.glFramebufferRenderbuffer(DebugGL4bc.java:33077) + * at jogamp.graph.curve.opengl.VBORegion2PGL3.initFBOTexture(VBORegion2PGL3.java:295) + */ + static final boolean DEBUG = false; + static final boolean TRACE = false; + + public static void main(String[] args) { + GLProfile glp = GLProfile.getGL2ES2(); + + GLCapabilities caps = new GLCapabilities(glp); + caps.setAlphaBits(4); + System.out.println("Requested: "+caps); + + final GLWindow window = GLWindow.create(caps); + + window.setPosition(10, 10); + window.setSize(800, 400); + window.setTitle("GPU Text Newt Demo 02 - gvbaa0 gmsaa4"); + + RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); + GPUTextGLListener0A textGLListener = new GPUTextGLListener0A(rs, Region.MSAA_RENDERING_BIT, 4, DEBUG, TRACE); + // ((TextRenderer)textGLListener.getRenderer()).setCacheLimit(32); + window.addGLEventListener(textGLListener); + window.setVisible(true); + // FPSAnimator animator = new FPSAnimator(60); + final Animator animator = new Animator(); + animator.setUpdateFPSFrames(60, System.err); + animator.add(window); + + window.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent arg0) { + if(arg0.getKeyCode() == KeyEvent.VK_F4) { + window.destroy(); + } + } + }); + window.addWindowListener(new WindowAdapter() { + public void windowDestroyed(WindowEvent e) { + animator.stop(); + } + }); + + animator.start(); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java index 3126517d3..e5eca2360 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java @@ -35,6 +35,7 @@ import javax.media.opengl.GLAnimatorControl; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLException; +import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; @@ -203,8 +204,9 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB tfps = 0f; td = 0f; } - final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize [head %.1f, bottom %.1f], sampleCount %d, td %4.1f", - lfps, tfps, gl.getSwapInterval(), fontSizeHead, fontSizeBottom, getSampleCount()[0], td); + final String modeS = Region.getRenderModeString(renderer.getRenderModes()); + final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize [head %.1f, bottom %.1f], %s-samples %d, td %4.1f", + lfps, tfps, gl.getSwapInterval(), fontSizeHead, fontSizeBottom, modeS, getSampleCount()[0], td); renderer.resetModelview(null); renderer.translate(gl, 0, pixelSizeFPS/2, -6000); // bottom, half line up diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java index 5de2e95a7..1a81204d6 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java @@ -77,7 +77,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { public GPUUISceneGLListener0A(RenderState rs, int renderModes, boolean debug, boolean trace) { this.rs = rs; this.renderModes = renderModes; - this.sampleCount[0] = Region.isVBAA(renderModes) ? 4 : 0; + this.sampleCount[0] = 4; this.renderModes2 = 0; this.texSize2[0] = 0; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java index c8e2acef3..8c4cfd4b3 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java @@ -41,6 +41,7 @@ import org.junit.Test; import org.junit.runners.MethodSorters; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.font.Font; import com.jogamp.opengl.test.junit.graph.TextRendererGLELBase; import com.jogamp.opengl.test.junit.util.UITestCase; @@ -55,10 +56,12 @@ public abstract class GLReadBuffer00Base extends UITestCase { final Font font = getFont(0, 0, 0); public int frameNo = 0; public int userCounter = 0; + private final GLRegion regionFPS; public TextRendererGLEL() { // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO super(Region.VBAA_RENDERING_BIT, new int[] { 4 }); + regionFPS = GLRegion.create(usrRenderModes); staticRGBAColor[0] = 1.0f; staticRGBAColor[1] = 1.0f; @@ -67,11 +70,17 @@ public abstract class GLReadBuffer00Base extends UITestCase { } @Override + public void dispose(GLAutoDrawable drawable) { + regionFPS.destroy(drawable.getGL().getGL2ES2(), renderer); + super.dispose(drawable); + } + + @Override public void display(GLAutoDrawable drawable) { final String text = String.format("Frame %04d (%03d): %04dx%04d", frameNo, userCounter, drawable.getWidth(), drawable.getHeight()); System.err.println("TextRendererGLEL.display: "+text); if( null != renderer ) { - renderString(drawable, font, 24f, text, 0 /* col */, 0 /* row */, 0, 0, -1, false); + renderString(drawable, font, 24f, text, 0 /* col */, 0 /* row */, 0, 0, -1, regionFPS); } else { System.err.println(text); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java index d2f2edec6..bc3786b81 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java @@ -43,6 +43,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.common.util.IOUtil; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.font.Font; import com.jogamp.newt.Window; import com.jogamp.newt.event.KeyAdapter; @@ -159,24 +160,17 @@ public class MovieCube implements GLEventListener { final int[] textSampleCount = { 4 }; private final class InfoTextRendererGLELBase extends TextRendererGLELBase { - static final float z_diff = 0.001f; - final Font font = getFont(0, 0, 0); - final float underlineSize; - final float fontSize; + private static final float z_diff = 0.001f; + private final Font font = getFont(0, 0, 0); + private final float fontSize = 12; + private final GLRegion regionFPS; + private float pixelSize, underlineSize; InfoTextRendererGLELBase() { // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO super(Region.VBAA_RENDERING_BIT, MovieCube.this.textSampleCount); - - fontSize = 1; - pixelScale = 1.0f / ( fontSize * 20f ); - - // underlineSize: 'underline' amount of pixel below 0/0 (Note: lineGap is negative) - final Font.Metrics metrics = font.getMetrics(); - final float lineGap = metrics.getLineGap(fontSize); - final float descent = metrics.getDescent(fontSize); - underlineSize = descent - lineGap; - // System.err.println("XXX: fLG "+lineGap+", fDesc "+descent+", underlineSize "+underlineSize); + regionFPS = GLRegion.create(usrRenderModes); + System.err.println("RegionFPS "+Region.getRenderModeString(usrRenderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); staticRGBAColor[0] = 0.0f; staticRGBAColor[1] = 0.0f; @@ -189,6 +183,21 @@ public class MovieCube implements GLEventListener { // non-exclusive mode! this.usrPMVMatrix = cube.pmvMatrix; super.init(drawable); + + pixelSize = font.getPixelSize(fontSize, dpiH); + pixelScale = 1.0f / ( pixelSize * 20f ); + // underlineSize: 'underline' amount of pixel below 0/0 (Note: lineGap is negative) + final Font.Metrics metrics = font.getMetrics(); + final float lineGap = metrics.getLineGap(pixelSize); + final float descent = metrics.getDescent(pixelSize); + underlineSize = descent - lineGap; + System.err.println("XXX: dpiH "+dpiH+", fontSize "+fontSize+", pixelSize "+pixelSize+", pixelScale "+pixelScale+", fLG "+lineGap+", fDesc "+descent+", underlineSize "+underlineSize); + } + + @Override + public void dispose(GLAutoDrawable drawable) { + regionFPS.destroy(drawable.getGL().getGL2ES2(), renderer); + super.dispose(drawable); } @Override @@ -228,10 +237,10 @@ public class MovieCube implements GLEventListener { mPlayer.getVID(), mPlayer.getVideoBitrate()/1000, mPlayer.getVideoCodec()); final String text4 = mPlayer.getURI().getRawPath(); if( displayOSD && null != renderer ) { - renderString(drawable, font, fontSize, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, false); - renderString(drawable, font, fontSize, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); - renderString(drawable, font, fontSize, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); - renderString(drawable, font, fontSize, text4, 1 /* col */, 2 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); + renderString(drawable, font, pixelSize, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS); // no-cache + renderString(drawable, font, pixelSize, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); + renderString(drawable, font, pixelSize, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); + renderString(drawable, font, pixelSize, text4, 1 /* col */, 2 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); } } }; private final InfoTextRendererGLELBase textRendererGLEL = new InfoTextRendererGLELBase(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java index 5c8a62b14..ab159fb85 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java @@ -49,6 +49,7 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.common.os.Platform; import com.jogamp.common.util.IOUtil; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.font.Font; import com.jogamp.newt.Window; import com.jogamp.newt.event.KeyAdapter; @@ -134,11 +135,15 @@ public class MovieSimple implements GLEventListener { final int[] textSampleCount = { 4 }; private final class InfoTextRendererGLELBase extends TextRendererGLELBase { - final Font font = getFont(0, 0, 0); - final float fontSize = 18f; + private final Font font = getFont(0, 0, 0); + private final float fontSize = 12f; + private final GLRegion regionFPS; + InfoTextRendererGLELBase() { // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO super(Region.VBAA_RENDERING_BIT, textSampleCount); + regionFPS = GLRegion.create(usrRenderModes); + System.err.println("RegionFPS "+Region.getRenderModeString(usrRenderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); staticRGBAColor[0] = 1.0f; staticRGBAColor[1] = 1.0f; @@ -147,6 +152,17 @@ public class MovieSimple implements GLEventListener { } @Override + public void init(GLAutoDrawable drawable) { + super.init(drawable); + } + + @Override + public void dispose(GLAutoDrawable drawable) { + regionFPS.destroy(drawable.getGL().getGL2ES2(), renderer); + super.dispose(drawable); + } + + @Override public void display(GLAutoDrawable drawable) { final GLAnimatorControl anim = drawable.getAnimator(); final float lfps = null != anim ? anim.getLastFPS() : 0f; @@ -170,10 +186,11 @@ public class MovieSimple implements GLEventListener { mPlayer.getVID(), mPlayer.getVideoBitrate()/1000, mPlayer.getVideoCodec()); final String text4 = mPlayer.getURI().getRawPath(); if( displayOSD && null != renderer ) { - renderString(drawable, font, fontSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, false); - renderString(drawable, font, fontSize, text2, 1 /* col */, -4 /* row */, 0, height, -1, true); - renderString(drawable, font, fontSize, text3, 1 /* col */, -3 /* row */, 0, height, -1, true); - renderString(drawable, font, fontSize, text4, 1 /* col */, -2 /* row */, 0, height, -1, true); + final float pixelSize = font.getPixelSize(fontSize, dpiH); + renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS); // no-cache + renderString(drawable, font, pixelSize, text2, 1 /* col */, -4 /* row */, 0, height, -1, true); + renderString(drawable, font, pixelSize, text3, 1 /* col */, -3 /* row */, 0, height, -1, true); + renderString(drawable, font, pixelSize, text4, 1 /* col */, -2 /* row */, 0, height, -1, true); } } }; private final InfoTextRendererGLELBase textRendererGLEL = new InfoTextRendererGLELBase(); |