diff options
11 files changed, 450 insertions, 475 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index dd668c927..0721c4726 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -54,16 +54,27 @@ public class TextRegionUtil { this.renderer = renderer; } + public static interface ShapeVisitor { + /** + * Visiting the given {@link OutlineShape} with it's corresponding {@link AffineTransform}. + * @param shape may be used as is, otherwise a copy shall be made if intended to be modified. + * @param t may be used immediately as is, otherwise a copy shall be made if stored. + */ + public void visit(final OutlineShape shape, final AffineTransform t); + } + /** - * Add the string in 3D space w.r.t. the font and pixelSize at the end of the {@link GLRegion}. - * @param region the {@link GLRegion} sink - * @param vertexFactory vertex impl factory {@link Factory} + * Visit each {@link Font.Glyph}'s {@link OutlineShape} with the given {@link ShapeVisitor} + * additionally passing the progressed {@link AffineTransform}. + * The latter reflects the given font metric, pixelSize and hence character position. + * @param visitor + * @param transform * @param font the target {@link Font} * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. * @param str string text */ - public static void addStringToRegion(final GLRegion region, final Factory<? extends Vertex> vertexFactory, - final Font font, final float pixelSize, final CharSequence str) { + public static void processString(final ShapeVisitor visitor, final AffineTransform transform, + final Font font, final float pixelSize, final CharSequence str) { final int charCount = str.length(); // region.setFlipped(true); @@ -71,8 +82,7 @@ public class TextRegionUtil { final float lineHeight = font.getLineHeight(pixelSize); final float scale = metrics.getScale(pixelSize); - final AffineTransform transform = new AffineTransform(vertexFactory); - final AffineTransform t = new AffineTransform(vertexFactory); + final AffineTransform t = new AffineTransform(transform); float y = 0; float advanceTotal = 0; @@ -97,7 +107,7 @@ public class TextRegionUtil { if( null == glyphShape ) { continue; } - region.addOutlineShape(glyphShape, t); + visitor.visit(glyphShape, t); advanceTotal += glyph.getAdvance(pixelSize, true); } @@ -105,6 +115,23 @@ public class TextRegionUtil { } /** + * Add the string in 3D space w.r.t. the font and pixelSize at the end of the {@link GLRegion}. + * @param region the {@link GLRegion} sink + * @param vertexFactory vertex impl factory {@link Factory} + * @param font the target {@link Font} + * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. + * @param str string text + */ + public static void addStringToRegion(final GLRegion region, final Factory<? extends Vertex> vertexFactory, + final Font font, final float pixelSize, final CharSequence str) { + final ShapeVisitor visitor = new ShapeVisitor() { + public final void visit(final OutlineShape shape, final AffineTransform t) { + region.addOutlineShape(shape, t); + } }; + processString(visitor, new AffineTransform(vertexFactory), font, pixelSize, str); + } + + /** * Render the string in 3D space w.r.t. the font and pixelSize * using a cached {@link GLRegion} for reuse. * <p> 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 701a6fd92..d5247eb51 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 @@ -76,6 +76,8 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { private final float[] position = new float[] {0,0,0}; + protected final float zNear = 0.1f, zFar = 7000f; + private float xTran = -10; private float yTran = 10; private float ang = 0f; @@ -132,7 +134,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glViewport(xstart, ystart, width, height); - renderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); + renderer.reshapePerspective(gl, 45.0f, width, height, zNear, zFar); 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 821f6835e..d77b0032d 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 @@ -208,7 +208,6 @@ 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 zNear = 0.1f, zFar = 7000f; final float zDistance0 = 500f; final float zDistance1 = 400f; final float[] objPos = new float[3]; @@ -217,12 +216,11 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB final RegionRenderer renderer = getRenderer(); final PMVMatrix pmv = renderer.getMatrix(); - renderer.reshapePerspective(null, 45.0f, width, height, zNear, zFar); 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 black background (== text color) + // 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); } @@ -285,7 +283,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB renderer.setColorStatic(gl, 1.0f, 0.0f, 0.0f); if( useBlending ) { // NOTE_ALPHA_BLENDING: - // Due to alpha blending and VBAA, we need a black background (== text color) + // Due to alpha blending and VBAA, we need a background in text color // otherwise blending will amplify 'white'! gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); } 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 7587295aa..aef3ab4bd 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 @@ -16,13 +16,13 @@ import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.geom.SVertex; +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.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.test.junit.graph.demos.ui.opengl.UIRegion; import com.jogamp.opengl.util.glsl.ShaderState; public class GPUUISceneGLListener0A implements GLEventListener { @@ -32,14 +32,18 @@ public class GPUUISceneGLListener0A implements GLEventListener { private final int renderModes; private final int[] sampleCount = new int[1]; - private final int renderModes2; private final int[] texSize2 = new int[1]; - private RegionRenderer regionRenderer; private final RenderState rs; + private final boolean useBlending; + private final SceneUIController sceneUIController; + protected final float zNear = 0.1f, zFar = 7000f; + + private RegionRenderer renderer; int fontSet = FontFactory.UBUNTU; Font font; - final int fontSizeFixed = 6; + final float fontSizeFixed = 6; + float dpiH = 96; private float xTran = 0; private float yTran = 0; @@ -50,18 +54,14 @@ public class GPUUISceneGLListener0A implements GLEventListener { private Label[] labels = null; private String[] strings = null; - private final UIRegion[] labelRegions; - private UIRegion fpsRegion = null; - private UIRegion jogampRegion = null; private RIButton[] buttons = null; - + private Label jogampLabel = null; + private Label fpsLabel = null; private final int numSelectable = 6; - private SceneUIController sceneUIController = null; private MultiTouchListener multiTouchListener = null; private boolean showFPS = false; private GLAutoDrawable cDrawable; - private float fps = 0; private final String jogamp = "JogAmp - Jogl Graph Module Demo"; private final float angText = 0; @@ -78,8 +78,8 @@ public class GPUUISceneGLListener0A implements GLEventListener { this.rs = rs; this.renderModes = renderModes; this.sampleCount[0] = 4; - this.renderModes2 = 0; this.texSize2[0] = 0; + this.useBlending = true; this.debug = debug; this.trace = trace; @@ -89,7 +89,6 @@ public class GPUUISceneGLListener0A implements GLEventListener { System.err.println("Catched: "+ioe.getMessage()); ioe.printStackTrace(); } - labelRegions = new UIRegion[3]; sceneUIController = new SceneUIController(); } @@ -110,7 +109,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { public void onRelease() { } }; - buttons[0].setPosition(xaxis,start,0); + buttons[0].translate(xaxis,start); buttons[1] = new RIButton(SVertex.factory(), font, "Show FPS", xSize, ySize){ public void onClick() { @@ -120,10 +119,8 @@ public class GPUUISceneGLListener0A implements GLEventListener { } showFPS = !showFPS; } - public void onPressed() { } - public void onRelease() { } }; - buttons[1].setPosition(xaxis,start - diff,0); + buttons[1].translate(xaxis,start - diff); buttons[1].setToggleable(true); buttons[2] = new RIButton(SVertex.factory(), font, "v-sync", xSize, ySize){ @@ -140,44 +137,34 @@ public class GPUUISceneGLListener0A implements GLEventListener { } }); } - public void onPressed() { } - public void onRelease() { } }; - buttons[2].setPosition(xaxis,start-diff*2,0); + buttons[2].translate(xaxis,start-diff*2); buttons[2].setToggleable(true); buttons[3] = new RIButton(SVertex.factory(), font, "Tilt +Y", xSize, ySize) { public void onClick() { ang+=10; } - public void onPressed() { - - } - public void onRelease() { } }; - buttons[3].setPosition(xaxis,start-diff*3,0); + buttons[3].translate(xaxis,start-diff*3); buttons[4] = new RIButton(SVertex.factory(), font, "Tilt -Y", xSize, ySize){ public void onClick() { ang-=10; } - public void onPressed() { } - public void onRelease() { } }; - buttons[4].setPosition(xaxis,start-diff*4,0); + buttons[4].translate(xaxis,start-diff*4); buttons[5] = new RIButton(SVertex.factory(), font, "Quit", xSize, ySize){ public void onClick() { cDrawable.destroy(); } - public void onPressed() { } - public void onRelease() { } }; - buttons[5].setPosition(xaxis,start-diff*5,0); - buttons[5].setButtonColor(0.8f, 0.0f, 0.0f); + buttons[5].translate(xaxis,start-diff*5); + buttons[5].setColor(0.8f, 0.0f, 0.0f); buttons[5].setLabelColor(1.0f, 1.0f, 1.0f); - buttons[5].setButtonSelectedColor(0.8f, 0.8f, 0.8f); + buttons[5].setSelectedColor(0.8f, 0.8f, 0.8f); buttons[5].setLabelSelectedColor(0.8f, 0.0f, 0.0f); } @@ -200,6 +187,12 @@ public class GPUUISceneGLListener0A implements GLEventListener { } public void init(GLAutoDrawable drawable) { + 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; + } if(drawable instanceof GLWindow) { System.err.println("GPUUISceneGLListener0A: init (1)"); final GLWindow glw = (GLWindow) drawable; @@ -225,34 +218,30 @@ public class GPUUISceneGLListener0A implements GLEventListener { ioe.printStackTrace(); } - regionRenderer = RegionRenderer.create(rs, renderModes, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable); + renderer = RegionRenderer.create(rs, renderModes, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable); gl.glEnable(GL2ES2.GL_DEPTH_TEST); gl.glEnable(GL2ES2.GL_BLEND); - regionRenderer.init(gl); - regionRenderer.setAlpha(gl, 1.0f); - regionRenderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); + renderer.init(gl); + renderer.setAlpha(gl, 1.0f); + renderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); initTexts(); initButtons(width, height); - sceneUIController.setRenderer(regionRenderer, renderModes, sampleCount); + sceneUIController.setRenderer(renderer, renderModes, sampleCount); sceneUIController.addShape(buttons[0]); sceneUIController.addShape(buttons[1]); sceneUIController.addShape(buttons[2]); sceneUIController.addShape(buttons[3]); sceneUIController.addShape(buttons[4]); sceneUIController.addShape(buttons[5]); - drawable.addGLEventListener(sceneUIController); + sceneUIController.init(drawable); - Label jlabel = new Label(SVertex.factory(), font, fontSizeFixed, jogamp){ - public void onClick() { } - public void onPressed() { } - public void onRelease() { } - }; + final float pixelSizeFixed = font.getPixelSize(fontSizeFixed, dpiH); + jogampLabel = new Label(SVertex.factory(), font, pixelSizeFixed, jogamp); - jogampRegion = new UIRegion(jlabel); final GLAnimatorControl a = drawable.getAnimator(); if( null != a ) { a.resetFPSCounter(); @@ -268,82 +257,74 @@ public class GPUUISceneGLListener0A implements GLEventListener { System.err.println("GPUUISceneGLListener0A: dispose (0)"); } - // sceneUIController will remove itself from the drawable! + sceneUIController.dispose(drawable); GL2ES2 gl = drawable.getGL().getGL2ES2(); - regionRenderer.destroy(gl); + renderer.destroy(gl); } public void display(GLAutoDrawable drawable) { // System.err.println("GPUUISceneGLListener0A: display"); - final int width = drawable.getWidth(); - final int height = drawable.getHeight(); GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - regionRenderer.reshapePerspective(null, 45.0f, width, height, 0.1f, 7000.0f); + renderer.resetModelview(null); sceneUIController.setTranslate(xTran, yTran, zoom); sceneUIController.setRotation(0, ang, 0); - - renderScene(drawable); - } - - private void renderScene(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); - - regionRenderer.resetModelview(null); - regionRenderer.translate(null, xTran-50, yTran+43, zoom); - regionRenderer.translate(gl, 0, 30, 0); - regionRenderer.scale(null, zoomText, zoomText, 1); - regionRenderer.scale(gl, 1.5f, 1.5f, 1.0f); - regionRenderer.rotate(gl, angText , 0, 1, 0); - regionRenderer.setColorStatic(gl, 0.0f, 1.0f, 0.0f); - jogampRegion.getRegion(gl, regionRenderer, 0).draw(gl, regionRenderer, null); - if(null == labelRegions[currentText]) { - if( null == labels[currentText]) { - labels[currentText] = new Label(SVertex.factory(), font, fontSizeFixed, strings[currentText]){ - public void onClick() { } - public void onPressed() { } - public void onRelease() { } - }; - } - labelRegions[currentText] = new UIRegion(labels[currentText]); + sceneUIController.display(drawable); + + final float pixelSizeFixed = font.getPixelSize(fontSizeFixed, dpiH); + + 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.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]); } - regionRenderer.resetModelview(null); - regionRenderer.translate(null, xTran-50, yTran, zoom); - regionRenderer.translate(gl, 0, 30, 0); - regionRenderer.scale(null, zoomText, zoomText, 1); - regionRenderer.scale(gl, 1.5f, 1.5f, 1.0f); - regionRenderer.rotate(gl, zoomText, 0, 1, 0); - - regionRenderer.setColorStatic(gl, 0.0f, 0.0f, 0.0f); - labelRegions[currentText].getRegion(gl, regionRenderer, renderModes2).draw(gl, regionRenderer, texSize2); - - final GLAnimatorControl animator = drawable.getAnimator(); - final boolean _drawFPS = showFPS && null != animator; - - if(_drawFPS && fps != animator.getTotalFPS()) { - if(null != fpsRegion) { - fpsRegion.destroy(gl, regionRenderer); + 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.setColorStatic(gl, 0.0f, 0.0f, 0.0f); + labels[currentText].drawShape(gl, renderer, sampleCount, false); + + if( showFPS ) { + final float lfps, tfps, td; + final GLAnimatorControl animator = drawable.getAnimator(); + if( null != animator ) { + lfps = animator.getLastFPS(); + tfps = animator.getTotalFPS(); + td = animator.getTotalFPSDuration()/1000f; + } else { + lfps = 0f; + tfps = 0f; + td = 0f; } - fps = animator.getTotalFPS(); - final String fpsS = String.valueOf(fps); - final int fpsSp = fpsS.indexOf('.'); - - Label fpsLabel = new Label(SVertex.factory(), font, fontSizeFixed, fpsS.substring(0, fpsSp+2)+" fps"){ - public void onClick() { } - public void onPressed() { } - public void onRelease() { } - }; - fpsRegion = new UIRegion(fpsLabel); - } - if(showFPS && null != fpsRegion) { - regionRenderer.translate(gl, 0, -60, 0); - regionRenderer.scale(null, zoomText, zoomText, 1); - fpsRegion.getRegion(gl, regionRenderer, renderModes2).draw(gl, regionRenderer, null); + 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()); + if(null != fpsLabel) { + fpsLabel.clear(gl, renderer); + fpsLabel.setText(text); + fpsLabel.setPixelSize(pixelSizeFixed); + } else { + fpsLabel = new Label(renderer.getRenderState().getVertexFactory(), font, pixelSizeFixed, text); + } + renderer.translate(gl, 0, -60, 0); + renderer.scale(null, zoomText, zoomText, 1); + fpsLabel.drawShape(gl, renderer, sampleCount, false); } } @@ -352,7 +333,8 @@ public class GPUUISceneGLListener0A implements GLEventListener { GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glViewport(x, y, width, height); - regionRenderer.reshapePerspective(gl, 45.0f, width, height, 5f, 70.0f); + renderer.reshapePerspective(gl, 45.0f, width, height, zNear, zFar); + sceneUIController.reshape(drawable, x, y, width, height); } public void attachInputListenerTo(GLWindow window) { 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 efbb992db..6275f25d2 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 @@ -29,38 +29,35 @@ package com.jogamp.opengl.test.junit.graph.demos.ui; import javax.media.opengl.GL2ES2; -import com.jogamp.graph.curve.opengl.GLRegion; +import jogamp.graph.geom.plane.AffineTransform; + +import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.TextRegionUtil; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; +import com.jogamp.opengl.math.geom.AABBox; -public abstract class Label extends UIShape implements UITextShape { +public class Label extends UIShape { protected Font font; - protected int size; + protected float pixelSize; protected String text; - protected GLRegion glyphRegion; - public Label(Factory<? extends Vertex> factory, Font font, int size, String text) { + public Label(Factory<? extends Vertex> factory, Font font, float pixelSize, String text) { super(factory); this.font = font; - this.size = size; + this.pixelSize = pixelSize; this.text = text; } - @Override - public GLRegion getRegion() { - return glyphRegion; - } - public String getText() { return text; } public void setText(String text) { this.text = text; - dirty |= DIRTY_SHAPE; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } public Font getFont() { @@ -69,39 +66,46 @@ public abstract class Label extends UIShape implements UITextShape { public void setFont(Font font) { this.font = font; - dirty |= DIRTY_SHAPE; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } - public int getSize() { - return size; + public float getPixelSize() { + return pixelSize; } - public void setSize(int size) { - this.size = size; - dirty |= DIRTY_SHAPE; + public void setPixelSize(float pixelSize) { + this.pixelSize = pixelSize; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } @Override - public String toString(){ - return "Label [" + font.toString() + ", size " + size + ", " + getText() + "]"; + protected void clearImpl(GL2ES2 gl, RegionRenderer renderer) { } @Override - protected void clearImpl(GL2ES2 gl, RegionRenderer renderer) { - if(null != glyphRegion) { - glyphRegion.destroy(gl, renderer); - } + protected void destroyImpl(GL2ES2 gl, RegionRenderer renderer) { } + private final TextRegionUtil.ShapeVisitor shapeVisitor = new TextRegionUtil.ShapeVisitor() { + final float[] tmp = new float[3]; + @Override + public void visit(OutlineShape shape, AffineTransform t) { + shapes.add(new TransformedShape(shape, new AffineTransform(t))); + final AABBox sbox = shape.getBounds(); + t.transform(sbox.getLow(), tmp); + box.resize(tmp, 0); + t.transform(sbox.getHigh(), tmp); + box.resize(tmp, 0); + } + }; + @Override - protected void createShape(RegionRenderer renderer) { - clearImpl(null, null); - glyphRegion = GLRegion.create(renderer.getRenderModes()); - TextRegionUtil.addStringToRegion(glyphRegion, renderer.getRenderState().getVertexFactory(), - font, size, text); + protected void createShape(GL2ES2 gl, RegionRenderer renderer) { + TextRegionUtil.processString(shapeVisitor, new AffineTransform(renderer.getRenderState().getVertexFactory()), font, pixelSize, text); } @Override - public void render(GL2ES2 gl, RegionRenderer renderer, int renderModes, int[/*1*/] texSize, boolean selection) { + public String toString(){ + return "Label [" + font.toString() + ", size " + pixelSize + ", " + getText() + "]"; } } 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 ea83c8e78..df0e504c6 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,14 +29,17 @@ 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; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.test.junit.graph.demos.ui.opengl.UIRegion; -/** GPU based resolution independent Button impl +/** + * GPU based resolution independent Button impl */ public abstract class RIButton extends UIShape { private float width, height; @@ -45,22 +48,15 @@ public abstract class RIButton extends UIShape { private float corner = 1.0f; private float labelZOffset = -0.05f; - private float[] buttonColor = {0.6f, 0.6f, 0.6f}; - private float[] buttonSelectedColor = {0.8f,0.8f,0.8f}; - private float[] labelColor = {1.0f, 1.0f, 1.0f}; - private float[] labelSelectedColor = {0.1f, 0.1f, 0.1f}; - - 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){ - public void onClick() { } - public void onPressed() { } - public void onRelease() { } - }; + this.label = new Label(factory, labelFont, 10, 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); this.width = width; this.height = height; @@ -74,36 +70,49 @@ public abstract class RIButton extends UIShape { public void setDimension(int width, int height) { this.width = width; this.height = height; - dirty |= DIRTY_SHAPE; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } @Override protected void clearImpl(GL2ES2 gl, RegionRenderer renderer) { - label.clear(); + label.clear(gl, renderer); } @Override - protected void createShape(RegionRenderer renderer) { - // FIXME: Only possible if all data (color) is - // is incl. in Outline Shape. - // Until then - draw each separately! - //shape.addOutlinShape( label.getShape() ); - label.updateShape(); + protected void destroyImpl(GL2ES2 gl, RegionRenderer renderer) { + label.destroy(gl, renderer); + } - final AABBox lbox = label.getBounds(); - if(corner == 0.0f) { - createSharpOutline(lbox); - } else { - createCurvedOutline(lbox); - } - float sx = getWidth() / ( 2f*spacing + lbox.getWidth() ); - float sy = getHeight() / ( 2f*spacing + lbox.getHeight() ); + @Override + public void drawShape(GL2ES2 gl, RegionRenderer renderer, int[] sampleCount, boolean select) { + gl.glEnable(GL2ES2.GL_POLYGON_OFFSET_FILL); + gl.glPolygonOffset(0.0f, 1f); + super.drawShape(gl, renderer, sampleCount, select); + gl.glDisable(GL2ES2.GL_POLYGON_OFFSET_FILL); - setScale(sx, sy, 1); + label.drawShape(gl, renderer, sampleCount, select); } + @Override + protected void createShape(GL2ES2 gl, RegionRenderer renderer) { + label.createShape(gl, renderer); + box.resize(label.getBounds()); - private void createSharpOutline(AABBox lbox) { + final float sx = getWidth() / ( 2f*spacing + box.getWidth() ); + final float sy = getHeight() / ( 2f*spacing + box.getHeight() ); + scale(sx, sy, 1); + + final OutlineShape shape = new OutlineShape(renderer.getRenderState().getVertexFactory()); + if(corner == 0.0f) { + createSharpOutline(shape, box); + } else { + createCurvedOutline(shape, box); + } + box.resize(shape.getBounds()); + shapes.add(new TransformedShape(shape, new AffineTransform(renderer.getRenderState().getVertexFactory()))); + 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(); @@ -117,20 +126,21 @@ public abstract class RIButton extends UIShape { shape.addVertex(minX, minY + th, minZ, true); shape.closeLastOutline(true); } - - private void createCurvedOutline(AABBox lbox){ - float th = 2.0f*spacing + lbox.getHeight(); - float tw = 2.0f*spacing + lbox.getWidth(); - - float cw = 0.5f*corner*Math.min(tw, th); - float ch = 0.5f*corner*Math.min(tw, th); + 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 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; + shape.addVertex(minX, minY + ch, minZ, true); shape.addVertex(minX, minY, minZ, false); + shape.addVertex(minX + cw, minY, minZ, true); + shape.addVertex(minX + tw - cw, minY, minZ, true); shape.addVertex(minX + tw, minY, minZ, false); shape.addVertex(minX + tw, minY + ch, minZ, true); @@ -153,7 +163,7 @@ public abstract class RIButton extends UIShape { else{ this.corner = corner; } - dirty |= DIRTY_SHAPE; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } public float getLabelZOffset() { @@ -162,7 +172,7 @@ public abstract class RIButton extends UIShape { public void setLabelZOffset(float labelZOffset) { this.labelZOffset = -labelZOffset; - dirty |= DIRTY_SHAPE; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } public float getSpacing() { return spacing; @@ -175,91 +185,19 @@ public abstract class RIButton extends UIShape { else{ this.spacing = spacing; } - dirty |= DIRTY_SHAPE; - } - - public float[] getButtonColor() { - return buttonColor; - } - - public void setButtonColor(float r, float g, float b) { - this.buttonColor = new float[3]; - this.buttonColor[0] = r; - this.buttonColor[1] = g; - this.buttonColor[2] = b; + dirty |= DIRTY_SHAPE | DIRTY_REGION; } public float[] getLabelColor() { - return labelColor; - } - - private UIRegion buttonRegion = null; - private UIRegion labelRegion = null; - private boolean toggle =false; - private boolean toggleable = false; - - public void render(GL2ES2 gl, RegionRenderer renderer, int renderModes, int[/*1*/] sampleCount, boolean selection) { - if(null == buttonRegion) { - buttonRegion = new UIRegion(this); - labelRegion = new UIRegion(getLabel()); - } - - gl.glEnable(GL2ES2.GL_POLYGON_OFFSET_FILL); - gl.glPolygonOffset(0.0f, 1f); - - float[] bColor = buttonColor; - if(isPressed() || toggle){ - bColor = buttonSelectedColor; - } - if(!selection){ - renderer.setColorStatic(gl, bColor[0], bColor[1], bColor[2]); - } - buttonRegion.getRegion(gl, renderer, renderModes).draw(gl, renderer, sampleCount); - gl.glDisable(GL2ES2.GL_POLYGON_OFFSET_FILL); - - float[] lColor = labelColor; - if(isPressed() || toggle ){ - lColor = labelSelectedColor; - } - if(!selection){ - renderer.setColorStatic(gl, lColor[0], lColor[1], lColor[2]); - } - labelRegion.getRegion(gl, renderer, renderModes).draw(gl, renderer, sampleCount); - } - public void setPressed(boolean b) { - super.setPressed(b); - if(isToggleable() && b) { - toggle = !toggle; - } + return label.getColor(); } public void setLabelColor(float r, float g, float b) { - this.labelColor = new float[3]; - this.labelColor[0] = r; - this.labelColor[1] = g; - this.labelColor[2] = b; - } - - public void setButtonSelectedColor(float r, float g, float b){ - this.buttonSelectedColor = new float[3]; - this.buttonSelectedColor[0] = r; - this.buttonSelectedColor[1] = g; - this.buttonSelectedColor[2] = b; + label.setColor(r, g, b); } public void setLabelSelectedColor(float r, float g, float b){ - this.labelSelectedColor = new float[3]; - this.labelSelectedColor[0] = r; - this.labelSelectedColor[1] = g; - this.labelSelectedColor[2] = b; - } - - public boolean isToggleable() { - return toggleable; - } - - public void setToggleable(boolean toggleable) { - this.toggleable = toggleable; + label.setSelectedColor(r, g, b); } public String toString() { 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 7b62b72f9..77195646d 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 @@ -10,12 +10,16 @@ import javax.media.opengl.GL2ES2; import javax.media.opengl.GLAutoDrawable; 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; import com.jogamp.newt.event.MouseListener; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.util.PMVMatrix; public class SceneUIController implements GLEventListener{ private final ArrayList<UIShape> shapes = new ArrayList<UIShape>(); @@ -23,13 +27,13 @@ public class SceneUIController implements GLEventListener{ private int count = 0; private int renderModes; private int[] sampleCount; - private RegionRenderer renderer = null; + private RegionRenderer renderer; private final float[] translate = new float[3]; private final float[] scale = new float[3]; private final float[] rotation = new float[3]; - private final float[] sceneClearColor = new float[]{0,0,0,1}; + private final float[] sceneClearColor = new float[]{0,0,0,0}; private int activeId = -1; @@ -38,12 +42,16 @@ public class SceneUIController implements GLEventListener{ private GLAutoDrawable cDrawable = null; public SceneUIController() { + this(null, 0, null); } public SceneUIController(RegionRenderer renderer, int renderModes, int[] sampleCount) { this.renderer = renderer; this.renderModes = renderModes; this.sampleCount = sampleCount; + setScale(1f, 1f, 1f); + setTranslate(0f, 0f, 0f); + setRotation(0f, 0f, 0f); } public void setRenderer(RegionRenderer renderer, int renderModes, int[] sampleCount) { @@ -96,14 +104,9 @@ public class SceneUIController implements GLEventListener{ public void dispose(GLAutoDrawable drawable) { System.err.println("SceneUIController: dispose"); cDrawable = null; - drawable.removeGLEventListener(this); } - public void reshape(GLAutoDrawable drawable, int x, int y, int width, - int height) { - System.err.println("SceneUIController: reshape"); - GL2ES2 gl = drawable.getGL().getGL2ES2(); - renderer.reshapePerspective(gl, 45.0f, width, height, 5f, 70.0f); + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } public UIShape getShape(GLAutoDrawable drawable,int x, int y) { @@ -149,26 +152,29 @@ public class SceneUIController implements GLEventListener{ } private void render(GL2ES2 gl, int width, int height, int renderModes, int[/*1*/] sampleCount, boolean select) { - renderer.reshapePerspective(null, 45.0f, width, height, 0.1f, 7000.0f); - for(int index=0; index < count;index++){ if(select) { float color= index+1; renderer.setColorStatic(gl, color/(count+2), color/(count+2), color/(count+2)); } - float[] s = shapes.get(index).getScale(); - float[] p = shapes.get(index).getPosition(); - renderer.resetModelview(null); - renderer.translate(null, translate[0]+p[0], translate[1]+p[1], translate[2]+p[2]); - renderer.scale(gl, s[0], s[1], s[2]); - renderer.rotate(gl, rotation[0], 1, 0, 0); - renderer.rotate(gl, rotation[1], 0, 1, 0); - renderer.rotate(gl, rotation[2], 0, 0, 1); - - shapes.get(index).render(gl, renderer, renderModes, sampleCount, select); - renderer.rotate(gl, -rotation[0], 1, 0, 0); - renderer.rotate(gl, -rotation[1], 0, 1, 0); - renderer.rotate(gl, -rotation[2], 0, 0, 1); + final UIShape uiShape = shapes.get(index); + uiShape.validate(gl, renderer); + final AffineTransform t = uiShape.getTransform(); + + 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); + 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 b646c8023..587b9b3dc 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,13 +34,14 @@ 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; import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.geom.SVertex; import com.jogamp.opengl.test.junit.graph.demos.MSAATool; -import com.jogamp.opengl.test.junit.graph.demos.ui.opengl.UIRegion; public class UIGLListener01 extends UIListenerBase01 { @@ -58,7 +59,7 @@ public class UIGLListener01 extends UIListenerBase01 { } }; - button.setPosition(2,1,0); + button.translate(2,1); /** Button defaults ! button.setLabelColor(1.0f,1.0f,1.0f); button.setButtonColor(0.6f,0.6f,0.6f); @@ -84,9 +85,6 @@ public class UIGLListener01 extends UIListenerBase01 { MSAATool.dump(drawable); } - UIRegion regionButton; - UIRegion regionLabel; - public void display(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); @@ -100,30 +98,15 @@ public class UIGLListener01 extends UIListenerBase01 { regionRenderer.translate(null, getXTran(), getYTran(), getZoom()); regionRenderer.rotate(gl, getAngle(), 0, 1, 0); - final float[] bColor = button.getButtonColor(); - final float[] lColor = button.getLabelColor(); - if(null == regionButton) { - regionButton = new UIRegion(button); - regionLabel = new UIRegion(button.getLabel()); - } - - regionRenderer.setColorStatic(gl, bColor[0], bColor[1], bColor[2]); - regionRenderer.translate(gl, button.getPosition()[0], button.getPosition()[1], button.getPosition()[2]); - regionButton.getRegion(gl, regionRenderer, 0).draw(gl, regionRenderer, null); - regionRenderer.setColorStatic(gl, lColor[0], lColor[1], lColor[2]); - regionLabel.getRegion(gl, regionRenderer, 0).draw(gl, regionRenderer, null); + final int[] sampleCount = { 4 }; + final AffineTransform t = button.getTransform(); + regionRenderer.translate(gl, t.getTranslateX(), t.getTranslateY(), 0); + button.drawShape(gl, regionRenderer, sampleCount, false); } public void dispose(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); - if(null != regionButton) { - regionButton.destroy(gl, getRegionRenderer()); - regionButton = null; - } - if(null != regionLabel) { - regionLabel.destroy(gl, getRegionRenderer()); - regionButton = null; - } + button.destroy(gl, getRegionRenderer()); super.dispose(drawable); } } 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 acc91ce65..5a7b147d5 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 @@ -27,9 +27,15 @@ */ package com.jogamp.opengl.test.junit.graph.demos.ui; +import java.util.ArrayList; + import javax.media.opengl.GL2ES2; +import jogamp.graph.geom.plane.AffineTransform; + 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.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; @@ -37,93 +43,237 @@ import com.jogamp.opengl.math.geom.AABBox; public abstract class UIShape { private final Factory<? extends Vertex> vertexFactory; - protected OutlineShape shape; - protected static final int DIRTY_SHAPE = 1 << 0 ; - protected int dirty = DIRTY_SHAPE; + public class TransformedShape { + public final OutlineShape shape; + public final AffineTransform t; + + public TransformedShape(final OutlineShape shape, final AffineTransform t) { + this.shape = shape; + this.t = t; + } + } + protected final ArrayList<TransformedShape> shapes; + + protected static final int DIRTY_SHAPE = 1 << 0 ; + protected static final int DIRTY_POSITION = 1 << 1 ; + protected static final int DIRTY_REGION = 1 << 2 ; + protected int dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; + + protected final AABBox box; + protected final AffineTransform transform; + private GLRegion region = null; + + protected final float[] color = {0.6f, 0.6f, 0.6f}; + protected final float[] selectedColor = {0.8f, 0.8f, 0.8f}; private boolean down = false; + private boolean toggle =false; + private boolean toggleable = false; public UIShape(Factory<? extends Vertex> factory) { this.vertexFactory = factory; - this.shape = new OutlineShape(factory); + this.shapes = new ArrayList<TransformedShape>(); + this.box = new AABBox(); + this.transform = new AffineTransform(factory); } - public void clear() { - clearImpl(null, null); - shape.clear(); + public final Vertex.Factory<? extends Vertex> getVertexFactory() { return vertexFactory; } + + /** + * Clears all data and reset all states as if this instance was newly created + * @param gl TODO + * @param renderer TODO\ + */ + public void clear(GL2ES2 gl, RegionRenderer renderer) { + clearImpl(gl, renderer); + shapes.clear(); + transform.setToIdentity(); + box.reset(); + dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; } - public abstract void render(GL2ES2 gl, RegionRenderer renderer, int renderModes, int[/*1*/] texSize, boolean selection); + /** + * Destroys all data + * @param gl + * @param renderer + */ + public void destroy(GL2ES2 gl, RegionRenderer renderer) { + destroyImpl(gl, renderer); + shapes.clear(); + transform.setToIdentity(); + box.reset(); + dirty = DIRTY_SHAPE | DIRTY_POSITION | DIRTY_REGION; + } - protected boolean positionDirty = false; + public final void translate(float tx, float ty) { + transform.translate(tx, ty); + dirty |= DIRTY_POSITION; + } - private final float[] position = new float[]{0,0,0}; - private final float[] scale = new float[]{1.0f,1.0f,1.0f}; - public void setScale(float x, float y, float z){ - scale[0] = x; - scale[1] = y; - scale[2] = z; + public final void scale(float sx, float sy, float sz) { + transform.scale(sx, sy); } - public void setPosition(float x, float y, float z) { - this.position[0] = x; - this.position[1] = y; - this.position[2] = z; - positionDirty = true; + public final AffineTransform getTransform() { + if( !isShapeDirty() ) { + validatePosition(); + } + return transform; } - private void updatePosition () { - float minX = shape.getBounds().getLow()[0]; - float minY = shape.getBounds().getLow()[1]; - float minZ = shape.getBounds().getLow()[2]; - System.out.println("Position was: " + (position[0]) + " " + (position[1]) + " " + (position[2])); - System.out.println("Position became: " + (position[0] - minX) + " " + (position[1] - minY) + " " + (position[2] - minZ)); - setPosition(position[0] - minX, position[1] - minY, position[2] - minZ); - positionDirty = false; + public final boolean isShapeDirty() { + return 0 != ( dirty & DIRTY_SHAPE ) ; } - public float[] getScale() { return scale; } - public float[] getPosition() { return position; } + public final boolean isPositionDirty() { + return 0 != ( dirty & DIRTY_POSITION ) ; + } - protected abstract void clearImpl(GL2ES2 gl, RegionRenderer renderer); + public final boolean isRegionDirty() { + return 0 != ( dirty & DIRTY_REGION ) ; + } - protected abstract void createShape(RegionRenderer renderer); + public ArrayList<TransformedShape> getShapes() { return shapes; } - public boolean updateShape() { - if( isShapeDirty() ) { - shape.clear(); - createShape(null); - if(positionDirty){ - updatePosition(); + public final AABBox getBounds() { return box; } + + public GLRegion getRegion(GL2ES2 gl, RegionRenderer renderer) { + validate(gl, renderer); + if( isRegionDirty() ) { + if( null == region ) { + region = GLRegion.create(renderer.getRenderModes()); + } else { + region.clear(gl, renderer); } + addToRegion(region); + dirty &= ~DIRTY_REGION; + System.err.println("XXX.UIShape: updated: "+region); + } + return region; + } + + /** + * Renders {@link OutlineShape} using local {@link GLRegion} which might be cached or updated. + * <p> + * No matrix operations (translate, scale, ..) are performed. + * </p> + * @param gl + * @param renderer + * @param sampleCount + * @param select + */ + public void drawShape(GL2ES2 gl, RegionRenderer renderer, int[] sampleCount, boolean select) { + float[] _color = color; + if( isPressed() || toggle ){ + _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); + } */ + renderer.setColorStatic(gl, _color[0], _color[1], _color[2]); + } + getRegion(gl, renderer).draw(gl, renderer, sampleCount); + } + + public final boolean validate(GL2ES2 gl, RegionRenderer renderer) { + if( !validateShape(gl, renderer) ) { + return validatePosition(); + } + return true; + } + private final boolean validateShape(GL2ES2 gl, RegionRenderer renderer) { + if( isShapeDirty() ) { + shapes.clear(); + box.reset(); + createShape(gl, renderer); dirty &= ~DIRTY_SHAPE; + dirty |= DIRTY_REGION; + validatePosition(); + return true; + } + return false; + } + private final boolean validatePosition () { + if( isPositionDirty() && !isShapeDirty() ) { + // Subtract the bbox minx/miny from position, i.e. the shape's offset. + 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); + translate(-minX, -minY); + System.err.println("XXX.UIShape: Position post: " + transform.getTranslateX() + " " + transform.getTranslateY() + ", sbox "+box); + dirty &= ~DIRTY_POSITION; return true; } return false; } - public final Vertex.Factory<? extends Vertex> getVertexFactory() { return vertexFactory; } - public AABBox getBounds() { return shape.getBounds(); } + private final void addToRegion(Region region) { + final int shapeCount = shapes.size(); + for(int i=0; i<shapeCount; i++) { + final TransformedShape tshape = shapes.get(i); + region.addOutlineShape(tshape.shape, tshape.t); + } + } - public OutlineShape getShape() { - updateShape(); - return shape; + public float[] getColor() { + return color; } - public boolean isShapeDirty() { - return 0 != ( dirty & DIRTY_SHAPE ) ; + public void setColor(float r, float g, float b) { + this.color[0] = r; + this.color[1] = g; + this.color[2] = b; } + public void setSelectedColor(float r, float g, float b){ + this.selectedColor[0] = r; + this.selectedColor[1] = g; + this.selectedColor[2] = b; + } + + // + // Input + // public void setPressed(boolean b) { this.down = b; + if(isToggleable() && b) { + toggle = !toggle; + } } public boolean isPressed() { return this.down; } - public abstract void onClick(); - public abstract void onPressed(); - public abstract void onRelease(); + public boolean isToggleable() { + return toggleable; + } + + public void setToggleable(boolean toggleable) { + this.toggleable = toggleable; + } + + public void onClick() { } + public void onPressed() { } + public void onRelease() { } + + // + // + // + + protected abstract void clearImpl(GL2ES2 gl, RegionRenderer renderer); + protected abstract void destroyImpl(GL2ES2 gl, RegionRenderer renderer); + protected abstract void createShape(GL2ES2 gl, RegionRenderer renderer); + + // + // + // + } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITextShape.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITextShape.java deleted file mode 100644 index ce9073a30..000000000 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITextShape.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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.ui; - -import com.jogamp.graph.curve.opengl.GLRegion; - -/** - * Marker interface to mark a UIShape implementation for text usage - */ -public interface UITextShape { - GLRegion getRegion(); -} diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/opengl/UIRegion.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/opengl/UIRegion.java deleted file mode 100644 index 8cf987bb3..000000000 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/opengl/UIRegion.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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.ui.opengl; - -import javax.media.opengl.GL2ES2; - -import com.jogamp.graph.curve.opengl.GLRegion; -import com.jogamp.graph.curve.opengl.RegionRenderer; -import com.jogamp.opengl.test.junit.graph.demos.ui.UIShape; -import com.jogamp.opengl.test.junit.graph.demos.ui.UITextShape; - -public class UIRegion { - protected static final int DIRTY_REGION = 1 << 0 ; - protected int dirty = DIRTY_REGION; - - private final UIShape uiShape; - private GLRegion region; - - public UIRegion(UIShape uis) { - this.uiShape = uis; - } - - public boolean updateRegion(GL2ES2 gl, RegionRenderer renderer, int renderModes) { - if( uiShape.updateShape() || isRegionDirty() ) { - destroy(gl, renderer); - if(uiShape instanceof UITextShape) { - region = ((UITextShape)uiShape).getRegion(); - } else { - region = GLRegion.create(renderModes); - region.addOutlineShape(uiShape.getShape(), null); - } - dirty &= ~DIRTY_REGION; - return true; - } - return false; - } - - public GLRegion getRegion(GL2ES2 gl, RegionRenderer renderer, int renderModes) { - updateRegion(gl, renderer, renderModes); - return region; - } - - public boolean isRegionDirty() { - return 0 != ( dirty & DIRTY_REGION ) ; - } - - public void destroy(GL2ES2 gl, RegionRenderer renderer) { - if(null != region) { - region.destroy(gl, renderer); - region = null; - } - } -} |