aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java319
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java118
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/shapes/GLButton.java2
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/shapes/ImageButton.java2
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java2
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/shapes/TexSeqButton.java13
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/Region.java38
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java1
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java111
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java25
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java27
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java26
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl18
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp7
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-segment-head.fp3
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/functions.glsl42
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl2
-rw-r--r--src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl2
19 files changed, 587 insertions, 183 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java
new file mode 100644
index 000000000..fbe62c675
--- /dev/null
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java
@@ -0,0 +1,319 @@
+/**
+ * Copyright 2010-2023 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.demos.graph.ui;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.common.net.Uri;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontFactory;
+import com.jogamp.graph.font.FontScale;
+import com.jogamp.graph.ui.Group;
+import com.jogamp.graph.ui.Scene;
+import com.jogamp.graph.ui.Shape;
+import com.jogamp.graph.ui.layout.Alignment;
+import com.jogamp.graph.ui.layout.Gap;
+import com.jogamp.graph.ui.layout.GridLayout;
+import com.jogamp.graph.ui.shapes.MediaButton;
+import com.jogamp.math.Vec2i;
+import com.jogamp.math.Vec4f;
+import com.jogamp.math.geom.AABBox;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.demos.util.CommandlineOptions;
+import com.jogamp.opengl.demos.util.MiscUtils;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.av.GLMediaPlayer.EventMask;
+import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
+import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
+
+/**
+ * MediaButtons in a grid, filled by media files from a directory in different aspect ratios
+ */
+public class UIMediaGrid00 {
+ static CommandlineOptions options = new CommandlineOptions(1920, 1080, Region.VBAA_RENDERING_BIT);
+
+ public static int aid = GLMediaPlayer.STREAM_ID_AUTO;
+
+ public static void main(final String[] args) throws IOException {
+ final List<Uri> mediaFiles = new ArrayList<Uri>();
+ if( 0 != args.length ) {
+ final int[] idx = { 0 };
+ for (idx[0] = 0; idx[0] < args.length; ++idx[0]) {
+ if( options.parse(args, idx) ) {
+ continue;
+ } else if (args[idx[0]].equals("-file")) {
+ idx[0]++;
+ final Uri u = Uri.tryUriOrFile( args[idx[0]] );
+ if( null != u ) {
+ mediaFiles.add(u);
+ }
+ } else if(args[idx[0]].equals("-aid")) {
+ idx[0]++;
+ aid = MiscUtils.atoi(args[idx[0]], aid);
+ } else if(args[idx[0]].equals("-mute")) {
+ aid = GLMediaPlayer.STREAM_ID_NONE;
+ }
+ }
+ }
+ System.err.println(options);
+ System.err.println("aid "+aid);
+
+ if( 0 == mediaFiles.size() ) {
+ System.err.println("No media files, exit.");
+ return;
+ }
+ for(final Uri uri : mediaFiles) {
+ System.err.println("- "+uri);
+ }
+ final Vec2i gridDim = new Vec2i(4, mediaFiles.size());
+
+ // final Font fontStatus = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf", FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
+ final Font fontInfo = FontFactory.get(FontFactory.UBUNTU).getDefault();
+
+ final GLProfile reqGLP = GLProfile.get(options.glProfileName);
+ System.err.println("GLProfile: "+reqGLP);
+
+ final GLCapabilities caps = new GLCapabilities(reqGLP);
+ caps.setAlphaBits(4);
+ if( options.sceneMSAASamples > 0 ) {
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(options.sceneMSAASamples);
+ }
+ System.out.println("Requested: " + caps);
+
+ final Animator animator = new Animator(0 /* w/o AWT */);
+ animator.setUpdateFPSFrames(1*60, null); // System.err);
+ final GLWindow window = GLWindow.create(caps);
+ window.setSize(options.surface_width, options.surface_height);
+ window.setTitle(UIMediaGrid00.class.getSimpleName());
+ window.setVisible(true);
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowResized(final WindowEvent e) {
+ window.setTitle(FontView01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight());
+ }
+ @Override
+ public void windowDestroyNotify(final WindowEvent e) {
+ animator.stop();
+ }
+ });
+ animator.add(window);
+
+ final Scene scene = new Scene(options.graphAASamples);
+ scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ scene.setFrustumCullingEnabled(true);
+
+ scene.attachInputListenerTo(window);
+ window.addGLEventListener(scene);
+
+
+ final float[] ppmm = window.getPixelsPerMM(new float[2]);
+ {
+ final float[] dpi = FontScale.ppmmToPPI( new float[] { ppmm[0], ppmm[1] } );
+ System.err.println("DPI "+dpi[0]+" x "+dpi[1]+", "+ppmm[0]+" x "+ppmm[1]+" pixel/mm");
+
+ final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
+ System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
+ }
+ final Group mediaGrid;
+ {
+ final float cellWidth = 1f;
+ final float cellHeight = 1f;
+ mediaGrid = new Group(new GridLayout(gridDim.x(), cellWidth*0.9f, cellHeight*0.9f, Alignment.FillCenter, new Gap(cellHeight*0.1f, cellWidth*0.1f)));
+ mediaGrid.setRelayoutOnDirtyShapes(false);
+ }
+ addMedia(reqGLP, fontInfo, mediaGrid, gridDim, mediaFiles, null);
+ mediaGrid.validate(reqGLP);
+ System.err.println("MediaGrid "+mediaGrid);
+ System.err.println("MediaGrid "+mediaGrid.getLayout());
+
+ final Group mainGrid = new Group(new GridLayout(1, 0f, 0f, Alignment.None));
+ mainGrid.addShape(mediaGrid);
+ scene.addShape(mainGrid);
+
+ window.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyReleased(final KeyEvent e) {
+ final short keySym = e.getKeySymbol();
+ if( keySym == KeyEvent.VK_S ) {
+ printScreenOnGLThread(scene, window.getChosenGLCapabilities());
+ } else if( keySym == KeyEvent.VK_DOWN ) {
+ } else if( keySym == KeyEvent.VK_PAGE_DOWN ) {
+ } else if( keySym == KeyEvent.VK_UP ) {
+ } else if( keySym == KeyEvent.VK_PAGE_UP ) {
+ } else if( keySym == KeyEvent.VK_F4 || keySym == KeyEvent.VK_ESCAPE || keySym == KeyEvent.VK_Q ) {
+ MiscUtils.destroyWindow(window);
+ } else if( keySym == KeyEvent.VK_SPACE ) {
+ final Shape a = scene.getActiveShape();
+ if( a instanceof MediaButton ) {
+ final MediaButton b = (MediaButton)a;
+ final GLMediaPlayer mPlayer = b.getGLMediaPlayer();
+ if( GLMediaPlayer.State.Paused == mPlayer.getState() ) {
+ mPlayer.resume();
+ } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) {
+ mPlayer.playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, aid, MediaTexCount);
+ } else if( e.isShiftDown() ) {
+ mPlayer.stop();
+ } else {
+ mPlayer.pause(false);
+ }
+ }
+ }
+ }
+ });
+
+ animator.start();
+ scene.waitUntilDisplayed();
+ {
+ final AABBox sceneBox = scene.getBounds();
+ final AABBox mainGridBox = mainGrid.getBounds();
+ final float sx = sceneBox.getWidth() / mainGridBox.getWidth();
+ final float sy = sceneBox.getHeight() / mainGridBox.getHeight();
+ final float sxy = Math.min(sx, sy);
+ System.err.println("SceneBox "+sceneBox);
+ System.err.println("MainGridBox "+mainGridBox);
+ System.err.println("scale sx "+sx+", sy "+sy+", sxy "+sxy);
+ // scale, moveTo origin bottom-left, then move up to top-left corner.
+ mainGrid.scale(sxy, sxy, 1f).moveTo(sceneBox.getLow()).move(0, sceneBox.getHeight()-mainGridBox.getHeight()*sxy, 0);
+ }
+ printScreenOnGLThread(scene, window.getChosenGLCapabilities());
+ // stay open ..
+ }
+ static void printScreenOnGLThread(final Scene scene, final GLCapabilitiesImmutable caps) {
+ scene.screenshot(true, scene.nextScreenshotFile(null, UIMediaGrid00.class.getSimpleName(), options.renderModes, caps, "media"));
+ }
+
+ public static final int MediaTexUnitMediaPlayer = 1;
+ public static final int MediaTexCount = 3; // GLMediaPlayer.TEXTURE_COUNT_DEFAULT
+
+ public static MediaButton createMediaButton(final Uri medium, final float aratio, final boolean letterBox, final Shape.MouseGestureListener mouseListener) {
+ final float borderSz = 0.02f;
+ final Vec4f borderToggleOff = new Vec4f(0, 0, 0, 0.7f);
+ final Vec4f borderToggleOn = new Vec4f(0, 0, 1, 0.7f);
+ final Vec4f borderActive = new Vec4f(1, 1, 0, 0.7f);
+
+ final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
+ mPlayer.setTextureUnit(MediaTexUnitMediaPlayer);
+ // mPlayer.setAudioChannelLimit(1); // enforce mono to enjoy spatial 3D position effects
+ final MediaButton button = new MediaButton(options.renderModes, aratio, 1, mPlayer);
+ button.setVerbose(false).addDefaultEventListener().setTextureLetterbox(letterBox).setFixedARatioResize(true);
+ if( aid == GLMediaPlayer.STREAM_ID_NONE ) {
+ button.setToggle( true ); // toggle == false -> mute audio
+ } else {
+ button.setToggleable(true);
+ button.setToggle(false); // toggle == false -> mute audio
+ }
+ mPlayer.setAudioVolume( 0f );
+ if( null != mouseListener ) {
+ button.addMouseListener(mouseListener);
+ }
+ button.onToggle( (final Shape s) -> {
+ mPlayer.setAudioVolume( s.isToggleOn() ? 1f : 0f );
+ if( s.isActive() ) {
+ s.setBorderColor(borderActive);
+ } else {
+ if( s.isToggleOn() ) {
+ s.setBorderColor(borderToggleOn);
+ } else {
+ s.setBorderColor(borderToggleOff);
+ }
+ }
+ });
+ button.onActivation( (final Shape s) -> {
+ System.err.println("XXX "+s);
+ if( s.isActive() ) {
+ s.setBorderColor(borderActive);
+ } else {
+ if( s.isToggleOn() ) {
+ s.setBorderColor(borderToggleOn);
+ } else {
+ s.setBorderColor(borderToggleOff);
+ }
+ }
+ });
+ mPlayer.addEventListener( new GLMediaEventListener() {
+ @Override
+ public void newFrameAvailable(final GLMediaPlayer ts, final TextureFrame newFrame, final long when) { }
+
+ @Override
+ public void attributesChanged(final GLMediaPlayer mp, final EventMask eventMask, final long when) {
+ // System.err.println("MediaButton AttributesChanges: "+eventMask+", when "+when);
+ // System.err.println("MediaButton State: "+mp);
+ if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Init) ) {
+ System.err.println(mp.toString());
+ }
+ if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
+ final StreamException err = mp.getStreamException();
+ if( null != err ) {
+ System.err.println("MovieSimple State: Exception: "+err.getMessage());
+ } else {
+ new InterruptSource.Thread() {
+ @Override
+ public void run() {
+ mp.setPlaySpeed(1f);
+ mp.seek(0);
+ mp.resume();
+ }
+ }.start();
+ }
+ }
+ }
+ });
+ button.setToggleOffColorMod(1f, 1f, 1f, 1f);
+ button.setPressedColorMod(1f, 1f, 1f, 0.85f);
+ button.setPerp().setBorderColor(borderToggleOff).setBorder(borderSz);
+ mPlayer.playStream(medium, GLMediaPlayer.STREAM_ID_AUTO, aid, MediaTexCount);
+ return button;
+ }
+
+ static void addMedia(final GLProfile glp, final Font font, final Group grid,
+ final Vec2i gridDim, final List<Uri> mediaFiles,
+ final Shape.MouseGestureListener mouseListener) {
+ for(final Uri medium : mediaFiles) {
+ grid.addShape( createMediaButton(medium, 16f/9f, false, mouseListener) );
+ grid.addShape( createMediaButton(medium, 4f/3f, false, mouseListener) );
+ grid.addShape( createMediaButton(medium, 16f/9f, true, mouseListener) );
+ grid.addShape( createMediaButton(medium, 4f/3f, true, mouseListener) );
+ }
+ }
+}
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java
index df85e8ccf..95c8d3a38 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java
@@ -35,7 +35,6 @@ import java.util.Arrays;
import java.util.List;
import com.jogamp.common.net.Uri;
-import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
@@ -47,13 +46,10 @@ import com.jogamp.graph.ui.layout.Alignment;
import com.jogamp.graph.ui.layout.Gap;
import com.jogamp.graph.ui.layout.GridLayout;
import com.jogamp.graph.ui.shapes.MediaButton;
-import com.jogamp.math.FloatUtil;
import com.jogamp.math.Vec2i;
-import com.jogamp.math.Vec3f;
import com.jogamp.math.geom.AABBox;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
-import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
@@ -65,11 +61,6 @@ import com.jogamp.opengl.demos.util.CommandlineOptions;
import com.jogamp.opengl.demos.util.MiscUtils;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
-import com.jogamp.opengl.util.av.GLMediaPlayer.EventMask;
-import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
-import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
-import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
-import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
/**
* MediaButtons in a grid, filled by media files from a directory.
@@ -77,11 +68,13 @@ import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
public class UIMediaGrid01 {
static CommandlineOptions options = new CommandlineOptions(1920, 1080, Region.VBAA_RENDERING_BIT);
- public static final List<String> MEDIA_SUFFIXES = Arrays.asList("mp4", "mkv");
+ public static final List<String> MEDIA_SUFFIXES = Arrays.asList("mp4", "mkv", "m2v", "avi");
public static int aid = GLMediaPlayer.STREAM_ID_AUTO;
+ public static float boxRatio = 16f/9f;
+ public static boolean letterBox = true;
public static void main(final String[] args) throws IOException {
- int maxMediaFiles = Integer.MAX_VALUE;
+ int maxMediaFiles = 12; // Integer.MAX_VALUE;
String mediaDir = null;
if( 0 != args.length ) {
final int[] idx = { 0 };
@@ -99,11 +92,21 @@ public class UIMediaGrid01 {
aid = MiscUtils.atoi(args[idx[0]], aid);
} else if(args[idx[0]].equals("-mute")) {
aid = GLMediaPlayer.STREAM_ID_NONE;
+ } else if(args[idx[0]].equals("-ratio")) {
+ idx[0]++;
+ boxRatio = MiscUtils.atof(args[idx[0]], boxRatio);
+ } else if(args[idx[0]].equals("-zoom")) {
+ letterBox = false;
}
}
}
System.err.println(options);
System.err.println("mediaDir "+mediaDir);
+ System.err.println("maxMediaFiles "+maxMediaFiles);
+ System.err.println("aid "+aid);
+ System.err.println("boxRatio "+boxRatio);
+ System.err.println("letterBox "+letterBox);
+
final List<Uri> mediaFiles = new ArrayList<Uri>();
if( null != mediaDir && mediaDir.length() > 0 ) {
final File dir = new File(mediaDir);
@@ -201,11 +204,12 @@ public class UIMediaGrid01 {
}
final Group mediaGrid;
{
- final float cellWidth = 16.0f/9.0f;
+ final float cellWidth = boxRatio;
final float cellHeight = 1f;
mediaGrid = new Group(new GridLayout(gridDim.x(), cellWidth*0.9f, cellHeight*0.9f, Alignment.FillCenter, new Gap(cellHeight*0.1f, cellWidth*0.1f)));
+ mediaGrid.setRelayoutOnDirtyShapes(false);
}
- addMedia(reqGLP, fontInfo, mediaGrid, gridDim, mediaFiles, 16.0f/9.0f, null);
+ addMedia(reqGLP, fontInfo, mediaGrid, gridDim, mediaFiles, boxRatio, null);
mediaGrid.validate(reqGLP);
System.err.println("MediaGrid "+mediaGrid);
System.err.println("MediaGrid "+mediaGrid.getLayout());
@@ -234,7 +238,7 @@ public class UIMediaGrid01 {
if( GLMediaPlayer.State.Paused == mPlayer.getState() ) {
mPlayer.resume();
} else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) {
- mPlayer.playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, aid, MediaTexCount);
+ mPlayer.playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, aid, UIMediaGrid00.MediaTexCount);
} else if( e.isShiftDown() ) {
mPlayer.stop();
} else {
@@ -266,95 +270,11 @@ public class UIMediaGrid01 {
scene.screenshot(true, scene.nextScreenshotFile(null, UIMediaGrid01.class.getSimpleName(), options.renderModes, caps, "media"));
}
- private static final int MediaTexUnitMediaPlayer = 1;
- private static final int MediaTexCount = 3; // GLMediaPlayer.TEXTURE_COUNT_DEFAULT
-
static void addMedia(final GLProfile glp, final Font font, final Group grid,
final Vec2i gridDim, final List<Uri> mediaFiles, final float defRatio,
final Shape.MouseGestureListener mouseListener) {
for(final Uri medium : mediaFiles) {
- final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
- mPlayer.setTextureUnit(MediaTexUnitMediaPlayer);
- // mPlayer.setAudioChannelLimit(1); // enforce mono to enjoy spatial 3D position effects
- final MediaButton button = new MediaButton(options.renderModes, defRatio, 1, mPlayer);
- button.setVerbose(false).addDefaultEventListener().setFixedARatioResize(true);
- if( aid == GLMediaPlayer.STREAM_ID_NONE ) {
- button.setToggle( true ); // toggle == false -> mute audio
- } else {
- button.setToggleable(true);
- button.setToggle(false); // toggle == false -> mute audio
- button.setToggleOffColorMod(0.80f, 0.80f, 0.95f, 1.0f);
- }
- mPlayer.setAudioVolume( 0f );
- if( null != mouseListener ) {
- button.addMouseListener(mouseListener);
- }
- button.onToggle( (final Shape s) -> {
- mPlayer.setAudioVolume( s.isToggleOn() ? 1f : 0f );
- });
- mPlayer.addEventListener( new GLMediaEventListener() {
- @Override
- public void newFrameAvailable(final GLMediaPlayer ts, final TextureFrame newFrame, final long when) { }
-
- @Override
- public void attributesChanged(final GLMediaPlayer mp, final EventMask eventMask, final long when) {
- // System.err.println("MediaButton AttributesChanges: "+eventMask+", when "+when);
- // System.err.println("MediaButton State: "+mp);
- if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Init) ) {
- System.err.println(mp.toString());
- }
- if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
- final StreamException err = mp.getStreamException();
- if( null != err ) {
- System.err.println("MovieSimple State: Exception: "+err.getMessage());
- } else {
- new InterruptSource.Thread() {
- @Override
- public void run() {
- mp.setPlaySpeed(1f);
- mp.seek(0);
- mp.resume();
- }
- }.start();
- }
- }
- }
- });
- button.setPerp().setBorderColor(0, 0, 0, 1).setBorder(0.01f);
- grid.addShape(button);
- mPlayer.playStream(medium, GLMediaPlayer.STREAM_ID_AUTO, aid, MediaTexCount);
+ grid.addShape( UIMediaGrid00.createMediaButton(medium, defRatio, letterBox, mouseListener) );
}
}
-
- /**
- * 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 Shape.MouseGestureAdapter dragZoomRotateListener = new Shape.MouseGestureAdapter() {
- MediaButton zoomed = null;
-
- @Override
- public void mousePressed(final MouseEvent e) {
- zoomed = null;
- }
- @Override
- public void mouseReleased(final MouseEvent e) {
- zoomed = null;
- }
-
- @Override
- public void mouseDragged(final MouseEvent e) {
- final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
- }
-
- @Override
- public void mouseWheelMoved(final MouseEvent e) {
- final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
- final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f );
- // swap axis for onscreen rotation matching natural feel
- final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp );
- shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) );
- }
- };
-
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/GLButton.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/GLButton.java
index a8d7c4295..d5a192456 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/shapes/GLButton.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/GLButton.java
@@ -76,7 +76,7 @@ public class GLButton extends TexSeqButton {
this.glel = glel;
this.useAlpha = useAlpha;
- setColor(1.0f, 1.0f, 1.0f, 1.0f);
+ setColor(1.0f, 1.0f, 1.0f, 0.0f);
setPressedColorMod(0.9f, 0.9f, 0.9f, 0.7f);
setToggleOffColorMod(0.8f, 0.8f, 0.8f, 1.0f);
setToggleOnColorMod(1.0f, 1.0f, 1.0f, 1.0f);
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/ImageButton.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/ImageButton.java
index cd919546d..d8c79d8e7 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/shapes/ImageButton.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/ImageButton.java
@@ -55,7 +55,7 @@ public class ImageButton extends TexSeqButton {
final float height, final ImageSequence texSeq) {
super(renderModes, width, height, texSeq);
- setColor(1f, 1f, 1f, 1.0f);
+ setColor(1f, 1f, 1f, 0.0f);
setPressedColorMod(0.9f, 0.9f, 0.9f, 0.9f);
setToggleOffColorMod(1f, 1f, 1f, 1f);
setToggleOnColorMod(0.8f, 0.8f, 0.8f, 1f);
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java
index b73f224d1..ed44324de 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java
@@ -68,7 +68,7 @@ public class MediaButton extends TexSeqButton {
final float height, final GLMediaPlayer mPlayer) {
super(renderModes, width, height, mPlayer);
- setColor(1.0f, 1.0f, 1.0f, 1.0f);
+ setColor(1.0f, 1.0f, 1.0f, 0.0f);
setPressedColorMod(0.9f, 0.9f, 0.9f, 0.7f);
setToggleOffColorMod(0.8f, 0.8f, 0.8f, 1.0f);
setToggleOnColorMod(1.0f, 1.0f, 1.0f, 1.0f);
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/TexSeqButton.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/TexSeqButton.java
index 0dbd11adf..de5c43be1 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/shapes/TexSeqButton.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/TexSeqButton.java
@@ -55,6 +55,19 @@ public abstract class TexSeqButton extends BaseButton {
public final TextureSequence getTextureSequence() { return this.texSeq; }
+ /**
+ * Sets a renderMode {@link Region#COLORTEXTURE_LETTERBOX_RENDERING_BIT} on or off.
+ * @return this instance for chaining
+ */
+ public TexSeqButton setTextureLetterbox(final boolean v) {
+ if( getTextureLetterbox() != v ) {
+ renderModes = Region.setRenderMode(renderModes, Region.COLORTEXTURE_LETTERBOX_RENDERING_BIT, v);
+ markShapeDirty();
+ }
+ return this;
+ }
+ public boolean getTextureLetterbox() { return Region.isColorTextureLetterbox(renderModes); }
+
@Override
protected void addShapeToRegion(final GLProfile glp, final GL2ES2 gl) {
final OutlineShape shape = createBaseShape(0f);
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java
index 93b05aefa..5f78283ed 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/Region.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java
@@ -127,9 +127,21 @@ public abstract class Region {
* <p>
* If set, a color texture is used to determine the color.
* </p>
+ * @see #COLORTEXTURE_LETTERBOX_RENDERING_BIT
*/
public static final int COLORTEXTURE_RENDERING_BIT = 1 << 10;
+ /**
+ * Rendering-Mode bit for {@link #getRenderModes() Region}
+ * <p>
+ * If set, a used {@link #COLORTEXTURE_RENDERING_BIT} color texture is added letter-box space to match aspect-ratio, otherwise it will be zoomed in.
+ * </p>
+ * <p>
+ * Note that {@link #COLORTEXTURE_RENDERING_BIT} must also be set to even enable color texture.
+ * </p>
+ */
+ public static final int COLORTEXTURE_LETTERBOX_RENDERING_BIT = 1 << 11;
+
/** Default maximum {@link #getQuality() quality}, {@value}. */
public static final int MAX_QUALITY = 1;
@@ -147,6 +159,9 @@ public abstract class Region {
protected final AABBox box = new AABBox();
protected Frustum frustum = null;
+ public static final boolean isRenderModeSet(final int renderModes, final int mask) { return mask == ( renderModes & mask ); }
+ public static final int setRenderMode(int renderModes, final int mask, final boolean v) { if( v ) { renderModes |= mask; } else { renderModes &= ~mask; }; return renderModes; }
+
/** Returns true if given {@code renderModes} has {@link Region#VBAA_RENDERING_BIT} set. */
public static boolean isVBAA(final int renderModes) {
return 0 != (renderModes & Region.VBAA_RENDERING_BIT);
@@ -194,6 +209,11 @@ public abstract class Region {
return 0 != (renderModes & Region.COLORTEXTURE_RENDERING_BIT);
}
+ /** Returns true if given {@code renderModes} has {@link Region#COLORTEXTURE_LETTERBOX_RENDERING_BIT} set. */
+ public static boolean isColorTextureLetterbox(final int renderModes) {
+ return 0 != ( renderModes & Region.COLORTEXTURE_LETTERBOX_RENDERING_BIT );
+ }
+
/**
* Returns a unique technical description string for renderModes as follows:
* <pre>
@@ -204,7 +224,16 @@ public abstract class Region {
public static String getRenderModeString(final int renderModes) {
final String curveS = hasVariableWeight(renderModes) ? "-curve" : "";
final String cChanS = hasColorChannel(renderModes) ? "-cols" : "";
- final String cTexS = hasColorTexture(renderModes) ? "-ctex" : "";
+ final String cTexS;
+ if( hasColorTexture(renderModes) ) {
+ if( Region.isColorTextureLetterbox(renderModes) ) {
+ cTexS = "-ctex_lbox";
+ } else {
+ cTexS = "-ctex_zoom";
+ }
+ } else {
+ cTexS = "";
+ }
if( Region.isVBAA(renderModes) ) {
return "vbaa"+curveS+cChanS+cTexS;
} else if( Region.isMSAA(renderModes) ) {
@@ -299,6 +328,8 @@ public abstract class Region {
box.reset();
}
+ public final boolean isRenderModeSet(final int mask) { return mask == ( renderModes & mask ); }
+
/**
* Returns true if capable of two pass rendering - VBAA, otherwise false.
* @see #getRenderModes()
@@ -340,11 +371,16 @@ public abstract class Region {
* i.e. the bit {@link #COLORTEXTURE_RENDERING_BIT} is set,
* otherwise false.
* @see #getRenderModes()
+ * @see #isColorTextureLetterbox()
*/
public final boolean hasColorTexture() {
return Region.hasColorTexture(renderModes);
}
+ /** Returns true if given {@code renderModes} has {@link Region#COLORTEXTURE_LETTERBOX_RENDERING_BIT} set. */
+ public final boolean isColorTextureLetterbox() {
+ return Region.isColorTextureLetterbox(renderModes);
+ }
/** See {@link #setFrustum(Frustum)} */
public final Frustum getFrustum() { return frustum; }
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
index 7e3a7ff30..0927c41cb 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -631,6 +631,7 @@ public final class RegionRenderer {
}
try {
+ posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "functions.glsl");
posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "uniforms.glsl");
posFp = rsFp.insertShaderSource(0, posFp, AttributeNames.class, "varyings.glsl");
} catch (final IOException ioe) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java
index 17fcc7016..b4fd0cc1e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java
@@ -78,20 +78,16 @@ public class TextureCoords {
return d;
}
- /** Returns the leftmost (x) texture coordinate of this
- rectangle. */
+ /** Returns the leftmost (x) texture coordinate of this rectangle. */
public float left() { return left; }
- /** Returns the rightmost (x) texture coordinate of this
- rectangle. */
+ /** Returns the rightmost (x) texture coordinate of this rectangle. */
public float right() { return right; }
- /** Returns the bottommost (y) texture coordinate of this
- rectangle. */
+ /** Returns the bottommost (y) texture coordinate of this rectangle. */
public float bottom() { return bottom; }
- /** Returns the topmost (y) texture coordinate of this
- rectangle. */
+ /** Returns the topmost (y) texture coordinate of this rectangle. */
public float top() { return top; }
@Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 1e308b215..7c924864a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -33,6 +33,7 @@ import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.common.av.TimeFrameI;
+import com.jogamp.math.geom.AABBox;
/**
* Protocol for texture sequences, like animations, movies, etc.
@@ -303,4 +304,114 @@ public interface TextureSequence {
* @see #getTextureLookupFragmentShaderImpl()
*/
public int getTextureFragmentShaderHashCode();
+
+ /**
+ * Calculates the texture coordinates bounding box while correcting for aspect-ratio.
+ * @param tex the {@link Texture}
+ * @param box the {@Link AABBpx} of the destination
+ * @param letterBox true to produce letter-box space to match aspect-ratio, otherwise will zoom in
+ * @param colorTexBBox destination float[6] array for the following three texture-coordinate tuples: minX/minY, maxX/maxY, texW/texH
+ */
+ @SuppressWarnings("unused")
+ public static void setTexCoordBBox(final Texture tex, final AABBox box, final boolean letterBox, final float[] colorTexBBox) {
+ final TextureCoords tc = tex.getImageTexCoords();
+ final float boxRatio = box.getWidth() / box.getHeight();
+ final float imgRatio = tex.getAspectRatio();
+ final float box2ImgRatio = boxRatio / imgRatio;
+ final float tcW = tc.right() - tc.left();
+ final float tcH;
+ float boxWidthCut=0, boxHeightCut=0, boxWidthExt=0, boxHeightExt=0;
+ if( box2ImgRatio >= 1.0f ) {
+ if( letterBox ) {
+ boxWidthCut = box.getWidth() * ( 1f - 1f / box2ImgRatio );
+ final float tcWH = tcW * 0.5f;
+ final float boxWidthCutL = boxWidthCut * tcWH;
+ final float boxWidthCutR = boxWidthCut * ( 1f - tcWH );
+ colorTexBBox[0] = ( box.getMinX() + boxWidthCutL ) / tcW;
+ colorTexBBox[2] = ( box.getMaxX() - boxWidthCutR ) / tcW;
+ if( tex.getMustFlipVertically() ) {
+ tcH = tc.bottom() - tc.top();
+ colorTexBBox[1] = box.getMaxY() / tcH;
+ colorTexBBox[3] = box.getMinY() / tcH;
+ } else {
+ tcH = tc.top() - tc.bottom();
+ colorTexBBox[1] = box.getMinY() / tcH;
+ colorTexBBox[3] = box.getMaxY() / tcH;
+ }
+ } else {
+ colorTexBBox[0] = box.getMinX() / tcW;
+ colorTexBBox[2] = box.getMaxX() / tcW;
+ boxHeightExt = box.getHeight() * ( box2ImgRatio - 1f );
+ if( tex.getMustFlipVertically() ) {
+ tcH = tc.bottom() - tc.top();
+ final float tcHH = tcH * 0.5f;
+ final float boxHeightExtB = boxHeightExt * tcHH;
+ final float boxHeightExtT = boxHeightExt * ( 1f - tcHH );
+ colorTexBBox[1] = ( box.getMaxY() + boxHeightExtT ) / tcH;
+ colorTexBBox[3] = ( box.getMinY() - boxHeightExtB ) / tcH;
+ } else {
+ tcH = tc.top() - tc.bottom();
+ final float tcHH = tcH * 0.5f;
+ final float boxHeightExtB = boxHeightExt * tcHH;
+ final float boxHeightExtT = boxHeightExt * ( 1f - tcHH );
+ colorTexBBox[1] = ( box.getMinY() - boxHeightExtB ) / tcH;
+ colorTexBBox[3] = ( box.getMaxY() + boxHeightExtT ) / tcH;
+ }
+ }
+ } else {
+ if( letterBox ) {
+ colorTexBBox[0] = box.getMinX() / tcW;
+ colorTexBBox[2] = box.getMaxX() / tcW;
+ boxHeightCut = box.getHeight() * ( 1f - box2ImgRatio );
+ if( tex.getMustFlipVertically() ) {
+ tcH = tc.bottom() - tc.top();
+ final float tcHH = tcH * 0.5f;
+ final float boxHeightCutB = boxHeightCut * tcHH;
+ final float boxHeightCutT = boxHeightCut * ( 1f - tcHH );
+ colorTexBBox[1] = ( box.getMaxY() - boxHeightCutT ) / tcH;
+ colorTexBBox[3] = ( box.getMinY() + boxHeightCutB ) / tcH;
+ } else {
+ tcH = tc.top() - tc.bottom();
+ final float tcHH = tcH * 0.5f;
+ final float boxHeightCutB = boxHeightCut * tcHH;
+ final float boxHeightCutT = boxHeightCut * ( 1f - tcHH );
+ colorTexBBox[1] = ( box.getMinY() + boxHeightCutB ) / tcH;
+ colorTexBBox[3] = ( box.getMaxY() - boxHeightCutT ) / tcH;
+ }
+ } else {
+ boxWidthExt = box.getWidth() * ( 1f / box2ImgRatio - 1f );
+ final float tcWH = tcW * 0.5f;
+ final float boxWidthExtL = boxWidthExt * tcWH;
+ final float boxWidthExtR = boxWidthExt * ( 1f - tcWH );
+ colorTexBBox[0] = ( box.getMinX() - boxWidthExtL ) / tcW;
+ colorTexBBox[2] = ( box.getMaxX() + boxWidthExtR ) / tcW;
+ if( tex.getMustFlipVertically() ) {
+ tcH = tc.bottom() - tc.top();
+ colorTexBBox[1] = box.getMaxY() / tcH;
+ colorTexBBox[3] = box.getMinY() / tcH;
+ } else {
+ tcH = tc.top() - tc.bottom();
+ colorTexBBox[1] = box.getMinY() / tcH;
+ colorTexBBox[3] = box.getMaxY() / tcH;
+ }
+ }
+ }
+ colorTexBBox[4] = tcW;
+ colorTexBBox[5] = tcH;
+ if( false ) {
+ final float texWidthRatio = (float)tex.getImageWidth() / (float)tex.getWidth();
+ final float texHeightRatio = (float)tex.getImageHeight() / (float)tex.getHeight();
+ final float texRatio = ( tc.right() - tc.left() ) / ( tc.bottom() - tc.top() );
+ final float box2TexRatio = boxRatio / texRatio;
+ final float colorTexBBoxW = colorTexBBox[2] - colorTexBBox[0];
+ final float colorTexBBoxH = colorTexBBox[3] - colorTexBBox[1];
+ System.err.println("XXX");
+ System.err.println("XXX ColorTex imgRatio "+imgRatio+", texRatio "+texRatio+", texPixelRatio[w "+texWidthRatio+", h "+texHeightRatio+"], "+tex);
+ System.err.println("XXX ColorTexBBox lbox "+letterBox+", cut "+boxWidthCut+"/"+boxHeightCut+", ext "+boxWidthExt+"/"+boxHeightExt);
+ System.err.println("XXX ColorTexBBox min "+colorTexBBox[0]+"/"+colorTexBBox[1]+", max "+colorTexBBox[2]+" x "+colorTexBBox[3]+
+ ", dim "+colorTexBBoxW+" x "+colorTexBBoxH+
+ ", tc-dim "+tcW+" x "+tcH+", tc "+tc+", box2ImgRatio "+box2ImgRatio+", box2TexRatio "+box2TexRatio);
+ System.err.println("XXX Box ratio "+boxRatio+", "+box);
+ }
+ }
}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
index 73af4603d..c5b1e8309 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java
@@ -50,7 +50,6 @@ import com.jogamp.opengl.FBObject.Attachment;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.TextureSequence;
public final class VBORegion2PMSAAES2 extends GLRegion {
@@ -61,8 +60,8 @@ public final class VBORegion2PMSAAES2 extends GLRegion {
// Pass-1:
private final GLUniformData gcu_ColorTexUnit;
- private final float[] colorTexBBox; // x0, y0, x1, y1
- private final GLUniformData gcu_ColorTexBBox;
+ private final float[] colorTexBBox; // minX/minY, maxX/maxY, texW/texH
+ private final GLUniformData gcu_ColorTexBBox; // vec2 gcu_ColorTexBBox[3] -> boxMin[2], boxMax[2] and texSize[2]
private ShaderProgram spPass1 = null;
// Pass-2:
@@ -97,8 +96,8 @@ public final class VBORegion2PMSAAES2 extends GLRegion {
if( hasColorTexture() ) {
gcu_ColorTexUnit = new GLUniformData(UniformNames.gcu_ColorTexUnit, colorTexSeq.getTextureUnit());
- colorTexBBox = new float[4];
- gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 4, FloatBuffer.wrap(colorTexBBox));
+ colorTexBBox = new float[6];
+ gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 2, FloatBuffer.wrap(colorTexBBox));
} else {
gcu_ColorTexUnit = null;
colorTexBBox = null;
@@ -148,21 +147,7 @@ public final class VBORegion2PMSAAES2 extends GLRegion {
vpc_ileave.enableBuffer(gl, false);
if( hasColorTexture && null != gcu_ColorTexUnit && colorTexSeq.isTextureAvailable() ) {
- final TextureSequence.TextureFrame frame = colorTexSeq.getLastTexture();
- final Texture tex = frame.getTexture();
- final TextureCoords tc = tex.getImageTexCoords();
- final float tcSx = 1f / ( tc.right() - tc.left() );
- colorTexBBox[0] = box.getMinX() * tcSx;
- colorTexBBox[2] = box.getMaxX() * tcSx;
- if( tex.getMustFlipVertically() ) {
- final float tcSy = 1f / ( tc.bottom() - tc.top() );
- colorTexBBox[1] = box.getMaxY() * tcSy;
- colorTexBBox[3] = box.getMinY() * tcSy;
- } else {
- final float tcSy = 1f / ( tc.top() - tc.bottom() );
- colorTexBBox[1] = box.getMinY() * tcSy;
- colorTexBBox[3] = box.getMaxY() * tcSy;
- }
+ TextureSequence.setTexCoordBBox(colorTexSeq.getLastTexture().getTexture(), box, isColorTextureLetterbox(), colorTexBBox);
}
gca_FboVerticesAttr.seal(gl, false);
{
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
index 9fad72881..b05a04802 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java
@@ -53,7 +53,6 @@ import com.jogamp.opengl.FBObject.TextureAttachment;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.TextureSequence;
public final class VBORegion2PVBAAES2 extends GLRegion {
@@ -94,8 +93,9 @@ public final class VBORegion2PVBAAES2 extends GLRegion {
// Pass-1:
private final GLUniformData gcu_ColorTexUnit;
- private final float[] colorTexBBox; // x0, y0, x1, y1
- private final GLUniformData gcu_ColorTexBBox;
+ private final float[] colorTexBBox; // minX/minY, maxX/maxY, texW/texH
+ private final GLUniformData gcu_ColorTexBBox; // vec2 gcu_ColorTexBBox[3] -> boxMin[2], boxMax[2] and texSize[2]
+
private ShaderProgram spPass1 = null;
// Pass-2:
@@ -193,8 +193,8 @@ public final class VBORegion2PVBAAES2 extends GLRegion {
if( hasColorTexture() ) {
gcu_ColorTexUnit = new GLUniformData(UniformNames.gcu_ColorTexUnit, colorTexSeq.getTextureUnit());
- colorTexBBox = new float[4];
- gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 4, FloatBuffer.wrap(colorTexBBox));
+ colorTexBBox = new float[6];
+ gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 2, FloatBuffer.wrap(colorTexBBox));
} else {
gcu_ColorTexUnit = null;
colorTexBBox = null;
@@ -235,6 +235,7 @@ public final class VBORegion2PVBAAES2 extends GLRegion {
@Override
protected void updateImpl(final GL2ES2 gl, final int curRenderModes) {
+ @SuppressWarnings("unused")
final boolean hasColorChannel = Region.hasColorChannel( curRenderModes );
final boolean hasColorTexture = Region.hasColorTexture( curRenderModes );
@@ -244,21 +245,7 @@ public final class VBORegion2PVBAAES2 extends GLRegion {
vpc_ileave.seal(gl, true);
vpc_ileave.enableBuffer(gl, false);
if( hasColorTexture && null != gcu_ColorTexUnit && colorTexSeq.isTextureAvailable() ) {
- final TextureSequence.TextureFrame frame = colorTexSeq.getLastTexture();
- final Texture tex = frame.getTexture();
- final TextureCoords tc = tex.getImageTexCoords();
- final float tcSx = 1f / ( tc.right() - tc.left() );
- colorTexBBox[0] = box.getMinX() * tcSx;
- colorTexBBox[2] = box.getMaxX() * tcSx;
- if( tex.getMustFlipVertically() ) {
- final float tcSy = 1f / ( tc.bottom() - tc.top() );
- colorTexBBox[1] = box.getMaxY() * tcSy;
- colorTexBBox[3] = box.getMinY() * tcSy;
- } else {
- final float tcSy = 1f / ( tc.top() - tc.bottom() );
- colorTexBBox[1] = box.getMinY() * tcSy;
- colorTexBBox[3] = box.getMaxY() * tcSy;
- }
+ TextureSequence.setTexCoordBBox(colorTexSeq.getLastTexture().getTexture(), box, isColorTextureLetterbox(), colorTexBBox);
}
gca_FboVerticesAttr.seal(gl, false);
{
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
index a819f9267..634b53fe2 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
@@ -42,7 +42,6 @@ import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.TextureSequence;
public final class VBORegionSPES2 extends GLRegion {
@@ -50,8 +49,8 @@ public final class VBORegionSPES2 extends GLRegion {
// Pass-1:
private final GLUniformData gcu_ColorTexUnit;
- private final float[] colorTexBBox; // x0, y0, x1, y1
- private final GLUniformData gcu_ColorTexBBox;
+ private final float[] colorTexBBox; // minX/minY, maxX/maxY, texW/texH
+ private final GLUniformData gcu_ColorTexBBox; // vec2 gcu_ColorTexBBox[3] -> boxMin[2], boxMax[2] and texSize[2]
private ShaderProgram spPass1 = null;
public VBORegionSPES2(final GLProfile glp, final int renderModes, final TextureSequence colorTexSeq,
@@ -65,8 +64,8 @@ public final class VBORegionSPES2 extends GLRegion {
if( hasColorTexture() ) {
gcu_ColorTexUnit = new GLUniformData(UniformNames.gcu_ColorTexUnit, colorTexSeq.getTextureUnit());
- colorTexBBox = new float[4];
- gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 4, FloatBuffer.wrap(colorTexBBox));
+ colorTexBBox = new float[6];
+ gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 2, FloatBuffer.wrap(colorTexBBox));
} else {
gcu_ColorTexUnit = null;
colorTexBBox = null;
@@ -91,22 +90,7 @@ public final class VBORegionSPES2 extends GLRegion {
vpc_ileave.seal(gl, true);
vpc_ileave.enableBuffer(gl, false);
if( hasColorTexture && null != gcu_ColorTexUnit && colorTexSeq.isTextureAvailable() ) {
- final TextureSequence.TextureFrame frame = colorTexSeq.getLastTexture();
- final Texture tex = frame.getTexture();
- final TextureCoords tc = tex.getImageTexCoords();
- final float tcSx = 1f / ( tc.right() - tc.left() );
- colorTexBBox[0] = box.getMinX() * tcSx;
- colorTexBBox[2] = box.getMaxX() * tcSx;
- final float tcSy;
- if( tex.getMustFlipVertically() ) {
- tcSy = 1f / ( tc.bottom() - tc.top() );
- colorTexBBox[1] = box.getMaxY() * tcSy;
- colorTexBBox[3] = box.getMinY() * tcSy;
- } else {
- tcSy = 1f / ( tc.top() - tc.bottom() );
- colorTexBBox[1] = box.getMinY() * tcSy;
- colorTexBBox[3] = box.getMaxY() * tcSy;
- }
+ TextureSequence.setTexCoordBBox(colorTexSeq.getLastTexture().getTexture(), box, isColorTextureLetterbox(), colorTexBBox);
}
indicesBuffer.seal(gl, true);
indicesBuffer.enableBuffer(gl, false);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl
index 447242438..6ff35df85 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl
@@ -1,10 +1,15 @@
+ // Copyright 2010-2023 JogAmp Community. All rights reserved.
if( gcv_CurveParam.x == 0.0 && gcv_CurveParam.y == 0.0 ) {
// pass-1: Lines
#if defined(USE_COLOR_TEXTURE) && defined(USE_COLOR_CHANNEL)
- mgl_FragColor = gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st) * gcv_Color * gcu_ColorStatic;
+ vec4 t = clip_coord(gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st), vec4(1), gcv_ColorTexCoord, vec2(0), gcv_ColorTexExt);
+
+ mgl_FragColor = vec4( mix( t.rgb * gcu_ColorStatic.rgb, gcv_Color.rgb, gcv_Color.a ),
+ mix( t.a * gcu_ColorStatic.a, 1, gcv_Color.a) );
#elif defined(USE_COLOR_TEXTURE)
- mgl_FragColor = gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st) * gcu_ColorStatic;
+ mgl_FragColor = clip_coord(gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st), vec4(1), gcv_ColorTexCoord, vec2(0), gcv_ColorTexExt)
+ * gcu_ColorStatic;
#elif defined(USE_COLOR_CHANNEL)
mgl_FragColor = gcv_Color * gcu_ColorStatic;
#else
@@ -22,10 +27,13 @@
float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_CurveParam.y), 0.0, 1.0);
#if defined(USE_COLOR_TEXTURE) && defined(USE_COLOR_CHANNEL)
- vec4 t = gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st);
- mgl_FragColor = vec4(t.rgb * gcv_Color.rgb * gcu_ColorStatic.rgb, t.a * gcv_Color.a * gcu_ColorStatic.a * a);
+ vec4 t = clip_coord(gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st), vec4(1), gcv_ColorTexCoord, vec2(0), gcv_ColorTexExt);
+
+ mgl_FragColor = vec4( mix( t.rgb * gcu_ColorStatic.rgb, gcv_Color.rgb, gcv_Color.a ),
+ a * mix( t.a * gcu_ColorStatic.a, 1, gcv_Color.a) );
#elif defined(USE_COLOR_TEXTURE)
- vec4 t = gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st);
+ vec4 t = clip_coord(gcuTexture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st), vec4(1), gcv_ColorTexCoord, vec2(0), gcv_ColorTexExt);
+
mgl_FragColor = vec4(t.rgb * gcu_ColorStatic.rgb, t.a * gcu_ColorStatic.a * a);
#elif defined(USE_COLOR_CHANNEL)
mgl_FragColor = vec4(gcv_Color.rgb * gcu_ColorStatic.rgb, gcv_Color.a * gcu_ColorStatic.a * a);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp
index c6ed4ca58..de41d9198 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp
@@ -1,4 +1,4 @@
-//Copyright 2010 JogAmp Community. All rights reserved.
+// Copyright 2010-2023 JogAmp Community. All rights reserved.
#if __VERSION__ >= 130
#define attribute in
@@ -24,8 +24,9 @@ void main(void)
}
#endif
#ifdef USE_COLOR_TEXTURE
- vec2 dim = vec2(gcu_ColorTexBBox.z - gcu_ColorTexBBox.x, gcu_ColorTexBBox.w - gcu_ColorTexBBox.y);
- gcv_ColorTexCoord = vec2(gca_Vertices.x - gcu_ColorTexBBox.x, gca_Vertices.y - gcu_ColorTexBBox.y) / dim;
+ vec2 dim = vec2(gcu_ColorTexBBox[1].x - gcu_ColorTexBBox[0].x, gcu_ColorTexBBox[1].y - gcu_ColorTexBBox[0].y);
+ gcv_ColorTexCoord = vec2(gca_Vertices.x - gcu_ColorTexBBox[0].x, gca_Vertices.y - gcu_ColorTexBBox[0].y) / dim;
+ gcv_ColorTexExt = gcu_ColorTexBBox[2]; // texture-size
#endif
#ifdef USE_COLOR_CHANNEL
gcv_Color = gca_Colors;
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-segment-head.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-segment-head.fp
index 05407a4e6..c88619154 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-segment-head.fp
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-segment-head.fp
@@ -1,4 +1,4 @@
-//Copyright 2010 JogAmp Community. All rights reserved.
+// Copyright 2010-2023 JogAmp Community. All rights reserved.
//
// 2-pass shader w/o weight
@@ -13,4 +13,3 @@
#endif
#define GetSample(texUnit, texCoord, psize, cx, cy, offX, offY) texture2D(texUnit, texCoord + psize * vec2(cx+offX, cy+offY))
-
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/functions.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/functions.glsl
new file mode 100644
index 000000000..eeab54ebf
--- /dev/null
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/functions.glsl
@@ -0,0 +1,42 @@
+// Copyright 2023 JogAmp Community. All rights reserved.
+
+#ifndef functions_glsl
+#define functions_glsl
+
+/** Returns product of components. */
+float v_mul( vec2 v ) {
+ return v.x * v.y;
+}
+/** Returns component wise logical 'or' as float '0' or '1' using the components product and clamp. */
+float v_or( vec2 v ) {
+ return clamp(v.x * v.y, 0, 1);
+}
+
+/** Returns sum of components. */
+float v_sum( vec2 v ) {
+ return v.x + v.y;
+}
+/** Returns component wise logical 'and' as float '0' or '1' using the components sum and clamp. */
+float v_and( vec2 v ) {
+ return clamp(v.x + v.y, 0, 1);
+}
+
+/**
+ * Branch-less clipping function.
+ * <p>
+ * Returns either 'col_in' if the 'coord' is within ['low'..'high'] range,
+ * otherwise 'col_ex'.
+ * </p>
+ * <p>
+ * This is achieved via the build-in 'step' and 'mix' function
+ * as well as our own 'v_mul' and v_and' function,
+ * which flattens a 'vec2' to one float suitable to be used as the 'mix' criteria.
+ * </p>
+ */
+vec4 clip_coord(vec4 col_in, vec4 col_ex, vec2 coord, vec2 low, vec2 high) {
+ vec4 c = mix( col_ex, col_in, v_mul( step(low, coord) ));
+ return mix( c, col_ex, v_and( step(high, coord) ));
+}
+
+#endif // functions_glsl
+
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl
index cd014b732..956c31d4b 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl
@@ -7,7 +7,7 @@ uniform vec4 gcu_ColorStatic;
uniform float gcu_Weight;
#ifdef USE_COLOR_TEXTURE
- uniform vec4 gcu_ColorTexBBox;
+ uniform vec2 gcu_ColorTexBBox[3]; // box-min[2], box-max[2] and tex-size[2]
#endif
uniform mat4 gcu_PMVMatrix02[3]; // P, Mv, and Mvi
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl
index 265ab6915..a64b8ad4d 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl
@@ -8,11 +8,13 @@ varying vec2 gcv_FboTexCoord;
#ifdef USE_COLOR_TEXTURE
varying vec2 gcv_ColorTexCoord;
+ varying vec2 gcv_ColorTexExt;
#endif
#ifdef USE_COLOR_CHANNEL
varying vec4 gcv_Color;
#endif
+
#endif // varyings_glsl