aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/com
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-04-09 09:09:51 +0200
committerSven Gothel <[email protected]>2014-04-09 09:09:51 +0200
commitfe47c613e3e07681a5366d6ec3f071fdc4ade65d (patch)
treefd980c33b0fde468918227d31174320b8ae6b163 /src/test/com
parentff4e2b1996d2cfab1eb154020106004fb71471fd (diff)
Bug 801: Region Dirty Update; TextureSequence GLMediaPlayer Fix; Blending Fix ;
- Region Dirty Update - Split dirty -> ShapeDirty + StateDirty, where StateDirty forces re-rendering content w/o geometry update as req. for 2-pass mode. - Fix TextureSequence (GLMediaPlayer) usage in RegionRenderer / GLRegion* - handle GL_TEXTURE_EXTERNAL_OES incl. Android ES3 bug - inject TextureSequence's shader stubs - shader: Use abstract lookup 'texture2D' -> 'gcuTexture2D' - flip scaled colorTexBBox if TextureSequence 'tex.getMustFlipVertically()' - TODO: Handle multiple TextureSequence shader programs! - Fix Blending: GLRegion* / RegionRenderer / RenderState - Disable/Enable depth-writing w/ blending - Region impl. sets proper glBlendFunc*(..), i.e. 2-pass: - render2FBO: glClearColor(0f, 0f, 0f, 0f) glBlendFuncSeparate(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA, GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA) - renderFBO: glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA) - User code shall not set glClearColor(..) for 2-pass anymore - Graph-UI Demo - UIShape: - Add MouseGestureListener, combining MouseListener + GestureListener - EventDetails -> PointerEventInfo - PointerEventInfo contains objPos (ray-intersection) and glWin-pos - Toggle: - Separate color (on/off) if enabled - Toggle on click if enabled - SceneUIController - Use PinchToZoomGesture and propagete same gesture to UIShape - Use AABBox.getRayIntersection(..) using 'real' shape coordinates for 1st picking. - Use shape PMV for secondary picking (drag, zoom 2-pointer, etc), see windowToShapeCoords(..) - Sort shapes according to z-value (render: ascending; picking: descending) - Only 'drag' if pointerId matches 1st pressed pointer
Diffstat (limited to 'src/test/com')
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java14
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener0A.java243
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/CrossHair.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java343
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TextureButton.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIGLListener01.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java244
10 files changed, 586 insertions, 285 deletions
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 5704f3e7a..ad12e11e1 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
@@ -202,7 +202,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
final int height = drawable.getHeight();
GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+ gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// final float zDistance0 = 500f;
@@ -217,9 +217,6 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmv.glLoadIdentity();
rs.setColorStatic(0.1f, 0.1f, 0.1f, 1.0f);
- if( renderer.getRenderState().isHintMaskSet(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);
@@ -281,22 +278,21 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
pmv.glTranslatef(getXTran(), getYTran(), getZTran());
pmv.glRotatef(getAngle(), 0, 1, 0);
rs.setColorStatic(0.9f, 0.0f, 0.0f, 1.0f);
- if( renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED) ) {
- gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
- }
if( bottomTextUseFrustum ) {
regionBottom.setFrustum(pmv.glGetFrustum());
}
if(!userInput) {
if( bottomTextUseFrustum ) {
- TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount(), null, null);
+ TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount(),
+ textRegionUtil.tempT1, textRegionUtil.tempT2);
} else {
textRegionUtil.drawString3D(gl, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount());
}
} else {
if( bottomTextUseFrustum ) {
- TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount(), null, null);
+ TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount(),
+ textRegionUtil.tempT1, textRegionUtil.tempT2);
} else {
textRegionUtil.drawString3D(gl, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount());
}
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 f9f9d58a0..211e4c387 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
@@ -2,6 +2,8 @@ package com.jogamp.opengl.test.junit.graph.demos;
import java.io.File;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
@@ -22,8 +24,10 @@ import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.InputEvent;
-import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.PinchToZoomGesture;
+import com.jogamp.newt.event.GestureHandler.GestureEvent;
+import com.jogamp.newt.event.MouseEvent.PointerClass;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.VectorUtil;
@@ -34,8 +38,12 @@ import com.jogamp.opengl.test.junit.graph.demos.ui.RoundButton;
import com.jogamp.opengl.test.junit.graph.demos.ui.SceneUIController;
import com.jogamp.opengl.test.junit.graph.demos.ui.TextureButton;
import com.jogamp.opengl.test.junit.graph.demos.ui.UIShape;
-import com.jogamp.opengl.test.junit.jogl.demos.TextureSequenceDemo01;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
+import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
public class GPUUISceneGLListener0A implements GLEventListener {
@@ -168,7 +176,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
LabelButton button = new LabelButton(SVertex.factory(), renderModes, font, "Next Text", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart-diffY*buttons.size(), 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if( null != labels[currentText] ) {
@@ -186,8 +194,8 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button.setName(100); // FIXME: DEBUG tag
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
button.setToggleable(true);
- button.setToggleState(fpsLabel.isEnabled());
- button.addMouseListener(new MouseAdapter() {
+ button.setToggle(fpsLabel.isEnabled());
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final GLAnimatorControl a = cDrawable.getAnimator();
@@ -202,8 +210,8 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "v-sync", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
button.setToggleable(true);
- button.setToggleState(gl.getSwapInterval()>0);
- button.addMouseListener(new MouseAdapter() {
+ button.setToggle(gl.getSwapInterval()>0);
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
cDrawable.invoke(false, new GLRunnable() {
@@ -224,13 +232,13 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "< tilt >", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
- if( shapeEvent.rotPosition[0] < shapeEvent.rotBounds.getCenter()[0] ) {
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
+ if( shapeEvent.objPos[0] < shapeEvent.shape.getBounds().getCenter()[0] ) {
rotateButtons(new float[] { 0f, -5f, 0f}); // left-half pressed
} else {
rotateButtons(new float[] { 0f, 5f, 0f}); // right-half pressed
@@ -246,14 +254,14 @@ public class GPUUISceneGLListener0A implements GLEventListener {
if( pass2Mode ) { // second column to the left
button = new LabelButton(SVertex.factory(), renderModes, font, "< samples >", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
int sampleCount = sceneUIController.getSampleCount();
- if( shapeEvent.rotPosition[0] < shapeEvent.rotBounds.getCenter()[0] ) {
+ if( shapeEvent.objPos[0] < shapeEvent.shape.getBounds().getCenter()[0] ) {
// left-half pressed
if( sampleCount > 0 ) {
sampleCount-=1;
@@ -272,15 +280,15 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "< quality >", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
int quality = shapeEvent.shape.getQuality();
- if( shapeEvent.rotPosition[0] < shapeEvent.rotBounds.getCenter()[0] ) {
+ if( shapeEvent.objPos[0] < shapeEvent.shape.getBounds().getCenter()[0] ) {
// left-half pressed
if( quality > 0 ) {
quality--;
@@ -300,9 +308,10 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "Quit", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart,ystart - diffY*buttons.size(), 0f);
- button.setColor(0.8f, 0.0f, 0.0f, 1.0f);
- button.setSelectedColorMod(0.8f, 0.8f, 0.8f, 1.0f);
- button.addMouseListener(new MouseAdapter() {
+ button.setColor(0.7f, 0.0f, 0.0f, 1.0f);
+ button.setLabelColor(1.2f, 1.2f, 1.2f);
+ button.setPressedColorMod(1.1f, 0.0f, 0.0f, 1.0f);
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
new Thread() {
@@ -325,7 +334,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
int k = 0; // row
button = new LabelButton(SVertex.factory(), renderModes, font, "y flip", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
rotateButtons(new float[] { 0f, 180f, 0f});
@@ -336,7 +345,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
k++;
button = new LabelButton(SVertex.factory(), renderModes, font, "x flip", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
rotateButtons(new float[] { 180f, 0f, 0f});
@@ -347,18 +356,18 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "+", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
// rel position to center
- final float dx = shapeEvent.rotPosition[0] - shapeEvent.rotBounds.getCenter()[0] ;
- final float dy = shapeEvent.rotPosition[1] - shapeEvent.rotBounds.getCenter()[1] ;
+ final float dx = shapeEvent.objPos[0] - shapeEvent.shape.getBounds().getCenter()[0] ;
+ final float dy = shapeEvent.objPos[1] - shapeEvent.shape.getBounds().getCenter()[1] ;
// per-cent position to center (remove dependency on dimension)
- final float awdx = Math.abs(dx)/shapeEvent.rotBounds.getWidth();
- final float awdy = Math.abs(dy)/shapeEvent.rotBounds.getHeight();
+ final float awdx = Math.abs(dx)/shapeEvent.shape.getBounds().getWidth();
+ final float awdy = Math.abs(dy)/shapeEvent.shape.getBounds().getHeight();
float tx = 0, ty = 0;
if ( awdx > awdy ) {
tx = dx < 0 ? -5 : 5;
@@ -374,14 +383,14 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "< space >", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
final float dx, dy;
- if( shapeEvent.rotPosition[0] < shapeEvent.rotBounds.getCenter()[0] ) {
+ if( shapeEvent.objPos[0] < shapeEvent.shape.getBounds().getCenter()[0] ) {
dx=-0.01f; dy=-0.005f;
} else {
dx=0.01f; dy=0.005f;
@@ -398,14 +407,14 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "< corner >", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
final float dc;
- if( shapeEvent.rotPosition[0] < shapeEvent.rotBounds.getCenter()[0] ) {
+ if( shapeEvent.objPos[0] < shapeEvent.shape.getBounds().getCenter()[0] ) {
dc=-0.1f;
} else {
dc=0.1f;
@@ -423,7 +432,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "reset", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
resetButtons();
@@ -434,7 +443,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
button = new LabelButton(SVertex.factory(), renderModes, font, "screenshot", buttonXSize, buttonYSize, labelZOffset);
button.translate(xstart - diffX*j,ystart - diffY*k, 0f);
- button.addMouseListener(new MouseAdapter() {
+ button.addMouseListener(new UIShape.MouseGestureAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
cDrawable.invoke(false, new GLRunnable() {
@@ -451,15 +460,80 @@ public class GPUUISceneGLListener0A implements GLEventListener {
}
if(true) {
- final TextureSequenceDemo01 texSeq = new TextureSequenceDemo01(true);
- gl.glActiveTexture(GL.GL_TEXTURE0 + texSeq.getTextureUnit());
- texSeq.initGLResources(gl);
+ final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
final TextureButton texButton = new TextureButton(renderer.getRenderState().getVertexFactory(), renderModes,
- 2f*buttonXSize, 2f*buttonYSize, texSeq);
+ 2f*buttonXSize, 2f*buttonYSize, mPlayer) {
+ @Override
+ protected void destroyImpl(GL2ES2 gl, RegionRenderer renderer) {
+ mPlayer.destroy(gl);
+ }
+ @Override
+ public void drawShape(GL2ES2 gl, RegionRenderer renderer, int[] sampleCount) {
+ if( GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
+ try {
+ System.err.println("XXX InitGL.pre: "+mPlayer);
+ mPlayer.initGL(gl);
+ mPlayer.setAudioVolume( 0f );
+ System.err.println("XXX Play.pre: "+mPlayer);
+ GLMediaPlayer.State r = mPlayer.play();
+ System.err.println("XXX Play.post: "+r+", "+mPlayer);
+ markStateDirty();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ super.drawShape(gl, renderer, sampleCount);
+ markStateDirty(); // keep on going
+ } };
+ texButton.setEnabled(false); // wait until data is avail. (shader)
texButton.translate(xstart + diffX*5, ystart - diffY*1, 0f);
texButton.setToggleable(true);
+ texButton.setToggle(false); // toggle == false -> mute audio
+ texButton.setToggleOffColorMod(0f, 1f, 0f, 1.0f);
texButton.addMouseListener(dragZoomRotateListener);
+ texButton.addMouseListener(new UIShape.MouseGestureAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ mPlayer.setAudioVolume( texButton.isToggleOn() ? 1f : 0f );
+ } } );
buttons.add(texButton);
+ mPlayer.addEventListener(new GLMediaEventListener() {
+ @Override
+ public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) {
+ // texButton.markStateDirty();
+ }
+
+ @Override
+ public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) {
+ System.err.println("MovieCube AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("MovieCube State: "+mp);
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ texButton.setEnabled(true); // data and shader is available ..
+ }
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) {
+ // FIXME: mPlayer.resetGLState();
+ }
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
+ new Thread() {
+ public void run() {
+ // loop for-ever ..
+ mPlayer.seek(0);
+ mPlayer.play();
+ } }.start();
+ } else if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) {
+ final StreamException se = mPlayer.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ }
+ }
+ });
+ try {
+ final URI streamLoc = new URI("http://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4");
+ mPlayer.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
+ } catch (URISyntaxException e1) {
+ e1.printStackTrace();
+ }
}
}
@@ -613,7 +687,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
System.err.println("GPUUISceneGLListener0A: dispose (0)");
}
- sceneUIController.dispose(drawable);
+ sceneUIController.dispose(drawable); // disposes all registered UIShapes
GL2ES2 gl = drawable.getGL().getGL2ES2();
renderer.destroy(gl);
@@ -735,8 +809,8 @@ public class GPUUISceneGLListener0A implements GLEventListener {
* We can share this instance w/ all UI elements,
* since only mouse action / gesture is complete for a single one (press, drag, released and click).
*/
- private final MouseAdapter dragZoomRotateListener = new MouseAdapter() {
- int dragLastX=-1, dragLastY=-1;
+ private final UIShape.MouseGestureAdapter dragZoomRotateListener = new UIShape.MouseGestureAdapter() {
+ float dragFirstX=-1f, dragFirstY=-1f;
boolean dragFirst = false;
@Override
@@ -753,34 +827,23 @@ public class GPUUISceneGLListener0A implements GLEventListener {
@Override
public void mouseDragged(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
- if(e.getPointerCount()==2) {
- // 2 pointers zoom ..
- if(dragFirst) {
- dragLastX = Math.abs(e.getY(0)-e.getY(1));
- dragFirst=false;
- return;
- }
- int nv = Math.abs(e.getY(0)-e.getY(1));
- int dy = nv - dragLastX;
- dragLastX = nv;
-
- shapeEvent.shape.translate(0f, 0f, 2 * Math.signum(dy));
- } else {
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
+ if( e.getPointerCount() == 1 ) {
// 1 pointer drag
if(dragFirst) {
- dragLastX = e.getX();
- dragLastY = e.getY();
+ dragFirstX = shapeEvent.objPos[0]; // e.getX();
+ dragFirstY = shapeEvent.objPos[1]; // e.getY();
dragFirst=false;
return;
}
- final int nx = e.getX();
- final int ny = e.getY();
- shapeEvent.shape.translate(nx-dragLastX, -(ny-dragLastY), 0f);
- dragLastX = nx;
- dragLastY = ny;
- float[] tx = shapeEvent.shape.getTranslate();
+ final float nx = shapeEvent.objPos[0]; // e.getX();
+ final float ny = shapeEvent.objPos[1]; // e.getY();
+ final float dx = nx - dragFirstX;
+ final float dy = ny - dragFirstY;
+ // final float dy = -(ny - dragLastY);
+ shapeEvent.shape.translate(dx, dy, 0f);
+ final float[] tx = shapeEvent.shape.getTranslate();
actionText = String.format("Pos %6.2f / %6.2f / %6.2f", tx[0], tx[1], tx[2]);
}
}
@@ -789,15 +852,37 @@ public class GPUUISceneGLListener0A implements GLEventListener {
@Override
public void mouseWheelMoved(MouseEvent e) {
final Object attachment = e.getAttachment();
- if( attachment instanceof UIShape.EventDetails ) {
- final UIShape.EventDetails shapeEvent = (UIShape.EventDetails)attachment;
- if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) ) {
- float tz = 8f*e.getRotation()[1]; // vertical: wheel
- System.err.println("tz.4 "+tz);
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
+ final boolean isOnscreen = PointerClass.Onscreen == e.getPointerType(0).getPointerClass();
+ if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) && !isOnscreen ) {
+ // offscreen vertical mouse wheel zoom
+ final float tz = 8f*e.getRotation()[1]; // vertical: wheel
+ System.err.println("Rotate.Zoom.W: "+tz);
+ shapeEvent.shape.translate(0f, 0f, tz);
+ } else if( isOnscreen || e.isControlDown() ) {
+ final float[] rot = VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f);
+ if( isOnscreen ) {
+ System.err.println("XXX: "+e);
+ // swap axis for onscreen rotation matching natural feel
+ final float tmp = rot[0]; rot[0] = rot[1]; rot[1] = tmp;
+ VectorUtil.scaleVec3(rot, rot, 2f);
+ }
+ shapeEvent.shape.getRotation().rotateByEuler( rot );
+ }
+ }
+ }
+ @Override
+ public void gestureDetected(GestureEvent e) {
+ final Object attachment = e.getAttachment();
+ if( attachment instanceof UIShape.PointerEventInfo ) {
+ final UIShape.PointerEventInfo shapeEvent = (UIShape.PointerEventInfo)attachment;
+ if( e instanceof PinchToZoomGesture.ZoomEvent ) {
+ final PinchToZoomGesture.ZoomEvent ze = (PinchToZoomGesture.ZoomEvent) e;
+ final float tz = ze.getDelta() * ze.getScale();
+ System.err.println("Rotate.Zoom.G: "+tz);
shapeEvent.shape.translate(0f, 0f, tz);
- } else if( e.isControlDown() ) {
- shapeEvent.shape.getRotation().rotateByEuler( VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f) );
}
}
- } };
+ } };
} \ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/CrossHair.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/CrossHair.java
index a15e2acdd..1056bb0f9 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/CrossHair.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/CrossHair.java
@@ -104,7 +104,7 @@ public class CrossHair extends UIShape {
}
@Override
- public String toString() {
- return "CrossHair [" + translate[0]+getWidth()/2f+" / "+translate[1]+getHeight()/2f+" "+getWidth() + "x" + getHeight() + ", "+box+"]";
+ public String getSubString() {
+ return super.getSubString()+", dim "+getWidth() + "x" + getHeight();
}
}
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 37a82fe0f..175d18135 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
@@ -110,7 +110,8 @@ public class Label extends UIShape {
}
@Override
- public String toString(){
- return "Label [" + font.toString() + ", size " + pixelSize + ", " + getText() + "]";
+ public String getSubString() {
+ final int m = Math.min(text.length(), 8);
+ return super.getSubString()+", psize " + pixelSize + ", '" + text.substring(0, m)+"'";
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
index 336ce7526..573dd5604 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
@@ -99,6 +99,7 @@ public class Label0 {
@Override
public final String toString(){
- return "Label0 [" + font.toString() + ", " + getText() + "]";
+ final int m = Math.min(text.length(), 8);
+ return "Label0 ['" + text.substring(0, m) + "']";
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
index 64cf794c6..90237f56c 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
@@ -56,9 +56,12 @@ public class LabelButton extends RoundButton {
final Font labelFont, final String labelText,
final float width, final float height, final float labelZOffset) {
super(factory, renderModes | Region.COLORCHANNEL_RENDERING_BIT, width, height);
- this.label = new Label0(labelFont, labelText, new float[] { 0.9f, 0.9f, 0.9f, 1.0f });
+ this.label = new Label0(labelFont, labelText, new float[] { 1.33f, 1.33f, 1.33f, 1.0f }); // 0.75 * 1.33 = 1.0
this.labelZOffset = labelZOffset;
- setLabelColor(1.0f, 1.0f, 1.0f);
+ setColor(0.75f, 0.75f, 0.75f, 1.0f);
+ setPressedColorMod(0.9f, 0.9f, 0.9f, 0.7f);
+ setToggleOffColorMod(0.65f, 0.65f, 0.65f, 1.0f);
+ setToggleOnColorMod(0.85f, 0.85f, 0.85f, 1.0f);
}
@Override
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 45907ad6a..4581223d7 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
@@ -1,6 +1,8 @@
package com.jogamp.opengl.test.junit.graph.demos.ui;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
@@ -10,8 +12,12 @@ import javax.media.opengl.GLRunnable;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.newt.event.GestureHandler;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.PinchToZoomGesture;
+import com.jogamp.newt.event.GestureHandler.GestureEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.Quaternion;
@@ -35,9 +41,12 @@ public class SceneUIController implements GLEventListener{
private final float[] sceneScale = new float[3];
private final float[] scenePlaneOrigin = new float[3];
- private int activeId = -1;
+
+ private volatile UIShape activeShape = null;
private SBCMouseListener sbcMouseListener = null;
+ private SBCGestureListener sbcGestureListener = null;
+ private PinchToZoomGesture pinchToZoomGesture = null;
private GLAutoDrawable cDrawable = null;
@@ -61,12 +70,21 @@ public class SceneUIController implements GLEventListener{
if(null == sbcMouseListener) {
sbcMouseListener = new SBCMouseListener();
window.addMouseListener(sbcMouseListener);
+ sbcGestureListener = new SBCGestureListener();
+ window.addGestureListener(sbcGestureListener);
+ pinchToZoomGesture = new PinchToZoomGesture(window.getNativeSurface(), false);
+ window.addGestureHandler(pinchToZoomGesture);
}
}
public void detachInputListenerFrom(GLWindow window) {
if(null != sbcMouseListener) {
window.removeMouseListener(sbcMouseListener);
+ sbcMouseListener = null;
+ window.removeGestureListener(sbcGestureListener);
+ sbcGestureListener = null;
+ window.removeGestureHandler(pinchToZoomGesture);
+ pinchToZoomGesture = null;
}
}
@@ -76,7 +94,6 @@ public class SceneUIController implements GLEventListener{
public void addShape(UIShape b) {
shapes.add(b);
}
-
public void removeShape(UIShape b) {
shapes.remove(b);
}
@@ -109,41 +126,6 @@ public class SceneUIController implements GLEventListener{
cDrawable = drawable;
}
- public int pickShape(final int glWinX, final int glWinY) {
- final float winZ0 = 0f;
- final float winZ1 = 0.3f;
- /**
- final FloatBuffer winZRB = Buffers.newDirectFloatBuffer(1);
- gl.glReadPixels( x, y, 1, 1, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, winZRB);
- winZ1 = winZRB.get(0); // dir
- */
-
- final PMVMatrix pmv = renderer.getMatrix();
- pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
-
- final Ray ray = new Ray();
- final int shapeCount = shapes.size();
- for(int i=0; i<shapeCount; i++) {
- final UIShape uiShape = shapes.get(i);
- if( uiShape.isEnabled() ) {
- pmv.glPushMatrix();
- transformShape(pmv, uiShape);
-
- pmv.gluUnProjectRay(glWinX, glWinY, winZ0, winZ1, viewport, 0, ray);
- // System.err.printf("Pick: mapped.0: [%d, %d, %f/%f] -> %s%n", winX, winY, winZ0, winZ1, ray);
-
- pmv.glPopMatrix();
- final AABBox box = shapes.get(i).getBounds();
- final boolean hit = box.intersectsRay(ray);
- // System.err.println("Test: "+box+" -> hit "+hit+", shape: "+uiShape);
- if( hit ) {
- return i;
- }
- }
- }
- return -1;
- }
-
private void transformShape(final PMVMatrix pmv, final UIShape uiShape) {
final float[] uiTranslate = uiShape.getTranslate();
pmv.glTranslatef(uiTranslate[0], uiTranslate[1], uiTranslate[2]);
@@ -173,6 +155,21 @@ public class SceneUIController implements GLEventListener{
}
}
+ private static Comparator<UIShape> shapeZAscComparator = new Comparator<UIShape>() {
+ @Override
+ public int compare(final UIShape s1, final UIShape s2) {
+ final float s1Z = s1.getBounds().getMinZ()+s1.getTranslate()[2];
+ final float s2Z = s2.getBounds().getMinZ()+s2.getTranslate()[2];
+ if( FloatUtil.isEqual(s1Z, s2Z, FloatUtil.EPSILON) ) {
+ return 0;
+ } else if( s1Z < s2Z ){
+ return -1;
+ } else {
+ return 1;
+ }
+ } };
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void display(GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -183,9 +180,17 @@ public class SceneUIController implements GLEventListener{
final PMVMatrix pmv = renderer.getMatrix();
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- final int shapeCount = shapes.size();
+ final Object[] shapesS = shapes.toArray();
+ Arrays.sort(shapesS, (Comparator)shapeZAscComparator);
+
+ renderer.enable(gl, true);
+
+ //final int shapeCount = shapes.size();
+ final int shapeCount = shapesS.length;
for(int i=0; i<shapeCount; i++) {
- final UIShape uiShape = shapes.get(i);
+ // final UIShape uiShape = shapes.get(i);
+ final UIShape uiShape = (UIShape)shapesS[i];
+ // System.err.println("Id "+i+": "+uiShape);
if( uiShape.isEnabled() ) {
uiShape.validate(gl, renderer);
pmv.glPushMatrix();
@@ -194,11 +199,108 @@ public class SceneUIController implements GLEventListener{
pmv.glPopMatrix();
}
}
+
+ renderer.enable(gl, false);
+ }
+
+ public void pickShape(final int glWinX, final int glWinY, final float[] objPos, final UIShape[] shape, final Runnable runnable) {
+ if( null == cDrawable ) {
+ return;
+ }
+ cDrawable.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(GLAutoDrawable drawable) {
+ shape[0] = pickShapeImpl(glWinX, glWinY, objPos);
+ if( null != shape[0] ) {
+ runnable.run();
+ }
+ return true;
+ } } );
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private UIShape pickShapeImpl(final int glWinX, final int glWinY, final float[] objPos) {
+ final float winZ0 = 0f;
+ final float winZ1 = 0.3f;
+ /**
+ final FloatBuffer winZRB = Buffers.newDirectFloatBuffer(1);
+ gl.glReadPixels( x, y, 1, 1, GL2ES2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, winZRB);
+ winZ1 = winZRB.get(0); // dir
+ */
+ final PMVMatrix pmv = renderer.getMatrix();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+
+ final Ray ray = new Ray();
+
+ final Object[] shapesS = shapes.toArray();
+ Arrays.sort(shapesS, (Comparator)shapeZAscComparator);
+
+ for(int i=shapesS.length-1; i>=0; i--) {
+ final UIShape uiShape = (UIShape)shapesS[i];
+
+ if( uiShape.isEnabled() ) {
+ pmv.glPushMatrix();
+ transformShape(pmv, uiShape);
+ final boolean ok = pmv.gluUnProjectRay(glWinX, glWinY, winZ0, winZ1, viewport, 0, ray);
+ pmv.glPopMatrix();
+ if( ok ) {
+ final AABBox sbox = uiShape.getBounds();
+ if( sbox.intersectsRay(ray) ) {
+ // System.err.printf("Pick.0: shape %d, [%d, %d, %f/%f] -> %s%n", i, glWinX, glWinY, winZ0, winZ1, ray);
+ if( null == sbox.getRayIntersection(objPos, ray, FloatUtil.EPSILON, true, dpyTmp1V3, dpyTmp2V3, dpyTmp3V3) ) {
+ throw new InternalError("Ray "+ray+", box "+sbox);
+ }
+ // System.err.printf("Pick.1: shape %d @ [%f, %f, %f], within %s%n", i, objPos[0], objPos[1], objPos[2], uiShape.getBounds());
+ return uiShape;
+ }
+ }
+ }
+ }
+ return null;
+ }
+ private final float[] dpyTmp1V3 = new float[3];
+ private final float[] dpyTmp2V3 = new float[3];
+ private final float[] dpyTmp3V3 = new float[3];
+
+ public void windowToShapeCoords(final UIShape activeShape, final int glWinX, final int glWinY, final float[] objPos, final Runnable runnable) {
+ if( null == cDrawable || null == activeShape ) {
+ return;
+ }
+ cDrawable.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(GLAutoDrawable drawable) {
+ if( windowToShapeCoordsImpl(activeShape, glWinX, glWinY, objPos) ) {
+ runnable.run();
+ }
+ return true;
+ } } );
+ }
+ private boolean windowToShapeCoordsImpl(final UIShape activeShape, final int glWinX, final int glWinY, final float[] objPos) {
+ final PMVMatrix pmv = renderer.getMatrix();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+
+ pmv.glPushMatrix();
+ transformShape(pmv, activeShape);
+ boolean res = false;
+ final float[] ctr = activeShape.getBounds().getCenter();
+ if( pmv.gluProject(ctr[0], ctr[1], ctr[2], viewport, 0, dpyTmp1V3, 0) ) {
+ // System.err.printf("winToShapeCoords.0: shape %d: obj [%f, %f, %f] -> win [%f, %f, %f]%n", shapeId, ctr[0], ctr[1], ctr[2], dpyTmp1V3[0], dpyTmp1V3[1], dpyTmp1V3[2]);
+ if( pmv.gluUnProject(glWinX, glWinY, dpyTmp1V3[2], viewport, 0, objPos, 0) ) {
+ // System.err.printf("winToShapeCoords.1: shape %d: win [%d, %d, %f] -> obj [%f, %f, %f]%n", shapeId, glWinX, glWinY, dpyTmp1V3[2], objPos[0], objPos[1], objPos[2]);
+ res = true;
+ }
+ }
+ pmv.glPopMatrix();
+ return res;
}
@Override
public void dispose(GLAutoDrawable drawable) {
System.err.println("SceneUIController: dispose");
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ for(int i=0; i<shapes.size(); i++) {
+ shapes.get(i).destroy(gl, renderer);
+ }
+ shapes.clear();
cDrawable = null;
}
@@ -229,12 +331,11 @@ public class SceneUIController implements GLEventListener{
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);
+ mapWin2ObjectCoords(pmv, viewport, 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);
+ mapWin2ObjectCoords(pmv, viewport, 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
@@ -261,71 +362,128 @@ public class SceneUIController implements GLEventListener{
pmv.glScalef(sceneScale[0], sceneScale[1], sceneScale[2]);
}
- public UIShape getActiveUI() {
- if( 0 > activeId ) {
+ public final UIShape getShape(final int id) {
+ if( 0 > id ) {
return null;
}
- return shapes.get(activeId);
+ return shapes.get(id);
+ }
+ public final UIShape getActiveShape() {
+ return activeShape;
}
public void release() {
- activeId = -1;
+ setActiveShape(null);
+ }
+ private void setActiveShape(final UIShape shape) {
+ activeShape = shape;
}
- private class SBCMouseListener implements MouseListener {
- int lx=-1, ly=-1;
+ private final class SBCGestureListener implements GestureHandler.GestureListener {
+ @Override
+ public void gestureDetected(final GestureEvent gh) {
+ if( null != activeShape ) {
+ // gesture .. delegate to active shape!
+ final InputEvent orig = gh.getTrigger();
+ if( orig instanceof MouseEvent ) {
+ final MouseEvent e = (MouseEvent) orig;
+ // flip to GL window coordinates
+ final int glWinX = e.getX();
+ final int glWinY = viewport[3] - e.getY() - 1;
+ final float[] objPos = new float[3];
+ final UIShape shape = activeShape;
+ windowToShapeCoords(shape, glWinX, glWinY, objPos, new Runnable() {
+ public void run() {
+ shape.dispatchGestureEvent(gh, glWinX, glWinY, objPos);
+ } } );
+ }
+ }
+ }
+ }
- void clear() {
- lx = -1; ly = -1;
+ final void dispatchMouseEvent(final MouseEvent e, final int glWinX, final int glWinY) {
+ if( null == activeShape ) {
+ dispatchMouseEventPickShape(e, glWinX, glWinY, true);
+ } else {
+ dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
}
+ }
+ final void dispatchMouseEventPickShape(final MouseEvent e, final int glWinX, final int glWinY, final boolean setActive) {
+ final float[] objPos = new float[3];
+ final UIShape[] shape = { null };
+ pickShape(glWinX, glWinY, objPos, shape, new Runnable() {
+ public void run() {
+ if( setActive ) {
+ setActiveShape(shape[0]);
+ }
+ shape[0].dispatchMouseEvent(e, glWinX, glWinY, objPos);
+ } } );
+ }
+ final void dispatchMouseEventForShape(final UIShape shape, final MouseEvent e, final int glWinX, final int glWinY) {
+ final float[] objPos = new float[3];
+ windowToShapeCoords(shape, glWinX, glWinY, objPos, new Runnable() {
+ public void run() {
+ shape.dispatchMouseEvent(e, glWinX, glWinY, objPos);
+ } } );
+ }
- @Override
- public void mouseClicked(MouseEvent e) {
- UIShape uiShape = getActiveUI();
- if(uiShape != null){
- uiShape.dispatchMouseEvent(e, e.getX(), viewport[3]-e.getY());
- }
- clear();
- release();
+ private class SBCMouseListener implements MouseListener {
+ int lx=-1, ly=-1, lId=-1;
+
+ void clear() {
+ lx = -1; ly = -1; lId = -1;
}
@Override
public void mousePressed(final MouseEvent e) {
- if(null==cDrawable) {
- return;
+ if( -1 == lId || e.getPointerId(0) == lId ) {
+ lx = e.getX();
+ ly = e.getY();
+ lId = e.getPointerId(0);
}
-
// flip to GL window coordinates
final int glWinX = e.getX();
- final int glWinY = viewport[3] - e.getY();
-
- // Avoid race condition w/ matrix instance,
- // even thought we do not require a GL operation!
- cDrawable.invoke(true, new GLRunnable() {
- @Override
- public boolean run(GLAutoDrawable drawable) {
- activeId = pickShape(glWinX, glWinY);
- final UIShape uiShape = getActiveUI();
- if(uiShape != null) {
- uiShape.dispatchMouseEvent(e, glWinX, glWinY);
- }
- return true;
- } } );
+ final int glWinY = viewport[3] - e.getY() - 1;
+ dispatchMouseEvent(e, glWinX, glWinY);
}
@Override
public void mouseReleased(MouseEvent e) {
- final UIShape uiShape = getActiveUI();
- if(uiShape != null){
- uiShape.dispatchMouseEvent(e, e.getX(), viewport[3]-e.getY());
+ // flip to GL window coordinates
+ final int glWinX = e.getX();
+ final int glWinY = viewport[3] - e.getY() - 1;
+ dispatchMouseEvent(e, glWinX, glWinY);
+ if( 1 == e.getPointerCount() ) {
+ // Release active shape: last pointer has been lifted!
+ release();
+ clear();
}
}
@Override
- public void mouseDragged(MouseEvent e) {
- final UIShape uiShape = getActiveUI();
- if(uiShape != null) {
- uiShape.dispatchMouseEvent(e, e.getX(), viewport[3]-e.getY());
+ public void mouseClicked(final MouseEvent e) {
+ // flip to GL window coordinates
+ final int glWinX = e.getX();
+ final int glWinY = viewport[3] - e.getY() - 1;
+ // activeId should have been released by mouseRelease() already!
+ dispatchMouseEventPickShape(e, glWinX, glWinY, false);
+ // Release active shape: last pointer has been lifted!
+ release();
+ clear();
+ }
+
+ @Override
+ public void mouseDragged(final MouseEvent e) {
+ // drag activeShape, if no gesture-activity, only on 1st pointer
+ if( null != activeShape && !pinchToZoomGesture.isWithinGesture() && e.getPointerId(0) == lId ) {
+ lx = e.getX();
+ ly = e.getY();
+
+ // dragged .. delegate to active shape!
+ // flip to GL window coordinates
+ final int glWinX = lx;
+ final int glWinY = viewport[3] - ly - 1;
+ dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
}
}
@@ -333,24 +491,17 @@ public class SceneUIController implements GLEventListener{
public void mouseWheelMoved(final MouseEvent e) {
// flip to GL window coordinates
final int glWinX = lx;
- final int glWinY = viewport[3] - ly;
-
- cDrawable.invoke(true, new GLRunnable() {
- @Override
- public boolean run(GLAutoDrawable drawable) {
- activeId = pickShape(glWinX, glWinY);
- final UIShape uiShape = getActiveUI();
- if(uiShape != null) {
- uiShape.dispatchMouseEvent(e, glWinX, glWinY);
- }
- return true;
- } } );
+ final int glWinY = viewport[3] - ly - 1;
+ dispatchMouseEventPickShape(e, glWinX, glWinY, true);
}
@Override
public void mouseMoved(MouseEvent e) {
- lx = e.getX();
- ly = e.getY();
+ if( -1 == lId || e.getPointerId(0) == lId ) {
+ lx = e.getX();
+ ly = e.getY();
+ lId = e.getPointerId(0);
+ }
}
@Override
public void mouseEntered(MouseEvent e) { }
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TextureButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TextureButton.java
index eeb5e19f3..5b00d1e3b 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TextureButton.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TextureButton.java
@@ -47,8 +47,10 @@ public class TextureButton extends RoundButton {
final float width, final float height, final TextureSequence texSeq) {
super(factory, renderModes | Region.COLORTEXTURE_RENDERING_BIT, width, height);
this.texSeq = texSeq;
- setColor(1.0f, 1.0f, 1.0f, 1.0f);
- setSelectedColorMod(0.9f, 0.9f, 0.9f, 0.9f);
+ setColor(0.8f, 0.8f, 0.8f, 1.0f);
+ setPressedColorMod(1.1f, 1.1f, 1.1f, 0.7f);
+ setToggleOffColorMod(0.8f, 0.8f, 0.8f, 1.0f);
+ setToggleOnColorMod(1.0f, 1.0f, 1.0f, 1.0f);
}
@Override
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 90eb7d4f0..d019e696e 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
@@ -100,7 +100,7 @@ public class UIGLListener01 extends UIListenerBase01 {
@Override
public void dispose(GLAutoDrawable drawable) {
- GL2ES2 gl = drawable.getGL().getGL2ES2();
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
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 419370af9..2e9d33a78 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
@@ -36,20 +36,21 @@ 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.newt.event.GestureHandler.GestureEvent;
+import com.jogamp.newt.event.GestureHandler.GestureListener;
+import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.NEWTEvent;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.opengl.math.Quaternion;
-import com.jogamp.opengl.math.VectorUtil;
import com.jogamp.opengl.math.geom.AABBox;
public abstract class UIShape {
public static final boolean DRAW_DEBUG_BOX = false;
- protected static final int DIRTY_SHAPE = 1 << 0 ;
+ protected static final int DIRTY_SHAPE = 1 << 0 ;
protected static final int DIRTY_STATE = 1 << 1 ;
private final Factory<? extends Vertex> vertexFactory;
@@ -67,16 +68,22 @@ public abstract class UIShape {
protected int dirty = DIRTY_SHAPE | DIRTY_STATE;
protected float shapesSharpness = OutlineShape.DEFAULT_SHARPNESS;
- protected final float[] rgbaColor = {0.6f, 0.6f, 0.6f, 1.0f};
- protected final float[] selectedRGBAModulate = {1.4f, 1.4f, 1.4f, 1.0f};
+ /** Default base-color w/o color channel, will be modulated w/ pressed- and toggle color */
+ protected final float[] rgbaColor = {0.75f, 0.75f, 0.75f, 1.0f};
+ /** Default pressed color-factor w/o color channel, modulated base-color. 0.75 * 1.2 = 0.9 */
+ protected final float[] pressedRGBAModulate = {1.2f, 1.2f, 1.2f, 0.7f};
+ /** Default toggle color-factor w/o color channel, modulated base-color. 0.75 * 1.13 ~ 0.85 */
+ protected final float[] toggleOnRGBAModulate = {1.13f, 1.13f, 1.13f, 1.0f};
+ /** Default toggle color-factor w/o color channel, modulated base-color. 0.75 * 0.86 ~ 0.65 */
+ protected final float[] toggleOffRGBAModulate = {0.86f, 0.86f, 0.86f, 1.0f};
private int name = -1;
private boolean down = false;
- private boolean toggle =false;
+ private boolean toggle = false;
private boolean toggleable = false;
private boolean enabled = true;
- private ArrayList<MouseListener> mouseListeners = new ArrayList<MouseListener>();
+ private ArrayList<MouseGestureListener> mouseListeners = new ArrayList<MouseGestureListener>();
public UIShape(final Factory<? extends Vertex> factory, final int renderModes) {
this.vertexFactory = factory;
@@ -199,35 +206,58 @@ public abstract class UIShape {
*/
public void drawShape(GL2ES2 gl, RegionRenderer renderer, int[] sampleCount) {
final float r, g, b, a;
- final boolean isSelect;
- if( isPressed() || getToggleState() ) {
- isSelect = true;
- r = rgbaColor[0]*selectedRGBAModulate[0];
- g = rgbaColor[1]*selectedRGBAModulate[1];
- b = rgbaColor[2]*selectedRGBAModulate[2];
- a = rgbaColor[3]*selectedRGBAModulate[3];
- } else {
- isSelect = false;
- r = rgbaColor[0];
- g = rgbaColor[1];
- b = rgbaColor[2];
- a = rgbaColor[3];
- }
-
- if( renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED) ) {
- gl.glClearColor(r, g, b, 0.0f);
- }
- final RenderState rs = renderer.getRenderState();
-
- if( Region.hasColorChannel( renderModes ) || Region.hasColorTexture( renderModes ) ) {
- if( isSelect ) {
- rs.setColorStatic(selectedRGBAModulate[0], selectedRGBAModulate[1], selectedRGBAModulate[2], selectedRGBAModulate[3]);
+ final boolean isPressed = isPressed(), isToggleOn = isToggleOn();
+ final boolean modBaseColor = !Region.hasColorChannel( renderModes ) && !Region.hasColorTexture( renderModes );
+ if( modBaseColor ) {
+ if( isPressed ) {
+ r = rgbaColor[0]*pressedRGBAModulate[0];
+ g = rgbaColor[1]*pressedRGBAModulate[1];
+ b = rgbaColor[2]*pressedRGBAModulate[2];
+ a = rgbaColor[3]*pressedRGBAModulate[3];
+ } else if( isToggleable() ) {
+ if( isToggleOn ) {
+ r = rgbaColor[0]*toggleOnRGBAModulate[0];
+ g = rgbaColor[1]*toggleOnRGBAModulate[1];
+ b = rgbaColor[2]*toggleOnRGBAModulate[2];
+ a = rgbaColor[3]*toggleOnRGBAModulate[3];
+ } else {
+ r = rgbaColor[0]*toggleOffRGBAModulate[0];
+ g = rgbaColor[1]*toggleOffRGBAModulate[1];
+ b = rgbaColor[2]*toggleOffRGBAModulate[2];
+ a = rgbaColor[3]*toggleOffRGBAModulate[3];
+ }
} else {
- rs.setColorStatic(1.0f, 1.0f, 1.0f, 1.0f);
+ r = rgbaColor[0];
+ g = rgbaColor[1];
+ b = rgbaColor[2];
+ a = rgbaColor[3];
}
} else {
- rs.setColorStatic(r, g, b, a);
+ if( isPressed ) {
+ r = pressedRGBAModulate[0];
+ g = pressedRGBAModulate[1];
+ b = pressedRGBAModulate[2];
+ a = pressedRGBAModulate[3];
+ } else if( isToggleable() ) {
+ if( isToggleOn ) {
+ r = toggleOnRGBAModulate[0];
+ g = toggleOnRGBAModulate[1];
+ b = toggleOnRGBAModulate[2];
+ a = toggleOnRGBAModulate[3];
+ } else {
+ r = toggleOffRGBAModulate[0];
+ g = toggleOffRGBAModulate[1];
+ b = toggleOffRGBAModulate[2];
+ a = toggleOffRGBAModulate[3];
+ }
+ } else {
+ r = rgbaColor[0];
+ g = rgbaColor[1];
+ b = rgbaColor[2];
+ a = rgbaColor[3];
+ }
}
+ renderer.getRenderState().setColorStatic(r, g, b, a);
getRegion(gl, renderer).draw(gl, renderer, sampleCount);
}
@@ -252,12 +282,10 @@ public abstract class UIShape {
region.addOutlineShape(shape, null, rgbaColor);
}
region.setQuality(regionQuality);
- // dirty &= ~(DIRTY_SHAPE | DIRTY_STATE);
- dirty = 0;
+ dirty &= ~(DIRTY_SHAPE|DIRTY_STATE);
} else if( isStateDirty() ) {
- region.markDirty();
- // dirty &= ~DIRTY_STATE;
- dirty = 0;
+ region.markStateDirty();
+ dirty &= ~DIRTY_STATE;
}
}
@@ -286,14 +314,27 @@ public abstract class UIShape {
this.rgbaColor[2] = b;
this.rgbaColor[3] = a;
}
- public final void setSelectedColorMod(float r, float g, float b, float a){
- this.selectedRGBAModulate[0] = r;
- this.selectedRGBAModulate[1] = g;
- this.selectedRGBAModulate[2] = b;
- this.selectedRGBAModulate[3] = a;
+ public final void setPressedColorMod(float r, float g, float b, float a) {
+ this.pressedRGBAModulate[0] = r;
+ this.pressedRGBAModulate[1] = g;
+ this.pressedRGBAModulate[2] = b;
+ this.pressedRGBAModulate[3] = a;
+ }
+ public final void setToggleOnColorMod(float r, float g, float b, float a) {
+ this.toggleOnRGBAModulate[0] = r;
+ this.toggleOnRGBAModulate[1] = g;
+ this.toggleOnRGBAModulate[2] = b;
+ this.toggleOnRGBAModulate[3] = a;
+ }
+ public final void setToggleOffColorMod(float r, float g, float b, float a) {
+ this.toggleOffRGBAModulate[0] = r;
+ this.toggleOffRGBAModulate[1] = g;
+ this.toggleOffRGBAModulate[2] = b;
+ this.toggleOffRGBAModulate[3] = a;
}
- public String toString() {
+ @Override
+ public final String toString() {
return getClass().getSimpleName()+"["+getSubString()+"]";
}
@@ -307,12 +348,8 @@ public abstract class UIShape {
public void setPressed(final boolean b) {
this.down = b;
- if( isToggleable() && b ) {
- toggle = !toggle;
- }
markStateDirty();
}
-
public boolean isPressed() {
return this.down;
}
@@ -320,60 +357,93 @@ public abstract class UIShape {
public void setToggleable(final boolean toggleable) {
this.toggleable = toggleable;
}
-
public boolean isToggleable() {
return toggleable;
}
-
- public void setToggleState(final boolean v) {
+ public void setToggle(final boolean v) {
toggle = v;
markStateDirty();
}
- public boolean getToggleState() { return toggle; }
+ public void toggle() {
+ if( isToggleable() ) {
+ toggle = !toggle;
+ }
+ markStateDirty();
+ }
+ public boolean isToggleOn() { return toggle; }
- public final void addMouseListener(final MouseListener l) {
+ public final void addMouseListener(final MouseGestureListener l) {
if(l == null) {
return;
}
@SuppressWarnings("unchecked")
- ArrayList<MouseListener> clonedListeners = (ArrayList<MouseListener>) mouseListeners.clone();
+ final ArrayList<MouseGestureListener> clonedListeners = (ArrayList<MouseGestureListener>) mouseListeners.clone();
clonedListeners.add(l);
mouseListeners = clonedListeners;
}
- public final void removeMouseListener(MouseListener l) {
+ public final void removeMouseListener(final MouseGestureListener l) {
if (l == null) {
return;
}
@SuppressWarnings("unchecked")
- ArrayList<MouseListener> clonedListeners = (ArrayList<MouseListener>) mouseListeners.clone();
+ final ArrayList<MouseGestureListener> clonedListeners = (ArrayList<MouseGestureListener>) mouseListeners.clone();
clonedListeners.remove(l);
mouseListeners = clonedListeners;
}
/**
+ * Combining {@link MouseListener} and {@link GestureListener}
+ */
+ public static interface MouseGestureListener extends MouseListener, GestureListener {
+ }
+
+ /**
+ * Convenient adapter combining dummy implementation for {@link MouseListener} and {@link GestureListener}
+ */
+ public static abstract class MouseGestureAdapter extends MouseAdapter implements MouseGestureListener {
+ @Override
+ public void gestureDetected(GestureEvent gh) {
+ }
+ }
+
+ /**
* {@link UIShape} event details for propagated {@link NEWTEvent}s
* containing reference of {@link #shape the intended shape} as well as
- * the {@link #rotPosition rotated relative position} and {@link #rotBounds bounding box}.
+ * the {@link #objPos rotated relative position} and {@link #rotBounds bounding box}.
* The latter fields are also normalized to lower-left zero origin, allowing easier usage.
*/
- public static class EventDetails {
+ public static class PointerEventInfo {
/** The intended {@link UIShape} instance for this event */
public final UIShape shape;
- /** The {@link AABBox} of the intended {@link UIShape}, rotated about {@link UIShape#getRotation()} and normalized to lower-left zero origin.*/
- public final AABBox rotBounds;
- /** The relative mouse pointer position inside the intended {@link UIShape}, rotated about {@link UIShape#getRotation()} and normalized to lower-left zero origin. */
- public final float[] rotPosition;
-
- EventDetails(final UIShape shape, final AABBox rotatedBounds, final float[] rotatedRelPos) {
+ /** The relative pointer position inside the intended {@link UIShape}. */
+ public final float[] objPos;
+ /** window x-position in OpenGL model space */
+ public final int glWinX;
+ /** window y-position in OpenGL model space */
+ public final int glWinY;
+
+ PointerEventInfo(final int glWinX, final int glWinY, final UIShape shape, final float[] objPos) {
+ this.glWinX = glWinX;
+ this.glWinY = glWinY;
this.shape = shape;
- this.rotBounds = rotatedBounds;
- this.rotPosition = rotatedRelPos;
+ this.objPos = objPos;
}
public String toString() {
- return "EventDetails[pos "+rotPosition[0]+", "+rotPosition[1]+", "+rotPosition[2]+
- ", "+rotBounds+", "+shape+"]";
+ return "EventDetails[winPos ["+glWinX+", "+glWinY+"], objPos ["+objPos[0]+", "+objPos[1]+", "+objPos[2]+"], "+shape+"]";
+ }
+ }
+
+ /**
+ * @param e original Newt {@link GestureEvent}
+ * @param glWinX x-position in OpenGL model space
+ * @param glWinY y-position in OpenGL model space
+ */
+ public final void dispatchGestureEvent(final GestureEvent e, final int glWinX, final int glWinY, final float[] objPos) {
+ e.setAttachment(new PointerEventInfo(glWinX, glWinY, this, objPos));
+ for(int i = 0; !e.isConsumed() && i < mouseListeners.size(); i++ ) {
+ mouseListeners.get(i).gestureDetected(e);
}
}
@@ -381,36 +451,28 @@ public abstract class UIShape {
*
* @param e original Newt {@link MouseEvent}
* @param glX x-position in OpenGL model space
- * @param glY x-position in OpenGL model space
+ * @param glY y-position in OpenGL model space
*/
- public final void dispatchMouseEvent(final MouseEvent e, final int glX, final int glY) {
- // rotate bounding box and normalize to 0/0
- final Quaternion rot = getRotation();
- final float[] bLow = new float[3];
- VectorUtil.copyVec3(bLow, 0, getBounds().getLow(), 0);
- VectorUtil.scaleVec3(bLow, bLow, -1f);
- final AABBox rbox = new AABBox(getBounds());
- rbox.translate(bLow);
- rbox.rotate(rot);
-
- // get unrotated relative position within shape, rotate and normalize to 0/0
- final float[] relPos = new float[] { glX, glY, 0f };
- VectorUtil.subVec3(relPos, relPos, getTranslate());
- VectorUtil.addVec3(relPos, relPos, bLow);
- rot.rotateVector(relPos, 0, relPos, 0);
-
- // set as attachment
- e.setAttachment(new EventDetails(this, rbox, relPos));
+ public final void dispatchMouseEvent(final MouseEvent e, final int glWinX, final int glWinY, final float[] objPos) {
+ e.setAttachment(new PointerEventInfo(glWinX, glWinY, this, objPos));
final short eventType = e.getEventType();
- if( MouseEvent.EVENT_MOUSE_PRESSED == eventType ) {
- setPressed(true);
- } else if ( MouseEvent.EVENT_MOUSE_RELEASED == eventType ) {
- setPressed(false);
+ if( 1 == e.getPointerCount() ) {
+ switch( eventType ) {
+ case MouseEvent.EVENT_MOUSE_CLICKED:
+ toggle();
+ break;
+ case MouseEvent.EVENT_MOUSE_PRESSED:
+ setPressed(true);
+ break;
+ case MouseEvent.EVENT_MOUSE_RELEASED:
+ setPressed(false);
+ break;
+ }
}
for(int i = 0; !e.isConsumed() && i < mouseListeners.size(); i++ ) {
- final MouseListener l = mouseListeners.get(i);
+ final MouseGestureListener l = mouseListeners.get(i);
switch( eventType ) {
case MouseEvent.EVENT_MOUSE_CLICKED:
l.mouseClicked(e);