diff options
author | Sven Gothel <[email protected]> | 2014-03-14 08:13:42 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-14 08:13:42 +0100 |
commit | e16e974a3e2b38c65355838eeb010954354097d2 (patch) | |
tree | e1582436012d80ffddb5a81e6056a5aaa4e7368b /src | |
parent | 70979247aad156418c32959bbf4962f175191ec2 (diff) |
Bug 801: Add Frustum support to Region; Misc ..
Region: Add Frustum support, to drop 'out of sight' shapes
RenderState: Add hints, e.g. BITHINT_BLENDING_ENABLED,
allowing user code to toggle background color etc
Demos: Incomplete - WIP
- Reuse mapped object to window coords computed at reshape
- TODO: Use minimal Scenegraph for Graph-UI ..
Diffstat (limited to 'src')
19 files changed, 586 insertions, 284 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index 8e68b7913..853c837f5 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -30,22 +30,20 @@ package com.jogamp.graph.curve; import java.util.ArrayList; import java.util.List; -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; -import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.math.geom.Frustum; /** * Abstract Outline shape representation define the method an OutlineShape(s) * is bound and rendered. * - * @see GLRegion */ + * @see com.jogamp.graph.curve.opengl.GLRegion + */ public abstract class Region { /** Debug flag for region impl (graph.curve) */ @@ -53,25 +51,34 @@ public abstract class Region { public static final boolean DEBUG_INSTANCE = Debug.debug("graph.curve.instance"); /** + * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * <p> * 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. + * </p> */ - public static final int MSAA_RENDERING_BIT = 1 << 0; + public static final int MSAA_RENDERING_BIT = 1 << 0; /** + * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * <p> * 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. + * </p> */ - public static final int VBAA_RENDERING_BIT = 1 << 1; + public static final int VBAA_RENDERING_BIT = 1 << 1; /** + * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * <p> * 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. + * </p> */ - public static final int VARIABLE_CURVE_WEIGHT_BIT = 1 << 8; + public static final int VARIABLE_CURVE_WEIGHT_BIT = 1 << 8; public static final int TWO_PASS_DEFAULT_TEXTURE_UNIT = 0; @@ -79,6 +86,7 @@ public abstract class Region { private boolean dirty = true; private int numVertices = 0; protected final AABBox box = new AABBox(); + protected Frustum frustum = null; public static boolean isVBAA(int renderModes) { return 0 != (renderModes & Region.VBAA_RENDERING_BIT); @@ -86,15 +94,6 @@ public abstract class Region { 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 @@ -108,22 +107,14 @@ public abstract class Region { return 0 != (renderModes & Region.VARIABLE_CURVE_WEIGHT_BIT); } - /** - * Create a Region using the passed render mode - * - * <p> In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit - * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.</p> - * - * @param rs the RenderState to be used - * @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( 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); + public static String getRenderModeString(int renderModes) { + final String curveS = isNonUniformWeight(renderModes) ? "-curve" : ""; + if( Region.isVBAA(renderModes) ) { + return "vbaa"+curveS; + } else if( Region.isMSAA(renderModes) ) { + return "msaa"+curveS; } else { - return new VBORegionSPES2(renderModes); + return "norm"+curveS; } } @@ -170,6 +161,16 @@ public abstract class Region { return Region.isNonUniformWeight(renderModes); } + /** See {@link #setFrustum(Frustum)} */ + public final Frustum getFrustum() { return frustum; } + + /** + * Set {@link Frustum} culling for {@link #addOutlineShape(OutlineShape, AffineTransform)}. + */ + public final void setFrustum(Frustum frustum) { + this.frustum = frustum; + } + final float[] coordsEx = new float[3]; private void pushNewVertexImpl(final Vertex vertIn, final AffineTransform transform) { @@ -191,7 +192,33 @@ public abstract class Region { pushNewVertexImpl(vertIn, transform); } + private final AABBox tmpBox = new AABBox(); + + /** + * Add the given {@link OutlineShape} to this region with the given optional {@link AffineTransform}. + * <p> + * In case {@link #setFrustum(Frustum) frustum culling is set}, the {@link OutlineShape} + * is dropped if it's {@link OutlineShape#getBounds() bounding-box} is fully outside of the frustum. + * The optional {@link AffineTransform} is applied to the bounding-box beforehand. + * </p> + */ public final void addOutlineShape(final OutlineShape shape, final AffineTransform transform) { + if( null != frustum ) { + final AABBox shapeBox = shape.getBounds(); + final AABBox shapeBoxT; + if( null != transform ) { + transform.transform(shapeBox, tmpBox); + shapeBoxT = tmpBox; + } else { + shapeBoxT = shapeBox; + } + if( frustum.isAABBoxOutside(shapeBoxT) ) { + if(DEBUG_INSTANCE) { + System.err.println("Region.addOutlineShape(): Dropping outside shapeBoxT: "+shapeBoxT); + } + return; + } + } final List<Triangle> trisIn = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS); final ArrayList<Vertex> vertsIn = shape.getVertices(); if(DEBUG_INSTANCE) { @@ -277,4 +304,8 @@ public abstract class Region { protected final void setDirty(boolean v) { dirty = v; } + + public String toString() { + return "Region["+getRenderModeString(this.renderModes)+", dirty "+dirty+", vertices "+numVertices+", box "+box+"]"; + } }
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java index defb7722a..96d285898 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java @@ -30,6 +30,10 @@ package com.jogamp.graph.curve.opengl; import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
+import jogamp.graph.curve.opengl.VBORegion2PMSAAES2;
+import jogamp.graph.curve.opengl.VBORegion2PVBAAES2;
+import jogamp.graph.curve.opengl.VBORegionSPES2;
+
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.graph.curve.Region;
@@ -55,7 +59,13 @@ public abstract class GLRegion extends 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) {
- return Region.create(renderModes);
+ 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);
+ }
}
protected GLRegion(int renderModes) {
@@ -68,7 +78,7 @@ public abstract class GLRegion extends Region { * <p>Allocates the ogl related data and initializes it the 1st time.<p>
* <p>Called by {@link #draw(GL2ES2, RenderState, int, int, int)}.</p>
*/
- protected abstract void update(GL2ES2 gl, RegionRenderer renderer);
+ protected abstract void updateImpl(GL2ES2 gl, RegionRenderer renderer);
protected abstract void destroyImpl(GL2ES2 gl, RegionRenderer renderer);
@@ -121,7 +131,7 @@ public abstract class GLRegion extends Region { */
public final void draw(GL2ES2 gl, RegionRenderer renderer, int[/*1*/] sampleCount) {
if(isDirty()) {
- update(gl, renderer);
+ updateImpl(gl, renderer);
setDirty(false);
}
drawImpl(gl, renderer, sampleCount);
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java index 1f6e532d3..bff7c905f 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -62,27 +62,35 @@ public abstract class RegionRenderer { * Default {@link GL#GL_BLEND} <i>enable</i> {@link GLCallback}, * turning on the {@link GL#GL_BLEND} state and setting up * {@link GL#glBlendFunc(int, int) glBlendFunc}({@link GL#GL_SRC_ALPHA}, {@link GL#GL_ONE_MINUS_SRC_ALPHA}). - * @see #setEnableCallback(GLCallback, GLCallback) + * <p> + * Implementation also sets {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}. + * </p> + * @see #create(RenderState, int, GLCallback, GLCallback) * @see #enable(GL2ES2, boolean) */ public static final GLCallback defaultBlendEnable = new GLCallback() { @Override - public void run(final GL gl, final RegionRenderer args) { + public void run(final GL gl, final RegionRenderer renderer) { gl.glEnable(GL.GL_BLEND); gl.glBlendEquation(GL.GL_FUNC_ADD); // default gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + renderer.rs.setHintBits(RenderState.BITHINT_BLENDING_ENABLED); } }; /** * Default {@link GL#GL_BLEND} <i>disable</i> {@link GLCallback}, * simply turning off the {@link GL#GL_BLEND} state. - * @see #setEnableCallback(GLCallback, GLCallback) + * <p> + * Implementation also clears {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}. + * </p> + * @see #create(RenderState, int, GLCallback, GLCallback) * @see #enable(GL2ES2, boolean) */ public static final GLCallback defaultBlendDisable = new GLCallback() { @Override - public void run(final GL gl, final RegionRenderer args) { + public void run(final GL gl, final RegionRenderer renderer) { + renderer.rs.clearHintBits(RenderState.BITHINT_BLENDING_ENABLED); gl.glDisable(GL.GL_BLEND); } }; @@ -287,7 +295,7 @@ public abstract class RegionRenderer { } - public final void getColorStatic(GL2ES2 gl, float[] rgb) { + public final void getColorStatic(float[] rgb) { FloatBuffer fb = (FloatBuffer) rs.getColorStatic().getBuffer(); rgb[0] = fb.get(0); rgb[1] = fb.get(1); diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java index 9b0f32ef6..d6eac19de 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java @@ -27,6 +27,7 @@ */ package com.jogamp.graph.curve.opengl; +import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import javax.media.opengl.GLUniformData; @@ -34,6 +35,7 @@ import jogamp.graph.curve.opengl.RenderStateImpl; import jogamp.graph.curve.opengl.shader.UniformNames; import com.jogamp.common.os.Platform; +import com.jogamp.graph.curve.Region; import com.jogamp.graph.geom.Vertex; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderState; @@ -41,6 +43,25 @@ import com.jogamp.opengl.util.glsl.ShaderState; public abstract class RenderState { private static final String thisKey = "jogamp.graph.curve.RenderState" ; + /** + * Bitfield hint, {@link #isHintBitSet(int) if set} + * stating <i>enabled</i> {@link GL#GL_BLEND}, otherwise <i>disabled</i>. + * <p> + * Shall be set via {@link #setHintBits(int)} and cleared via {@link #clearHintBits(int)}. + * </p> + * <p> + * Due to alpha blending and multipass rendering, e.g. {@link Region#VBAA_RENDERING_BIT}, + * the clear-color shall be set to the {@link #getColorStatic() foreground color} and <i>zero alpha</i>, + * otherwise blending will amplify the scene's clear-color. + * </p> + * <p> + * Shall be called by custom code, e.g. via {@link RegionRenderer}'s + * enable and disable {@link RegionRenderer.GLCallback} as done in + * {@link RegionRenderer#defaultBlendEnable} and {@link RegionRenderer#defaultBlendDisable}. + * </p> + */ + public static final int BITHINT_BLENDING_ENABLED = 1 << 0 ; + public static RenderState createRenderState(ShaderState st, Vertex.Factory<? extends Vertex> pointFactory) { return new RenderStateImpl(st, pointFactory, null); } @@ -57,6 +78,7 @@ public abstract class RenderState { protected final Vertex.Factory<? extends Vertex> vertexFactory; protected final PMVMatrix pmvMatrix; protected final GLUniformData gcu_PMVMatrix; + protected int hintBitfield; protected RenderState(ShaderState st, Vertex.Factory<? extends Vertex> vertexFactory, PMVMatrix pmvMatrix) { this.st = st; @@ -64,6 +86,7 @@ public abstract class RenderState { this.pmvMatrix = null != pmvMatrix ? pmvMatrix : new PMVMatrix(); this.gcu_PMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, this.pmvMatrix.glGetPMvMatrixf()); st.ownUniform(gcu_PMVMatrix); + this.hintBitfield = 0; } public final ShaderState getShaderState() { return st; } @@ -71,6 +94,16 @@ public abstract class RenderState { public final PMVMatrix pmvMatrix() { return pmvMatrix; } public final GLUniformData getPMVMatrix() { return gcu_PMVMatrix; } + public final boolean isHintBitSet(int mask) { + return mask == ( hintBitfield & mask ); + } + public final void setHintBits(int mask) { + hintBitfield |= mask; + } + public final void clearHintBits(int mask) { + hintBitfield &= ~mask; + } + public void destroy(GL2ES2 gl) { st.destroy(gl); } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java index 176b39c25..4aeceea7e 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -111,7 +111,7 @@ public class VBORegion2PMSAAES2 extends GLRegion { } @Override - protected void update(final GL2ES2 gl, final RegionRenderer renderer) { + protected void updateImpl(final GL2ES2 gl, final RegionRenderer renderer) { if(null == indicesFbo) { final ShaderState st = renderer.getShaderState(); @@ -137,7 +137,7 @@ public class VBORegion2PMSAAES2 extends GLRegion { st.ownAttribute(texCoordTxtAttr, true); if(Region.DEBUG_INSTANCE) { - System.err.println("VBORegion2PES2 Create: " + this); + System.err.println("VBORegion2PMSAAES2 Create: " + this); } } // seal buffers @@ -178,6 +178,18 @@ public class VBORegion2PMSAAES2 extends GLRegion { @Override protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + if( 0 >= indicesTxtBuffer.getElementCount() ) { + if(DEBUG_INSTANCE) { + System.err.printf("VBORegion2PMSAAES2.drawImpl: Empty%n"); + } + return; // empty! + } + if( Float.isInfinite(box.getWidth()) || Float.isInfinite(box.getHeight()) ) { + if(DEBUG_INSTANCE) { + System.err.printf("VBORegion2PMSAAES2.drawImpl: Inf %s%n", box); + } + return; // inf + } final int width = renderer.getWidth(); final int height = renderer.getHeight(); if(width <=0 || height <= 0 || null==sampleCount || sampleCount[0] <= 0){ @@ -209,6 +221,10 @@ public class VBORegion2PMSAAES2 extends GLRegion { diffWidth, diffHeight, sampleCount[0]); } } + if( 0 >= targetFboWidth || 0 >= targetFboHeight ) { + // Nothing .. + return; + } final int deltaFboWidth = Math.abs(targetFboWidth-fboWidth); final int deltaFboHeight = Math.abs(targetFboHeight-fboHeight); final int maxDeltaFbo, maxLengthFbo; diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java index 3f3709d6e..a760dcd33 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -112,7 +112,7 @@ public class VBORegion2PVBAAES2 extends GLRegion { } @Override - protected void update(final GL2ES2 gl, final RegionRenderer renderer) { + protected void updateImpl(final GL2ES2 gl, final RegionRenderer renderer) { if(null == indicesFbo) { final ShaderState st = renderer.getShaderState(); @@ -138,7 +138,7 @@ public class VBORegion2PVBAAES2 extends GLRegion { st.ownAttribute(texCoordTxtAttr, true); if(Region.DEBUG_INSTANCE) { - System.err.println("VBORegion2PES2 Create: " + this); + System.err.println("VBORegion2PVBAAES2 Create: " + this); } } // seal buffers @@ -179,6 +179,18 @@ public class VBORegion2PVBAAES2 extends GLRegion { @Override protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + if( 0 >= indicesTxtBuffer.getElementCount() ) { + if(DEBUG_INSTANCE) { + System.err.printf("VBORegion2PVBAAES2.drawImpl: Empty%n"); + } + return; // empty! + } + if( Float.isInfinite(box.getWidth()) || Float.isInfinite(box.getHeight()) ) { + if(DEBUG_INSTANCE) { + System.err.printf("VBORegion2PVBAAES2.drawImpl: Inf %s%n", box); + } + return; // inf + } final int width = renderer.getWidth(); final int height = renderer.getHeight(); if(width <=0 || height <= 0 || null==sampleCount || sampleCount[0] <= 0){ @@ -207,13 +219,19 @@ public class VBORegion2PVBAAES2 extends GLRegion { targetFboWidth = (int)Math.ceil(renderFboWidth); targetFboHeight = (int)Math.ceil(renderFboHeight); if( DEBUG_FBO_2 ) { - System.err.printf("XXX.MinMax1 view[%d, %d] -> win[%.3f, %.3f]: FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n", + System.err.printf("XXX.MinMax obj %s%n", box.toString()); + System.err.printf("XXX.MinMax win %s%n", drawWinBox.toString()); + System.err.printf("XXX.MinMax view[%d, %d] -> win[%.3f, %.3f]: FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n", drawView[2], drawView[3], winWidth, winHeight, renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight, diffWidth, diffHeight, sampleCount[0]); } } + if( 0 >= targetFboWidth || 0 >= targetFboHeight ) { + // Nothing .. + return; + } final int deltaFboWidth = Math.abs(targetFboWidth-fboWidth); final int deltaFboHeight = Math.abs(targetFboHeight-fboHeight); final int maxDeltaFbo, maxLengthFbo; diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index bdf824b6a..e45e623ba 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java @@ -81,7 +81,7 @@ public class VBORegionSPES2 extends GLRegion { } @Override - protected void update(final GL2ES2 gl, final RegionRenderer renderer) { + protected void updateImpl(final GL2ES2 gl, final RegionRenderer renderer) { if( !buffersAttached ) { final ShaderState st = renderer.getShaderState(); st.ownAttribute(verticeAttr, true); @@ -104,6 +104,12 @@ public class VBORegionSPES2 extends GLRegion { @Override protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + if( 0 >= indicesBuffer.getElementCount() ) { + if(DEBUG_INSTANCE) { + System.err.printf("VBORegionSPES2.drawImpl: Empty%n"); + } + return; // empty! + } verticeAttr.enableBuffer(gl, true); texCoordAttr.enableBuffer(gl, true); indicesBuffer.bindBuffer(gl, true); // keeps VBO binding diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 3cd9ab7c1..a75c5e02c 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -224,7 +224,7 @@ class TypecastFont implements Font { @Override public final float getPixelSize(float fontSize /* points per inch */, float resolution) { - return fontSize * resolution / ( 72 /* points per inch */ ); + return fontSize * resolution / ( 72f /* points per inch */ ); } @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 d5247eb51..03f04a752 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 @@ -48,7 +48,9 @@ import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.PMVMatrix; /** * @@ -77,7 +79,9 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { private final float[] position = new float[] {0,0,0}; protected final float zNear = 0.1f, zFar = 7000f; - + /** Describing the bounding box in model-coordinates of the near-plane parallel at distance one. */ + protected final AABBox nearPlane1Box; + private float xTran = -10; private float yTran = 10; private float ang = 0f; @@ -93,6 +97,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { this.debug = debug; this.trace = trace; this.screenshot = new GLReadBufferUtil(false, false); + nearPlane1Box = new AABBox(); } public final RegionRenderer getRenderer() { return renderer; } @@ -104,7 +109,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { public final int[] getSampleCount() { return sampleCount; } public final float[] getPosition() { return position; } - public void setMatrix(float xtrans, float ytrans, int zTran, float angle, int sampleCount) { + public void setMatrix(float xtrans, float ytrans, float zTran, float angle, int sampleCount) { this.xTran = xtrans; this.yTran = ytrans; this.zTran = zTran; @@ -129,12 +134,45 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { getRenderer().init(gl); } + public static void mapWin2ObjectCoords(final PMVMatrix pmv, final int[] view, + final float zNear, final float zFar, + float orthoX, float orthoY, float orthoDist, + final float[] winZ, final float[] objPos) { + winZ[0] = (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar); + pmv.gluUnProject(orthoX, orthoY, winZ[0], view, 0, objPos, 0); + } + @Override public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) { GL2ES2 gl = drawable.getGL().getGL2ES2(); - gl.glViewport(xstart, ystart, width, height); - renderer.reshapePerspective(gl, 45.0f, width, height, zNear, zFar); + final PMVMatrix pmv = renderer.getMatrix(); + renderer.reshapePerspective(null, 45.0f, width, height, zNear, zFar); + renderer.resetModelview(null); + renderer.updateMatrix(gl); + System.err.printf("Reshape: zNear %f, zFar %f%n", zNear, zFar); + System.err.printf("Reshape: Frustum: %s%n", pmv.glGetFrustum()); + { + final float orthoDist = 1f; + final float[] obj00Coord = new float[3]; + final float[] obj11Coord = new float[3]; + final float[] winZ = new float[1]; + final int[] view = new int[] { 0, 0, width, height }; + + mapWin2ObjectCoords(pmv, view, zNear, zFar, 0f, 0f, orthoDist, winZ, obj00Coord); + System.err.printf("Reshape: mapped.00: [%f, %f, %f], winZ %f -> [%f, %f, %f]%n", 0f, 0f, orthoDist, winZ[0], obj00Coord[0], obj00Coord[1], obj00Coord[2]); + + mapWin2ObjectCoords(pmv, view, zNear, zFar, width, height, orthoDist, winZ, obj11Coord); + System.err.printf("Reshape: mapped.11: [%f, %f, %f], winZ %f -> [%f, %f, %f]%n", (float)width, (float)height, orthoDist, winZ[0], obj11Coord[0], obj11Coord[1], obj11Coord[2]); + + nearPlane1Box.setSize( obj00Coord[0], // lx + obj00Coord[1], // ly + obj00Coord[2], // lz + obj11Coord[0], // hx + obj11Coord[1], // hy + obj11Coord[2] );// hz + System.err.printf("Reshape: dist1Box: %s%n", nearPlane1Box); + } dumpMatrix(); // System.err.println("Reshape: "+renderer.getRenderState()); 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 d77b0032d..4fceb4f2b 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 @@ -67,8 +67,7 @@ import com.jogamp.opengl.util.PMVMatrix; */ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerBase01 { public final TextRegionUtil textRegionUtil; - private final GLRegion regionFPS; - private final boolean useBlending; + private final GLRegion regionFPS, regionBottom; int fontSet = FontFactory.UBUNTU; Font font; @@ -117,9 +116,9 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB blending ? RegionRenderer.defaultBlendEnable : null, blending ? RegionRenderer.defaultBlendDisable : null), renderModes, debug, trace); - this.useBlending = blending; this.textRegionUtil = new TextRegionUtil(this.getRenderer()); this.regionFPS = GLRegion.create(renderModes); + this.regionBottom = GLRegion.create(renderModes); try { this.font = FontFactory.get(fontSet).getDefault(); dumpFontNames(); @@ -175,30 +174,28 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB } @Override + public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) { + super.reshape(drawable, xstart, ystart, width, height); + final float dist = 100f; + nearPlaneX0 = nearPlane1Box.getMinX() * dist; + nearPlaneY0 = nearPlane1Box.getMinY() * dist; + nearPlaneZ0 = nearPlane1Box.getMinZ() * dist; + final float xd = nearPlane1Box.getWidth() * dist; + final float yd = nearPlane1Box.getHeight() * dist; + nearPlaneSx = xd / width; + nearPlaneSy = yd / height; + nearPlaneS = nearPlaneSy; + System.err.printf("Scale: [%f x %f] / [%d x %d] = [%f, %f] -> %f%n", xd, yd, width, height, nearPlaneSx, nearPlaneSy, nearPlaneS); + } + float nearPlaneX0, nearPlaneY0, nearPlaneZ0, nearPlaneSx, nearPlaneSy, nearPlaneS; + + @Override public void dispose(GLAutoDrawable drawable) { regionFPS.destroy(drawable.getGL().getGL2ES2(), getRenderer()); + regionBottom.destroy(drawable.getGL().getGL2ES2(), getRenderer()); super.dispose(drawable); } - public static void mapWin2ObjectCoords(final PMVMatrix pmv, final int[] view, - final float zNear, final float zFar, - float orthoX, float orthoY, float orthoDist, - final float[] winZ, final float[] objPos) { - winZ[0] = (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar); - pmv.gluUnProject(orthoX, orthoY, winZ[0], view, 0, objPos, 0); - } - public static void translateOrtho(final String msg, - final PMVMatrix pmv, final int[] view, - final float zNear, final float zFar, - float orthoX, float orthoY, float orthoDist, - final float[] winZ, final float[] objPos) { - mapWin2ObjectCoords(pmv, view, zNear, zFar, orthoX, orthoY, orthoDist, winZ, objPos); - pmv.glTranslatef(objPos[0], objPos[1], objPos[2]); - /** - System.err.printf("XXX %7s: [%5.1f, %5.1f, [%5.1f -> %5.1f]] --> [%8.3f, %8.3f, %8.3f]%n", - msg, orthoX, orthoY, orthoDist, winZ[0], objPos[0], objPos[1], objPos[2]); */ - } - @Override public void display(GLAutoDrawable drawable) { final int width = drawable.getWidth(); @@ -208,23 +205,19 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - final float zDistance0 = 500f; - final float zDistance1 = 400f; - final float[] objPos = new float[3]; - final float[] winZ = new float[1]; - final int[] view = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight() }; + // final float zDistance0 = 500f; + // final float zDistance1 = 400f; + // final float[] objPos = new float[3]; + // final float[] winZ = new float[1]; + // final int[] view = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight() }; final RegionRenderer renderer = getRenderer(); final PMVMatrix pmv = renderer.getMatrix(); renderer.resetModelview(null); renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); - if( useBlending ) { - // NOTE_ALPHA_BLENDING: - // Due to alpha blending and VBAA, we need a background in text color - // otherwise blending will amplify 'white'! + if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } - final float pixelSizeFName = font.getPixelSize(fontSizeFName, dpiH); final float pixelSizeHead = font.getPixelSize(fontSizeHead, dpiH); final float pixelSizeBottom = font.getPixelSize(fontSizeBottom, dpiH); @@ -245,55 +238,69 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB 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, this %d], td %4.1f, blend %b, alpha-bits %d", lfps, tfps, gl.getSwapInterval(), fontSizeHead, fontSizeBottom, modeS, getSampleCount()[0], sampleCountFPS[0], td, - useBlending, drawable.getChosenGLCapabilities().getAlphaBits()); + renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED), + drawable.getChosenGLCapabilities().getAlphaBits()); // bottom, half line up renderer.resetModelview(null); - translateOrtho("fpstxt", pmv, view, zNear, zFar, 0, pixelSizeFPS/2, zDistance0, winZ, objPos); + pmv.glTranslatef(nearPlaneX0, nearPlaneY0+(nearPlaneS * pixelSizeFPS / 2f), nearPlaneZ0); renderer.updateMatrix(gl); // No cache, keep region alive! - TextRegionUtil.drawString3D(regionFPS, renderer, gl, font, pixelSizeFPS, text, sampleCountFPS); + TextRegionUtil.drawString3D(regionFPS, renderer, gl, font, nearPlaneS * pixelSizeFPS, text, sampleCountFPS); } float dx = width-fontNameBox.getWidth()-2f; float dy = height - 10f; renderer.resetModelview(null); - translateOrtho("fontxt", pmv, view, zNear, zFar, dx, dy, zDistance0, winZ, objPos); + pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0); renderer.updateMatrix(gl); - textRegionUtil.drawString3D(gl, font, pixelSizeFName, fontName, getSampleCount()); + System.err.printf("FontN: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy)); + textRegionUtil.drawString3D(gl, font, nearPlaneS * pixelSizeFName, fontName, getSampleCount()); dx = 10f; dy += -fontNameBox.getHeight() - 10f; if(null != headtext) { renderer.resetModelview(null); - translateOrtho("headtx", pmv, view, zNear, zFar, dx, dy, zDistance0, winZ, objPos); + System.err.printf("Head: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy)); + pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0); + // pmv.glTranslatef(x0, y1, z0); renderer.updateMatrix(gl); - textRegionUtil.drawString3D(gl, font, pixelSizeHead, headtext, getSampleCount()); + textRegionUtil.drawString3D(gl, font, nearPlaneS * pixelSizeHead, headtext, getSampleCount()); } dy += -headbox.getHeight() - font.getLineHeight(pixelSizeBottom); renderer.resetModelview(null); - translateOrtho("Bottom", pmv, view, zNear, zFar, dx, dy, zDistance1, winZ, objPos); + pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0); + System.err.printf("Bottom: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy)); renderer.translate(null, getXTran(), getYTran(), getZTran()); renderer.rotate(gl, getAngle(), 0, 1, 0); renderer.setColorStatic(gl, 1.0f, 0.0f, 0.0f); - if( useBlending ) { - // NOTE_ALPHA_BLENDING: - // Due to alpha blending and VBAA, we need a background in text color - // otherwise blending will amplify 'white'! + if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); } + if( bottomTextUseFrustum ) { + regionBottom.setFrustum(pmv.glGetFrustum()); + } if(!userInput) { - textRegionUtil.drawString3D(gl, font, pixelSizeBottom, text2, getSampleCount()); + if( bottomTextUseFrustum ) { + TextRegionUtil.drawString3D(regionBottom, renderer, gl, font, nearPlaneS * pixelSizeBottom, text2, getSampleCount()); + } else { + textRegionUtil.drawString3D(gl, font, nearPlaneS * pixelSizeBottom, text2, getSampleCount()); + } } else { - textRegionUtil.drawString3D(gl, font, pixelSizeBottom, userString.toString(), getSampleCount()); + if( bottomTextUseFrustum ) { + TextRegionUtil.drawString3D(regionBottom, renderer, gl, font, nearPlaneS * pixelSizeBottom, userString.toString(), getSampleCount()); + } else { + textRegionUtil.drawString3D(gl, font, nearPlaneS * pixelSizeBottom, userString.toString(), getSampleCount()); + } } } + final boolean bottomTextUseFrustum = true; public void fontBottomIncr(int v) { fontSizeBottom = Math.abs((fontSizeBottom + v) % fontSizeModulo) ; @@ -347,7 +354,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB void dumpMatrix(boolean bbox) { System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZTran() + " @"+getAngle() +" fontSize "+fontSizeBottom); if(bbox) { - System.err.println("bbox: "+font.getStringBounds(text2, font.getPixelSize(fontSizeBottom, dpiH))); + System.err.println("bbox: "+font.getStringBounds(text2, nearPlaneS * font.getPixelSize(fontSizeBottom, dpiH))); } } 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 aef3ab4bd..6804fdab1 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 @@ -20,9 +20,11 @@ import com.jogamp.newt.Window; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.test.junit.graph.demos.ui.Label; import com.jogamp.opengl.test.junit.graph.demos.ui.RIButton; import com.jogamp.opengl.test.junit.graph.demos.ui.SceneUIController; +import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderState; public class GPUUISceneGLListener0A implements GLEventListener { @@ -34,21 +36,23 @@ public class GPUUISceneGLListener0A implements GLEventListener { private final int[] sampleCount = new int[1]; private final int[] texSize2 = new int[1]; private final RenderState rs; - private final boolean useBlending; private final SceneUIController sceneUIController; protected final float zNear = 0.1f, zFar = 7000f; + /** Describing the bounding box in model-coordinates of the near-plane parallel at distance one. */ + protected final AABBox nearPlane1Box; private RegionRenderer renderer; int fontSet = FontFactory.UBUNTU; Font font; - final float fontSizeFixed = 6; + final float fontSizeFixed = 12f; + final float fontSizeFPS = 10f; float dpiH = 96; - private float xTran = 0; + private float xTran = 0f; private float yTran = 0; - private float ang = 0f; - private float zoom = -200f; + private float zTran = 0f; + private float rotY = 0f; private final float zoomText = 1f; private int currentText = 0; @@ -60,7 +64,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { private final int numSelectable = 6; private MultiTouchListener multiTouchListener = null; - private boolean showFPS = false; + private boolean showFPS = true; private GLAutoDrawable cDrawable; private final String jogamp = "JogAmp - Jogl Graph Module Demo"; @@ -79,7 +83,6 @@ public class GPUUISceneGLListener0A implements GLEventListener { this.renderModes = renderModes; this.sampleCount[0] = 4; this.texSize2[0] = 0; - this.useBlending = true; this.debug = debug; this.trace = trace; @@ -90,26 +93,24 @@ public class GPUUISceneGLListener0A implements GLEventListener { ioe.printStackTrace(); } sceneUIController = new SceneUIController(); + nearPlane1Box = new AABBox(); } private void initButtons(int width, int height) { buttons = new RIButton[numSelectable]; - int xaxis = -110; - float xSize = 40f; - float ySize = 16f; + float xaxis = 20f; + float xSize = 50f; + float ySize = xSize/2.5f; - int start = 50; - int diff = (int)ySize + 5; + float ystart = 25; + float diff = ySize + 5; buttons[0] = new RIButton(SVertex.factory(), font, "Next Text", xSize, ySize){ public void onClick() { currentText = (currentText+1)%3; } - public void onPressed() { } - public void onRelease() { } }; - - buttons[0].translate(xaxis,start); + buttons[0].translate(xaxis,ystart); buttons[1] = new RIButton(SVertex.factory(), font, "Show FPS", xSize, ySize){ public void onClick() { @@ -120,7 +121,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { showFPS = !showFPS; } }; - buttons[1].translate(xaxis,start - diff); + buttons[1].translate(xaxis,ystart - diff); buttons[1].setToggleable(true); buttons[2] = new RIButton(SVertex.factory(), font, "v-sync", xSize, ySize){ @@ -138,29 +139,32 @@ public class GPUUISceneGLListener0A implements GLEventListener { }); } }; - buttons[2].translate(xaxis,start-diff*2); + buttons[2].translate(xaxis,ystart-diff*2); buttons[2].setToggleable(true); + buttons[2].setLabelColor(1.0f, 1.0f, 1.0f); buttons[3] = new RIButton(SVertex.factory(), font, "Tilt +Y", xSize, ySize) { public void onClick() { - ang+=10; + rotY+=10; } }; - buttons[3].translate(xaxis,start-diff*3); + buttons[3].translate(xaxis,ystart-diff*3); + buttons[3].setLabelColor(1.0f, 1.0f, 1.0f); buttons[4] = new RIButton(SVertex.factory(), font, "Tilt -Y", xSize, ySize){ public void onClick() { - ang-=10; + rotY-=10; } }; - buttons[4].translate(xaxis,start-diff*4); + buttons[4].translate(xaxis,ystart-diff*4); + buttons[4].setLabelColor(1.0f, 1.0f, 1.0f); buttons[5] = new RIButton(SVertex.factory(), font, "Quit", xSize, ySize){ public void onClick() { cDrawable.destroy(); } }; - buttons[5].translate(xaxis,start-diff*5); + buttons[5].translate(xaxis,ystart-diff*5); buttons[5].setColor(0.8f, 0.0f, 0.0f); buttons[5].setLabelColor(1.0f, 1.0f, 1.0f); @@ -171,7 +175,13 @@ public class GPUUISceneGLListener0A implements GLEventListener { private void initTexts() { strings = new String[3]; - strings[0] = "abcdefghijklmn\nopqrstuvwxyz\nABCDEFGHIJKL\nMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]"; + strings[0] = "Next Text\n"+ + "Show FPS\n"+ + "abcdefghijklmn\nopqrstuvwxyz\n"+ + "ABCDEFGHIJKL\n"+ + "MNOPQRSTUVWXYZ\n"+ + "0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]"; + strings[1] = "The quick brown fox\njumps over the lazy\ndog"; strings[2] = @@ -241,7 +251,6 @@ public class GPUUISceneGLListener0A implements GLEventListener { final float pixelSizeFixed = font.getPixelSize(fontSizeFixed, dpiH); jogampLabel = new Label(SVertex.factory(), font, pixelSizeFixed, jogamp); - final GLAnimatorControl a = drawable.getAnimator(); if( null != a ) { a.resetFPSCounter(); @@ -265,41 +274,46 @@ public class GPUUISceneGLListener0A implements GLEventListener { public void display(GLAutoDrawable drawable) { // System.err.println("GPUUISceneGLListener0A: display"); - GL2ES2 gl = drawable.getGL().getGL2ES2(); + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + final int width = drawable.getWidth(); + final int height = drawable.getHeight(); gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + final float pixelSizeFixed = font.getPixelSize(fontSizeFixed, dpiH); + renderer.resetModelview(null); - sceneUIController.setTranslate(xTran, yTran, zoom); - sceneUIController.setRotation(0, ang, 0); + sceneUIController.setTranslate(nearPlaneX0+xTran, nearPlaneY0+yTran, nearPlaneZ0+zTran); + sceneUIController.setScale(nearPlaneSx, nearPlaneSy, 1f); + sceneUIController.setRotation(0, rotY, 0); sceneUIController.display(drawable); - final float pixelSizeFixed = font.getPixelSize(fontSizeFixed, dpiH); + float dx = width * 1f/3f; + float dy = height - 10f - jogampLabel.getLineHeight(); renderer.resetModelview(null); - renderer.translate(null, xTran-50, yTran+43, zoom); - renderer.translate(gl, 0, 30, 0); - renderer.scale(null, zoomText, zoomText, 1); - renderer.scale(gl, 1.5f, 1.5f, 1.0f); + renderer.translate(null, nearPlaneX0+xTran+(dx*nearPlaneSx), nearPlaneY0+yTran+(dy*nearPlaneSy), nearPlaneZ0+zTran); + renderer.scale(null, nearPlaneSx*zoomText, nearPlaneSy*zoomText, 1f); renderer.rotate(gl, angText , 0, 1, 0); renderer.setColorStatic(gl, 0.0f, 1.0f, 0.0f); jogampLabel.drawShape(gl, renderer, sampleCount, false); + if(null == labels[currentText]) { labels[currentText] = new Label(SVertex.factory(), font, pixelSizeFixed, strings[currentText]); + labels[currentText].setColor(0, 0, 0); } - + labels[currentText].validate(gl, renderer); + dy -= labels[currentText].getBounds().getHeight(); renderer.resetModelview(null); - renderer.translate(null, xTran-50, yTran, zoom); - renderer.translate(gl, 0, 30, 0); - renderer.scale(null, zoomText, zoomText, 1); - renderer.scale(gl, 1.5f, 1.5f, 1.0f); - renderer.rotate(gl, zoomText, 0, 1, 0); - + renderer.translate(null, nearPlaneX0+xTran+(dx*nearPlaneSx), nearPlaneY0+yTran+(dy*nearPlaneSy), nearPlaneZ0+zTran); + renderer.scale(null, nearPlaneSx*zoomText, nearPlaneSy*zoomText, 1f); + renderer.rotate(gl, angText, 0, 1, 0); renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); labels[currentText].drawShape(gl, renderer, sampleCount, false); if( showFPS ) { + final float pixelSizeFPS = font.getPixelSize(fontSizeFPS, dpiH); final float lfps, tfps, td; final GLAnimatorControl animator = drawable.getAnimator(); if( null != animator ) { @@ -314,28 +328,75 @@ public class GPUUISceneGLListener0A implements GLEventListener { final String modeS = Region.getRenderModeString(renderer.getRenderModes()); final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize %.1f, %s-samples %d, td %4.1f, blend %b, alpha-bits %d", lfps, tfps, gl.getSwapInterval(), fontSizeFixed, modeS, sampleCount[0], td, - useBlending, drawable.getChosenGLCapabilities().getAlphaBits()); + renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED), + drawable.getChosenGLCapabilities().getAlphaBits()); if(null != fpsLabel) { fpsLabel.clear(gl, renderer); fpsLabel.setText(text); - fpsLabel.setPixelSize(pixelSizeFixed); } else { - fpsLabel = new Label(renderer.getRenderState().getVertexFactory(), font, pixelSizeFixed, text); + fpsLabel = new Label(renderer.getRenderState().getVertexFactory(), font, pixelSizeFPS, text); } - renderer.translate(gl, 0, -60, 0); - renderer.scale(null, zoomText, zoomText, 1); + renderer.resetModelview(null); + renderer.translate(null, nearPlaneX0, nearPlaneY0+(nearPlaneS * pixelSizeFPS / 2f), nearPlaneZ0); + renderer.scale(null, nearPlaneSx, nearPlaneSy, 1f); + renderer.updateMatrix(gl); fpsLabel.drawShape(gl, renderer, sampleCount, false); } } + public static void mapWin2ObjectCoords(final PMVMatrix pmv, final int[] view, + final float zNear, final float zFar, + float orthoX, float orthoY, float orthoDist, + final float[] winZ, final float[] objPos) { + winZ[0] = (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar); + pmv.gluUnProject(orthoX, orthoY, winZ[0], view, 0, objPos, 0); + } + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { System.err.println("GPUUISceneGLListener0A: reshape"); GL2ES2 gl = drawable.getGL().getGL2ES2(); - gl.glViewport(x, y, width, height); + final PMVMatrix pmv = renderer.getMatrix(); renderer.reshapePerspective(gl, 45.0f, width, height, zNear, zFar); + renderer.resetModelview(null); + renderer.updateMatrix(gl); + System.err.printf("Reshape: zNear %f, zFar %f%n", zNear, zFar); + System.err.printf("Reshape: Frustum: %s%n", pmv.glGetFrustum()); + { + final float orthoDist = 1f; + final float[] obj00Coord = new float[3]; + final float[] obj11Coord = new float[3]; + final float[] winZ = new float[1]; + final int[] view = new int[] { 0, 0, width, height }; + + mapWin2ObjectCoords(pmv, view, zNear, zFar, 0f, 0f, orthoDist, winZ, obj00Coord); + System.err.printf("Reshape: mapped.00: [%f, %f, %f], winZ %f -> [%f, %f, %f]%n", 0f, 0f, orthoDist, winZ[0], obj00Coord[0], obj00Coord[1], obj00Coord[2]); + + mapWin2ObjectCoords(pmv, view, zNear, zFar, width, height, orthoDist, winZ, obj11Coord); + System.err.printf("Reshape: mapped.11: [%f, %f, %f], winZ %f -> [%f, %f, %f]%n", (float)width, (float)height, orthoDist, winZ[0], obj11Coord[0], obj11Coord[1], obj11Coord[2]); + + nearPlane1Box.setSize( obj00Coord[0], // lx + obj00Coord[1], // ly + obj00Coord[2], // lz + obj11Coord[0], // hx + obj11Coord[1], // hy + obj11Coord[2] );// hz + System.err.printf("Reshape: dist1Box: %s%n", nearPlane1Box); + } sceneUIController.reshape(drawable, x, y, width, height); + + final float dist = 100f; + nearPlaneX0 = nearPlane1Box.getMinX() * dist; + nearPlaneY0 = nearPlane1Box.getMinY() * dist; + nearPlaneZ0 = nearPlane1Box.getMinZ() * dist; + final float xd = nearPlane1Box.getWidth() * dist; + final float yd = nearPlane1Box.getHeight() * dist; + nearPlaneSx = xd / width; + nearPlaneSy = yd / height; + nearPlaneS = nearPlaneSy; + System.err.printf("Scale: [%f x %f] / [%d x %d] = [%f, %f] -> %f%n", xd, yd, width, height, nearPlaneSx, nearPlaneSy, nearPlaneS); } + float nearPlaneX0, nearPlaneY0, nearPlaneZ0, nearPlaneSx, nearPlaneSy, nearPlaneS; public void attachInputListenerTo(GLWindow window) { if ( null == multiTouchListener ) { @@ -381,7 +442,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { int nv = Math.abs(e.getY(0)-e.getY(1)); int dy = nv - lx; - zoom += 2 * Math.signum(dy); + zTran += 2 * Math.signum(dy); lx = nv; } else { @@ -410,7 +471,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { @Override public void mouseWheelMoved(MouseEvent e) { if( !e.isShiftDown() ) { - zoom += 2f*e.getRotation()[1]; // vertical: wheel + zTran += 2f*e.getRotation()[1]; // vertical: wheel } } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java index 17b9642d9..a371aa8b2 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java @@ -14,35 +14,35 @@ import com.jogamp.opengl.util.glsl.ShaderState; public class GPUUISceneNewtDemo01 { 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); caps.setSampleBuffers(true); caps.setNumSamples(4); - - final GLWindow window = GLWindow.create(caps); + + final GLWindow window = GLWindow.create(caps); window.setPosition(10, 10); - window.setSize(680, 480); + window.setSize(800, 400); window.setTitle("GraphUI Newt Demo"); - + final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); GPUUISceneGLListener0A textGLListener = new GPUUISceneGLListener0A(rs, 0, DEBUG, TRACE); window.addGLEventListener(textGLListener); textGLListener.attachInputListenerTo(window); - + final Animator animator = new Animator(); - animator.setUpdateFPSFrames(60, System.err); + animator.setUpdateFPSFrames(60, System.err); animator.add(window); - + window.addWindowListener(new WindowAdapter() { public void windowDestroyed(WindowEvent e) { animator.stop(); } }); - + window.setVisible(true); animator.start(); - } + } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java index a4673f0c5..32c3a9439 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java @@ -15,35 +15,35 @@ import com.jogamp.opengl.util.glsl.ShaderState; public class GPUUISceneNewtDemo02 { 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); caps.setSampleBuffers(true); caps.setNumSamples(4); - - final GLWindow window = GLWindow.create(caps); + + final GLWindow window = GLWindow.create(caps); window.setPosition(10, 10); - window.setSize(680, 480); + window.setSize(800, 400); window.setTitle("GraphUI Newt Demo"); - + final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); GPUUISceneGLListener0A textGLListener = new GPUUISceneGLListener0A(rs, Region.VBAA_RENDERING_BIT, DEBUG, TRACE); window.addGLEventListener(textGLListener); textGLListener.attachInputListenerTo(window); - + final Animator animator = new Animator(); animator.setUpdateFPSFrames(60, System.err); animator.add(window); - + window.addWindowListener(new WindowAdapter() { public void windowDestroyed(WindowEvent e) { animator.stop(); } }); - + window.setVisible(true); animator.start(); - } + } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java index 6275f25d2..243be4e68 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java @@ -73,6 +73,10 @@ public class Label extends UIShape { return pixelSize; } + public float getLineHeight() { + return font.getLineHeight(pixelSize); + } + public void setPixelSize(float pixelSize) { this.pixelSize = pixelSize; dirty |= DIRTY_SHAPE | DIRTY_REGION; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java index df0e504c6..0e49d1bee 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java @@ -29,8 +29,6 @@ package com.jogamp.opengl.test.junit.graph.demos.ui; import javax.media.opengl.GL2ES2; -import jogamp.graph.geom.plane.AffineTransform; - import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; @@ -44,16 +42,19 @@ import com.jogamp.opengl.math.geom.AABBox; public abstract class RIButton extends UIShape { private float width, height; private final Label label; - private float spacing = 4.0f; + /** 20 % to each side default */ + private float spacing = 0.2f; + private static final float spacingSx = 2f; + private static final float spacingSy = 2f; private float corner = 1.0f; private float labelZOffset = -0.05f; public RIButton(Factory<? extends Vertex> factory, Font labelFont, String labelText, float width, float height) { super(factory); - // FIXME: Determine font size - PMV Matrix relation ? - // this.label = new Label(factory, labelFont, (int)(height - 2f * spacing), labelText); - this.label = new Label(factory, labelFont, 10, labelText); + final float pixelSize = height * ( 1f - spacingSy*spacing ) ; + System.err.printf("RIButton: height %f -> pixelSize %f%n", height, pixelSize); + this.label = new Label(factory, labelFont, pixelSize, labelText); this.label.setSelectedColor(this.color[0], this.color[1], this.color[2]); this.label.setColor(0.9f, 0.9f, 0.9f); this.label.setSelectedColor(1f, 1f, 1f); @@ -95,30 +96,55 @@ public abstract class RIButton extends UIShape { @Override protected void createShape(GL2ES2 gl, RegionRenderer renderer) { + // label.createShape(gl, renderer); + // final AABBox lbox = label.getBounds(); + + final float lw = getWidth() * ( 1f - spacingSx*spacing ); + final float lh = getHeight() * ( 1f - spacingSy*spacing ); + final AABBox lbox0 = label.font.getStringBounds(label.text, lh); + final float lsx = lw / lbox0.getWidth(); + final float lsy = lh / lbox0.getHeight(); + final float ls = Math.min(lsx, lsy); + + final float sx = getWidth() / ( ( spacingSx*spacing + 1f ) * lbox0.getWidth() * ls ); + final float sy = getHeight() / ( ( spacingSy*spacing + 1f ) * lbox0.getHeight() * ls ); + System.err.printf("RIButton: bsize %f x %f, lsize %f x %f, lbox0 %f x %f -> ls %f x %f, bs %f x %f .... %s%n", + getWidth(), getHeight(), lw, lh, lbox0.getWidth(), lbox0.getHeight(), lsx, lsy, sx, sy, this.label.text); + + final float lPixelSize1 = lh * ls; + label.setPixelSize(lPixelSize1); label.createShape(gl, renderer); - box.resize(label.getBounds()); - - final float sx = getWidth() / ( 2f*spacing + box.getWidth() ); - final float sy = getHeight() / ( 2f*spacing + box.getHeight() ); - scale(sx, sy, 1); + final AABBox lbox1 = label.getBounds(); + final float lsx1 = lw / lbox1.getWidth(); + final float lsy1 = lh / lbox1.getHeight(); + // final float ls1 = Math.min(lsx1, lsy1); + System.err.printf("RIButton: ls %f x %f, lbox1 %s .... %s%n", + lsx1, lsy1, lbox1, this.label.text); + // label.scale(ls1, ls1); + // scale(sx, sy); + // box.resize(lbox1); final OutlineShape shape = new OutlineShape(renderer.getRenderState().getVertexFactory()); if(corner == 0.0f) { - createSharpOutline(shape, box); + createSharpOutline(shape, lbox1); } else { - createCurvedOutline(shape, box); + createCurvedOutline(shape, lbox1); } box.resize(shape.getBounds()); - shapes.add(new TransformedShape(shape, new AffineTransform(renderer.getRenderState().getVertexFactory()))); + + label.locTranslate( ( box.getWidth() - lbox1.getWidth() ) / 1f, + -1f * ( box.getHeight() - lbox1.getHeight() ) / 1f ); + + shapes.add(new TransformedShape(shape, null)); System.err.println("XXX.UIShape.RIButton: Added Shape: "+shape+", "+box); } private void createSharpOutline(OutlineShape shape, AABBox lbox) { - float th = (2f*spacing) + lbox.getHeight(); - float tw = (2f*spacing) + lbox.getWidth(); + final float tw = getWidth(); // ( spacingSx*spacing + 1f ) * lbox.getWidth(); + final float th = getHeight(); // ( spacingSy*spacing + 1f ) * lbox.getHeight(); - float minX = lbox.getMinX()-spacing; - float minY = lbox.getMinY()-spacing; - float minZ = labelZOffset; + final float minX = lbox.getMinX() - ( spacingSx / 2f * spacing * lbox.getWidth() ); + final float minY = lbox.getMinY() - ( spacingSy / 2f * spacing * lbox.getHeight() ); + final float minZ = labelZOffset; shape.addVertex(minX, minY, minZ, true); shape.addVertex(minX+tw, minY, minZ, true); @@ -127,14 +153,14 @@ public abstract class RIButton extends UIShape { shape.closeLastOutline(true); } private void createCurvedOutline(OutlineShape shape, AABBox lbox){ - final float th = 2.0f*spacing + lbox.getHeight(); - final float tw = 2.0f*spacing + lbox.getWidth(); + final float tw = getWidth(); // ( spacingSx*spacing + 1f ) * lbox.getWidth(); + final float th = getHeight(); // ( spacingSy*spacing + 1f ) * lbox.getHeight(); final float cw = 0.5f*corner*Math.min(tw, th); final float ch = 0.5f*corner*Math.min(tw, th); - float minX = lbox.getMinX()-spacing; - float minY = lbox.getMinY()-spacing; - float minZ = labelZOffset; + final float minX = lbox.getMinX() - ( spacingSx / 2f * spacing * getWidth() ); // lbox.getWidth() ); + final float minY = lbox.getMinY() - ( spacingSy / 2f * spacing * getHeight() ); // lbox.getHeight() ); + final float minZ = labelZOffset; shape.addVertex(minX, minY + ch, minZ, true); shape.addVertex(minX, minY, minZ, false); @@ -178,11 +204,13 @@ public abstract class RIButton extends UIShape { return spacing; } + /** In percent of text label */ public void setSpacing(float spacing) { - if(spacing < 0.0f){ + if ( spacing < 0.0f ) { this.spacing = 0.0f; - } - else{ + } else if ( spacing > 1.0f ) { + this.spacing = 1.0f; + } else { this.spacing = spacing; } dirty |= DIRTY_SHAPE | DIRTY_REGION; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java index 77195646d..7691126a6 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java @@ -12,8 +12,6 @@ import javax.media.opengl.GLEventListener; import javax.media.opengl.GLRunnable; import javax.media.opengl.fixedfunc.GLMatrixFunc; -import jogamp.graph.geom.plane.AffineTransform; - import com.jogamp.common.nio.Buffers; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.newt.event.MouseEvent; @@ -152,6 +150,17 @@ public class SceneUIController implements GLEventListener{ } private void render(GL2ES2 gl, int width, int height, int renderModes, int[/*1*/] sampleCount, boolean select) { + final PMVMatrix pmv = renderer.getMatrix(); + pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmv.glLoadIdentity(); + System.err.printf("SceneUICtrl.render.1.0: scale.0: %f, %f, %f%n", scale[0], scale[1], scale[2]); + System.err.printf("SceneUICtrl.render.1.0: translate.0: %f, %f, %f%n", translate[0], translate[1], translate[2]); + pmv.glTranslatef(translate[0], translate[1], translate[2]); + pmv.glScalef(scale[0], scale[1], scale[2]); + pmv.glRotatef(rotation[0], 1, 0, 0); + pmv.glRotatef(rotation[1], 0, 1, 0); + pmv.glRotatef(rotation[2], 0, 0, 1); + for(int index=0; index < count;index++){ if(select) { float color= index+1; @@ -159,19 +168,11 @@ public class SceneUIController implements GLEventListener{ } final UIShape uiShape = shapes.get(index); uiShape.validate(gl, renderer); - final AffineTransform t = uiShape.getTransform(); + final float[] uiTranslate = uiShape.getTranslate(); - final PMVMatrix pmv = renderer.getMatrix(); - pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmv.glPushMatrix(); - pmv.glLoadIdentity(); - System.err.printf("SceneUICtrl.render.1.0: translate.0: %f, %f, %f%n", translate[0], translate[1], translate[2]); - System.err.printf("SceneUICtrl.render.1.0: translate.1: %f, %f%n", t.getTranslateX(), t.getTranslateY()); - pmv.glTranslatef(translate[0]+t.getTranslateX(), translate[1]+t.getTranslateY(), translate[2]); - pmv.glScalef(scale[0]*t.getScaleX(), scale[1]*t.getScaleY(), scale[2]); - pmv.glRotatef(rotation[0], 1, 0, 0); - pmv.glRotatef(rotation[1], 0, 1, 0); - pmv.glRotatef(rotation[2], 0, 0, 1); + System.err.printf("SceneUICtrl.render.1.0: translate.1: %f, %f%n", uiTranslate[0], uiTranslate[1]); + pmv.glTranslatef(uiTranslate[0], uiTranslate[1], 0f); renderer.updateMatrix(gl); uiShape.drawShape(gl, renderer, sampleCount, select); pmv.glPopMatrix(); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIGLListener01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIGLListener01.java index 587b9b3dc..108aad879 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIGLListener01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIGLListener01.java @@ -34,8 +34,6 @@ import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import javax.media.opengl.GLAutoDrawable; -import jogamp.graph.geom.plane.AffineTransform; - import com.jogamp.graph.curve.opengl.RenderState; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; @@ -99,8 +97,8 @@ public class UIGLListener01 extends UIListenerBase01 { regionRenderer.rotate(gl, getAngle(), 0, 1, 0); final int[] sampleCount = { 4 }; - final AffineTransform t = button.getTransform(); - regionRenderer.translate(gl, t.getTranslateX(), t.getTranslateY(), 0); + final float[] translate = button.getTranslate(); + regionRenderer.translate(gl, translate[0], translate[1], 0); button.drawShape(gl, regionRenderer, sampleCount, false); } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java index c94b63494..ecd22ef71 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java @@ -55,27 +55,27 @@ import com.jogamp.opengl.util.GLReadBufferUtil; * - 1/2: zoom in/out * - 4/5: increase/decrease shape/text spacing * - 6/7: increase/decrease corner size - * - 0/9: rotate + * - 0/9: rotate * - v: toggle v-sync * - s: screenshot */ public abstract class UIListenerBase01 implements GLEventListener { - private GLReadBufferUtil screenshot; - private RegionRenderer rRenderer; - private boolean debug; - private boolean trace; - + private final GLReadBufferUtil screenshot; + private final RegionRenderer rRenderer; + private final boolean debug; + private final boolean trace; + protected RIButton button; - + private KeyAction keyAction; private MouseAction mouseAction; - + private volatile GLAutoDrawable autoDrawable = null; - + private final float[] position = new float[] {0,0,0}; - + private float xTran = -10; - private float yTran = 10; + private float yTran = 10; private float ang = 0f; private float zoom = -70f; @@ -87,7 +87,7 @@ public abstract class UIListenerBase01 implements GLEventListener { this.trace = trace; this.screenshot = new GLReadBufferUtil(false, false); } - + public final RegionRenderer getRegionRenderer() { return rRenderer; } public final float getZoom() { return zoom; } public final float getXTran() { return xTran; } @@ -97,11 +97,11 @@ public abstract class UIListenerBase01 implements GLEventListener { public void setMatrix(float xtrans, float ytrans, float angle, int zoom) { this.xTran = xtrans; - this.yTran = ytrans; - this.ang = angle; + this.yTran = ytrans; + this.ang = angle; this.zoom = zoom; } - + public void init(GLAutoDrawable drawable) { autoDrawable = drawable; GL2ES2 gl = drawable.getGL().getGL2ES2(); @@ -112,29 +112,29 @@ public abstract class UIListenerBase01 implements GLEventListener { gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2(); } gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - getRegionRenderer().init(gl); + getRegionRenderer().init(gl); } - + public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) { GL2ES2 gl = drawable.getGL().getGL2ES2(); - - gl.glViewport(xstart, ystart, width, height); + + gl.glViewport(xstart, ystart, width, height); rRenderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); dumpMatrix(); } - + public void dispose(GLAutoDrawable drawable) { autoDrawable = null; GL2ES2 gl = drawable.getGL().getGL2ES2(); screenshot.dispose(gl); rRenderer.destroy(gl); - } - + } + public void zoom(int v){ zoom += v; dumpMatrix(); } - + public void move(float x, float y){ xTran += x; yTran += y; @@ -145,23 +145,23 @@ public abstract class UIListenerBase01 implements GLEventListener { ang %= 360.0f; dumpMatrix(); } - + void dumpMatrix() { System.err.println("Matrix: " + xTran + "/" + yTran + " x"+zoom + " @"+ang); } - - /** Attach the input listener to the window */ + + /** Attach the input listener to the window */ public void attachInputListenerTo(GLWindow window) { if ( null == keyAction ) { keyAction = new KeyAction(); - window.addKeyListener(keyAction); + window.addKeyListener(keyAction); } if ( null == mouseAction ) { mouseAction = new MouseAction(); - window.addMouseListener(mouseAction); + window.addMouseListener(mouseAction); } } - + public void detachFrom(GLWindow window) { if ( null == keyAction ) { return; @@ -173,18 +173,18 @@ public abstract class UIListenerBase01 implements GLEventListener { window.removeKeyListener(keyAction); window.removeMouseListener(mouseAction); } - + public void printScreen(GLAutoDrawable drawable, String dir, String tech, String objName, boolean exportAlpha) throws GLException, IOException { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), 0, objName); - + final String filename = dir + tech + sw +".png"; if(screenshot.readPixels(drawable.getGL(), false)) { screenshot.write(new File(filename)); } } - + int screenshot_num = 0; public void setIgnoreInput(boolean v) { @@ -193,11 +193,11 @@ public abstract class UIListenerBase01 implements GLEventListener { public boolean getIgnoreInput() { return ignoreInput; } - + public class MouseAction implements MouseListener{ public void mouseClicked(MouseEvent e) { - + } public void mouseEntered(MouseEvent e) { @@ -208,37 +208,37 @@ public abstract class UIListenerBase01 implements GLEventListener { public void mousePressed(MouseEvent e) { button.setLabelColor(0.8f,0.8f,0.8f); - button.setButtonColor(0.1f, 0.1f, 0.1f); + button.setColor(0.1f, 0.1f, 0.1f); } public void mouseReleased(MouseEvent e) { button.setLabelColor(1.0f,1.0f,1.0f); - button.setButtonColor(0.6f,0.6f,0.6f); + button.setColor(0.6f,0.6f,0.6f); } public void mouseMoved(MouseEvent e) { // TODO Auto-generated method stub - + } public void mouseDragged(MouseEvent e) { // TODO Auto-generated method stub - + } public void mouseWheelMoved(MouseEvent e) { // TODO Auto-generated method stub - + } - + } - + public class KeyAction implements KeyListener { public void keyPressed(KeyEvent arg0) { if(ignoreInput) { return; } - + if(arg0.getKeyCode() == KeyEvent.VK_1){ zoom(10); } @@ -258,19 +258,19 @@ public abstract class UIListenerBase01 implements GLEventListener { move(-1, 0); } else if(arg0.getKeyCode() == KeyEvent.VK_4){ - button.setSpacing(button.getSpacing()-0.1f); + button.setSpacing(button.getSpacing()-0.01f); System.err.println("Button Spacing: " + button.getSpacing()); } else if(arg0.getKeyCode() == KeyEvent.VK_5){ - button.setSpacing(button.getSpacing()+0.1f); + button.setSpacing(button.getSpacing()+0.01f); System.err.println("Button Spacing: " + button.getSpacing()); } else if(arg0.getKeyCode() == KeyEvent.VK_6){ - button.setCorner(button.getCorner()-0.1f); + button.setCorner(button.getCorner()-0.01f); System.err.println("Button Corner: " + button.getCorner()); } else if(arg0.getKeyCode() == KeyEvent.VK_7){ - button.setCorner(button.getCorner()+0.1f); + button.setCorner(button.getCorner()+0.01f); System.err.println("Button Corner: " + button.getCorner()); } else if(arg0.getKeyCode() == KeyEvent.VK_0){ @@ -278,13 +278,13 @@ public abstract class UIListenerBase01 implements GLEventListener { } else if(arg0.getKeyCode() == KeyEvent.VK_9){ rotate(-1); - } + } else if(arg0.getKeyCode() == KeyEvent.VK_V) { if(null != autoDrawable) { autoDrawable.invoke(false, new GLRunnable() { public boolean run(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - int i = gl.getSwapInterval(); + int i = gl.getSwapInterval(); i = i==0 ? 1 : 0; gl.setSwapInterval(i); final GLAnimatorControl a = drawable.getAnimator(); @@ -295,7 +295,7 @@ public abstract class UIListenerBase01 implements GLEventListener { return true; } }); - } + } } else if(arg0.getKeyCode() == KeyEvent.VK_S){ rotate(-1); @@ -303,7 +303,7 @@ public abstract class UIListenerBase01 implements GLEventListener { autoDrawable.invoke(false, new GLRunnable() { public boolean run(GLAutoDrawable drawable) { try { - final String type = ( 1 == rRenderer.getRenderModes() ) ? "r2t0-msaa1" : "r2t1-msaa0" ; + final String type = ( 1 == rRenderer.getRenderModes() ) ? "r2t0-msaa1" : "r2t1-msaa0" ; printScreen(drawable, "./", "demo-"+type, "snap"+screenshot_num, false); screenshot_num++; } catch (GLException e) { @@ -311,11 +311,11 @@ public abstract class UIListenerBase01 implements GLEventListener { } catch (IOException e) { e.printStackTrace(); } - return true; + return true; } }); - } - } + } + } } public void keyReleased(KeyEvent arg0) {} } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java index 5a7b147d5..4db7da3ac 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java @@ -37,6 +37,7 @@ import com.jogamp.graph.curve.OutlineShape; 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.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.opengl.math.geom.AABBox; @@ -61,7 +62,9 @@ public abstract class UIShape { protected int dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; protected final AABBox box; - protected final AffineTransform transform; + protected final float[] translate = new float[] { 0f, 0f }; + protected final float[] ltranslate = new float[] { 0f, 0f }; + protected final float[] lscale = new float[] { 1f, 1f }; private GLRegion region = null; protected final float[] color = {0.6f, 0.6f, 0.6f}; @@ -75,7 +78,6 @@ public abstract class UIShape { this.vertexFactory = factory; this.shapes = new ArrayList<TransformedShape>(); this.box = new AABBox(); - this.transform = new AffineTransform(factory); } public final Vertex.Factory<? extends Vertex> getVertexFactory() { return vertexFactory; } @@ -88,7 +90,12 @@ public abstract class UIShape { public void clear(GL2ES2 gl, RegionRenderer renderer) { clearImpl(gl, renderer); shapes.clear(); - transform.setToIdentity(); + translate[0] = 0f; + translate[1] = 0f; + ltranslate[0] = 0f; + ltranslate[1] = 0f; + lscale[0] = 1f; + lscale[1] = 1f; box.reset(); dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; } @@ -101,25 +108,35 @@ public abstract class UIShape { public void destroy(GL2ES2 gl, RegionRenderer renderer) { destroyImpl(gl, renderer); shapes.clear(); - transform.setToIdentity(); + translate[0] = 0f; + translate[1] = 0f; + ltranslate[0] = 0f; + ltranslate[1] = 0f; + lscale[0] = 1f; + lscale[1] = 1f; box.reset(); dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; } public final void translate(float tx, float ty) { - transform.translate(tx, ty); + translate[0] += tx; + translate[1] += ty; dirty |= DIRTY_POSITION; } - - public final void scale(float sx, float sy, float sz) { - transform.scale(sx, sy); - } - - public final AffineTransform getTransform() { + public final float[] getTranslate() { if( !isShapeDirty() ) { validatePosition(); } - return transform; + return translate; + } + + public final void locTranslate(float tx, float ty) { + ltranslate[0] += tx; + ltranslate[1] += ty; + } + public final void locScale(float sx, float sy) { + lscale[0] *= sx; + lscale[1] *= sy; } public final boolean isShapeDirty() { @@ -169,13 +186,9 @@ public abstract class UIShape { _color = selectedColor; } if(!select){ - /** - if( useBlending ) { - // NOTE_ALPHA_BLENDING: - // Due to alpha blending and VBAA, we need a background in text color - // otherwise blending will amplify 'white'! - gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - } */ + if( renderer.getRenderState().isHintBitSet(RenderState.BITHINT_BLENDING_ENABLED) ) { + gl.glClearColor(_color[0], _color[1], _color[2], 0.0f); + } renderer.setColorStatic(gl, _color[0], _color[1], _color[2]); } getRegion(gl, renderer).draw(gl, renderer, sampleCount); @@ -205,9 +218,9 @@ public abstract class UIShape { final AABBox box = getBounds(); final float minX = box.getMinX(); final float minY = box.getMinY(); - System.err.println("XXX.UIShape: Position pre: " + transform.getTranslateX() + " " + transform.getTranslateY() + ", sbox "+box); + System.err.println("XXX.UIShape: Position pre: " + translate[0] + " " + translate[1] + ", sbox "+box); translate(-minX, -minY); - System.err.println("XXX.UIShape: Position post: " + transform.getTranslateX() + " " + transform.getTranslateY() + ", sbox "+box); + System.err.println("XXX.UIShape: Position post: " + translate[0] + " " + translate[1] + ", sbox "+box); dirty &= ~DIRTY_POSITION; return true; } @@ -215,10 +228,40 @@ public abstract class UIShape { } private final void addToRegion(Region region) { + final AffineTransform t; + final boolean hasLocTrans = 0f != ltranslate[0] || 0f != ltranslate[1]; + final boolean hasLocScale = 1f != lscale[0] || 1f != lscale[1]; + if( hasLocTrans || hasLocScale ) { + System.err.printf("UIShape.addToRegion: locTranslate %f x %f, locScale %f x %f%n", + ltranslate[0], ltranslate[1], lscale[0], lscale[1]); + if( hasLocTrans ) { + t = AffineTransform.getTranslateInstance(vertexFactory, ltranslate[0], ltranslate[1]); + if( hasLocScale ) { + t.scale(lscale[0], lscale[1]); + } + } else if( hasLocScale ) { + t = AffineTransform.getScaleInstance(vertexFactory, lscale[0], lscale[1]); + } else { + t = null; // unreachable! + } + } else { + t = null; + } final int shapeCount = shapes.size(); for(int i=0; i<shapeCount; i++) { final TransformedShape tshape = shapes.get(i); - region.addOutlineShape(tshape.shape, tshape.t); + final AffineTransform t2; + if( null != tshape.t ) { + if( null != t ) { + t2 = new AffineTransform(t); + t2.concatenate(tshape.t); + } else { + t2 = tshape.t; + } + } else { + t2 = t; + } + region.addOutlineShape(tshape.shape, t2); } } |