28package com.jogamp.opengl.demos.graph.ui;
31import java.io.IOException;
32import java.net.URISyntaxException;
33import java.util.ArrayList;
34import java.util.Arrays;
37import com.jogamp.common.net.Uri;
38import com.jogamp.graph.curve.Region;
39import com.jogamp.graph.font.Font;
40import com.jogamp.graph.font.FontFactory;
41import com.jogamp.graph.font.FontScale;
42import com.jogamp.graph.ui.Group;
43import com.jogamp.graph.ui.Scene;
44import com.jogamp.graph.ui.Shape;
45import com.jogamp.graph.ui.layout.Alignment;
46import com.jogamp.graph.ui.layout.BoxLayout;
47import com.jogamp.graph.ui.layout.Gap;
48import com.jogamp.graph.ui.layout.GridLayout;
49import com.jogamp.graph.ui.layout.Margin;
50import com.jogamp.graph.ui.layout.Padding;
51import com.jogamp.graph.ui.shapes.Button;
52import com.jogamp.graph.ui.shapes.Label;
53import com.jogamp.graph.ui.shapes.MediaButton;
54import com.jogamp.graph.ui.shapes.Rectangle;
55import com.jogamp.graph.ui.widgets.MediaPlayer;
56import com.jogamp.graph.ui.widgets.RangeSlider;
57import com.jogamp.graph.ui.widgets.RangedGroup;
58import com.jogamp.graph.ui.widgets.RangedGroup.SliderParam;
59import com.jogamp.math.Vec2f;
60import com.jogamp.math.Vec2i;
61import com.jogamp.math.Vec3f;
62import com.jogamp.math.geom.AABBox;
63import com.jogamp.math.util.PMVMatrix4f;
64import com.jogamp.newt.event.KeyAdapter;
65import com.jogamp.newt.event.KeyEvent;
66import com.jogamp.newt.event.MouseEvent;
67import com.jogamp.newt.event.WindowAdapter;
68import com.jogamp.newt.event.WindowEvent;
69import com.jogamp.newt.opengl.GLWindow;
70import com.jogamp.opengl.GL;
71import com.jogamp.opengl.GLAutoDrawable;
72import com.jogamp.opengl.GLCapabilities;
73import com.jogamp.opengl.GLCapabilitiesImmutable;
74import com.jogamp.opengl.GLEventAdapter;
75import com.jogamp.opengl.GLProfile;
76import com.jogamp.opengl.demos.util.CommandlineOptions;
77import com.jogamp.opengl.demos.util.MiscUtils;
78import com.jogamp.opengl.util.Animator;
79import com.jogamp.opengl.util.av.GLMediaPlayer;
80import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
82import jogamp.graph.ui.TreeTool;
88 private static final float MediaGridWidth = 1f;
93 private static final boolean VERBOSE_UI =
false;
94 private static final List<String> MEDIA_SUFFIXES = Arrays.asList(
"mp4",
"mkv",
"m2v",
"avi");
97 private static String alang =
null;
98 private static String slang =
null;
99 private static int start_pos = 0;
100 private static float videoAspectRatio = 16f/9f;
101 private static boolean letterBox =
true;
102 private static boolean enableStills =
true;
105 public static void main(
final String[] args)
throws IOException {
106 float mmPerCellWidth = 50f;
107 int maxMediaFiles = 10000;
108 int gridColumns = -1;
109 String subFallbackFontFilename =
null;
110 String mediaDir =
null;
111 if( 0 != args.length ) {
112 final int[] idx = { 0 };
113 for (idx[0] = 0; idx[0] < args.length; ++idx[0]) {
114 if( options.
parse(args, idx) ) {
116 }
else if (args[idx[0]].equals(
"-dir")) {
118 mediaDir = args[idx[0]];
119 }
else if(args[idx[0]].equals(
"-max")) {
122 }
else if(args[idx[0]].equals(
"-aid")) {
125 }
else if(args[idx[0]].equals(
"-sid")) {
128 }
else if(args[idx[0]].equals(
"-alang")) {
130 alang = args[idx[0]];
131 }
else if(args[idx[0]].equals(
"-slang")) {
133 slang = args[idx[0]];
134 }
else if(args[idx[0]].equals(
"-start")) {
137 }
else if(args[idx[0]].equals(
"-ratio")) {
139 videoAspectRatio =
MiscUtils.
atof(args[idx[0]], videoAspectRatio);
140 }
else if(args[idx[0]].equals(
"-zoom")) {
142 }
else if(args[idx[0]].equals(
"-mmPerCell")) {
144 mmPerCellWidth =
MiscUtils.
atof(args[idx[0]], mmPerCellWidth);
145 }
else if(args[idx[0]].equals(
"-col")) {
148 }
else if(args[idx[0]].equals(
"-fallbackFont")) {
150 subFallbackFontFilename = args[idx[0]];
151 }
else if(args[idx[0]].equals(
"-texCount")) {
154 }
else if(args[idx[0]].equals(
"-noStills")) {
155 enableStills =
false;
159 if(
null != subFallbackFontFilename ) {
162 System.err.println(options);
163 System.err.println(
"mediaDir "+mediaDir);
164 System.err.println(
"maxMediaFiles "+maxMediaFiles);
165 System.err.println(
"aid "+aid+
", alang "+alang+
"; sid "+sid+
", slang "+slang);
166 System.err.println(
"texCount "+texCount);
167 System.err.println(
"boxRatio "+videoAspectRatio);
168 System.err.println(
"letterBox "+letterBox);
169 System.err.println(
"columns "+gridColumns);
172 final List<Uri> mediaFiles =
new ArrayList<Uri>();
173 if(
null != mediaDir && mediaDir.length() > 0 ) {
174 final File dir =
new File(mediaDir);
175 final File[] files = dir.listFiles((
final File pathname) -> {
176 if( !pathname.canRead() || !pathname.isFile() ) {
177 System.err.println(
"Not a file or not readable: "+pathname);
180 final String name = pathname.getName();
181 final int dot = name.lastIndexOf(
".");
182 if( 0 >= dot || dot == name.length() - 1 ) {
183 System.err.println(
"Not having a suffixe: "+pathname);
186 final String suffix = name.substring(dot+1);
187 if( !MEDIA_SUFFIXES.contains(suffix) ) {
188 System.err.println(
"Not having a media suffix: "+pathname+
", suffix '"+suffix+
"'");
193 Arrays.sort(files, (
final File f1,
final File f2) -> {
194 return f1.getAbsolutePath().compareTo(f2.getAbsolutePath());
196 for(
final File f : files) {
198 final Uri uri = Uri.valueOf(f);
199 if( mediaFiles.size() < maxMediaFiles ) {
200 mediaFiles.add( uri );
201 System.err.println(
"Adding media file: "+uri);
203 System.err.println(
"Dropping media file: "+uri);
205 }
catch (
final URISyntaxException e) {}
208 if( 0 == mediaFiles.size() ) {
209 System.err.println(
"No media files, exit.");
212 System.err.println(
"Media Files Count "+mediaFiles.size());
214 System.out.println(
"Requested: " + reqCaps);
233 public void windowDestroyNotify(
final WindowEvent e) {
237 animator.
add(window);
247 final float winAspectRatio, dpiV;
249 final int mediaRowsPerPage;
254 System.err.println(
"DPI "+dpi[0]+
" x "+dpi[1]+
", "+ppmm[0]+
" x "+ppmm[1]+
" pixel/mm");
258 System.err.println(
"HiDPI PixelScale: "+hasSurfacePixelScale1[0]+
"x"+hasSurfacePixelScale1[1]+
" (has)");
259 final float mmPerCellHeight = mmPerCellWidth / videoAspectRatio;
260 int _mediaRowsPerPage = (int)( ( window.
getSurfaceHeight() / ppmm[1] ) / mmPerCellHeight );
261 if( 0 >= gridColumns ) {
262 gridColumns = (int)( ( window.
getSurfaceWidth() * MediaGridWidth / ppmm[0] ) / mmPerCellWidth );
264 if( mediaFiles.size() < gridColumns * _mediaRowsPerPage ) {
265 gridColumns = (int)Math.floor( Math.sqrt ( mediaFiles.size() ) );
266 _mediaRowsPerPage = gridColumns;
268 mediaRowsPerPage = _mediaRowsPerPage;
269 gridDim =
new Vec2i(gridColumns, mediaRowsPerPage);
271 final float mediaCellWidth = videoAspectRatio;
272 final float mediaCellHeight = 1;
273 final Vec2f mediaGridSize =
new Vec2f(gridDim.x() * mediaCellWidth, mediaRowsPerPage * mediaCellHeight);
274 System.err.println(
"GridDim "+gridDim);
275 System.err.println(
"GridSize "+mediaGridSize);
276 System.err.println(
"CellSize "+mediaCellWidth+
" x "+mediaCellHeight+
", vAspectRatio "+videoAspectRatio);
282 new Gap(mediaCellHeight*0.1f, mediaCellWidth*0.1f)));
284 addMedia(scene, reqCaps.
getGLProfile(), mediaGrid, mediaFiles, videoAspectRatio);
288 System.err.println(
"MediaGrid "+mediaGrid);
289 System.err.println(
"MediaGrid "+mediaGrid.
getLayout());
293 new SliderParam(
new Vec2f(mediaCellWidth/20f, mediaGridSize.y()), mediaCellHeight/30f,
true));
300 final float row_f = val / mediaCellHeight;
301 System.err.println(
"VertSlider: row "+row_f+
", val["+old_val+
" -> "+val+
"], pct["+(100*old_val_pct)+
"% -> "+(100*val_pct)+
"%], minmax "+minmax);
306 System.err.println(
"GlyphView "+mediaView);
315 infoLabel.
setColor(0.1f, 0.1f, 0.1f, 1f);
331 public void keyReleased(
final KeyEvent e) {
340 final int[] shapeIdx = { 0 };
341 TreeTool.forAllRendered(scene,
false, pmv, (
final Shape s,
final PMVMatrix4f pmv_) -> {
343 System.err.printf(
"%03d: shape %s/%s, %s%n", shapeIdx[0], s.getClass().getSimpleName(), s.
getName(), s);
357 final float sxy = Math.min(sx, sy);
358 System.err.println(
"SceneBox "+sceneBox);
359 System.err.println(
"MainGridBox "+mainGridBox);
360 System.err.println(
"scale sx "+sx+
", sy "+sy+
", sxy "+sxy);
371 static void addMedia(
final Scene scene,
final GLProfile glp,
final Group grid,
372 final List<Uri> mediaFiles,
final float defRatio) {
373 final float zoomSize = 1;
374 for(
final Uri medium : mediaFiles) {
375 final GLMediaPlayer glMPlayer = GLMediaPlayerFactory.createDefault();
376 if( printNativeInfoOnce ) {
377 glMPlayer.printNativeInfo(System.err);
378 printNativeInfoOnce =
false;
381 glMPlayer.setTextureMinMagFilter(
new int[] {
GL.
GL_LINEAR, GL.GL_LINEAR } );
382 glMPlayer.setTextureUnit(1);
384 final List<Shape> customCtrls =
new ArrayList<Shape>();
386 final Font fontSymbols = FontFactory.getSymbolsFont();
387 if(
null == fontSymbols ) {
388 grid.addShape(
new Rectangle(options.
renderModes, defRatio, 1, 0.10f) );
391 final Button button =
new Button(options.
renderModes, fontSymbols,
392 fontSymbols.getUTF16String(
"reset_tv"), MediaPlayer.CtrlButtonWidth, MediaPlayer.CtrlButtonHeight, scene.getZEpsilon(16));
393 button.setName(
"reset");
394 button.setSpacing(MediaPlayer.SymSpacing, MediaPlayer.FixedSymSize).setPerp().setColor(MediaPlayer.CtrlCellCol);
395 button.onClicked((
final Shape s0,
final Vec3f pos,
final MouseEvent e) -> {
396 TreeTool.forAll(scene, (
final Shape s1) -> {
397 System.err.println(
"- "+s1.getName());
398 if( s1 instanceof MediaButton ) {
399 final MediaButton mb = (MediaButton)s1;
400 final GLMediaPlayer mp = mb.getGLMediaPlayer();
403 mp.setAudioVolume( 0f );
405 if( s1.getName().equals(
"muteLabel") ) {
408 if( s1.getName().equals(
"MediaGrid") ) {
410 System.err.println(
"Reset: "+s1);
415 customCtrls.add(button);
417 final MediaPlayer graphMPlayer =
new MediaPlayer(options.
renderModes, scene, glMPlayer, medium, defRatio, letterBox, zoomSize, enableStills, customCtrls);
418 grid.addShape( graphMPlayer );
419 glMPlayer.playStream(medium, GLMediaPlayer.STREAM_ID_AUTO, alang, aid, slang, sid, texCount);
420 if( start_pos > 0 ) {
421 glMPlayer.seek(start_pos * 1000);
425 private static boolean printNativeInfoOnce =
true;
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
static final int NORM_RENDERING_BIT
Rendering-Mode bit for Region.
The optional property jogamp.graph.font.ctor allows user to specify the FontConstructor implementatio...
static synchronized void setFallbackFont(final Font f)
Registers given Font as the default fallback font.
static synchronized Font getFallbackFont()
Returns registered fallback Font, maybe null.
static final FontSet get(final int font)
static Font getDefaultFont()
Returns default Font of default FontSet or null if n/a.
Simple static font scale methods for unit conversions.
static float[] ppmmToPPI(final float[] ppmm)
Converts [1/mm] to [1/inch] in place.
Group of Shapes, optionally utilizing a Group.Layout.
void addShape(final Shape s)
Adds a Shape.
Layout getLayout()
Return current Group.Layout.
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
void setRelayoutOnDirtyShapes(final boolean v)
Set relayout on dirty shapes mode, defaults to true.
void addShape(final Shape s)
Adds a Shape.
final void setClearParams(final float[] clearColor, final int clearMask)
Sets the clear parameter for glClearColor(..) and glClear(..) to be issued at display(GLAutoDrawable)...
final void setPMvCullingEnabled(final boolean v)
Enable or disable Project-Modelview (PMv) frustum culling per Shape for this container.
void waitUntilDisplayed()
Blocks until first display(GLAutoDrawable) has completed after construction or dispose(GLAutoDrawable...
void setupMatrix(final PMVMatrix4f pmv, final Recti viewport)
Setup PMVMatrix4f GLMatrixFunc#GL_PROJECTION and GLMatrixFunc#GL_MODELVIEW by calling getPMVMatrixSet...
void addGLEventListener(final GLEventListener listener)
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
synchronized void attachInputListenerTo(final GLWindow window)
String getStatusText(final GLAutoDrawable glad, final int renderModes, final float dpi)
Return a formatted status string containing avg fps and avg frame duration.
File nextScreenshotFile(final String dir, final String prefix, final int renderModes, final GLCapabilitiesImmutable caps, final String contentDetail)
Return the unique next technical screenshot PNG File instance as follows:
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Shape setColor(final float r, final float g, final float b, final float a)
Set base color.
Shape setName(final String name)
Set a symbolic name for this shape for identification.
final String getName()
Return the optional symbolic name for this shape, defaults to noname.
final Shape setInteractive(final boolean v)
Set whether this shape is interactive in general, i.e.
final Shape moveTo(final float tx, final float ty, final float tz)
Move to scaled position.
final Shape setDragAndResizable(final boolean v)
Set whether this shape is draggable and resizable.
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
final Shape setPaddding(final Padding padding)
Sets the unscaled padding for this shape, which is included in unscaled getBounds() and also includes...
final Shape scale(final Vec3f s)
Multiply current scale factor by given scale.
final Shape setToggleable(final boolean toggleable)
Set this shape toggleable, default is off.
Immutable layout alignment options, including Bit#Fill.
static final Alignment None
No alignment constant.
static final Alignment FillCenter
Bit#Fill, Bit#CenterHoriz and Bit#CenterVert alignment constant.
GraphUI Stack Group.Layout.
GraphUI CSS property Gap, scaled spacing between (grid) cells not belonging to the cell element.
GraphUI Grid Group.Layout.
GraphUI CSS property Margin, scaled space between or around elements and not included in the element'...
GraphUI CSS property Padding, unscaled space belonging to the element and included in the element's s...
A GraphUI text label GraphShape.
boolean setText(final CharSequence text)
Set the text to be rendered.
2D Vector based upon two float components.
2D Vector based upon two integer components.
3D Vector based upon three float components.
Axis Aligned Bounding Box.
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
static final short VK_F4
Constant for the F4 function key.
static final short VK_ESCAPE
Constant for the ESCAPE function key.
final short getKeySymbol()
Returns the virtual key symbol reflecting the current keyboard layout.
static final short VK_D
See VK_A.
static final short VK_S
See VK_A.
static final short VK_Q
See VK_A.
Pointer event of type PointerType.
NEWT Window events are provided for notification purposes ONLY.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
final int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
final void setTitle(final String title)
final float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter of this window's NativeSurface according to the main monitor's curr...
final void addKeyListener(final KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
final float[] getCurrentSurfaceScale(final float[] result)
Returns the current pixel scale of the associated NativeSurface.
final int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
final void addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Specifies a set of OpenGL capabilities.
final GLProfile getGLProfile()
Returns the GL profile you desire or used by the drawable.
Specifies the the OpenGL profile.
GLCapabilities getGLCaps()
int graphAASamples
Sample count for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT or Region#MSAA_RENDERING_BIT...
void parse(final String[] args)
static int atoi(final String str, final int def)
static void destroyWindow(final GLAutoDrawable glad)
static float atof(final String str, final float def)
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final void setUpdateFPSFrames(final int frames, final PrintStream out)
final synchronized boolean start()
Starts this animator, if not running.
final synchronized boolean stop()
Stops this animator.
CenterVert
Vertical center alignment.
Fill
Scale object to parent size, e.g.
Interface wrapper for font implementation.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
boolean invoke(boolean wait, GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Specifies an immutable set of OpenGL capabilities.
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
static final int GL_LINEAR
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_LINEAR" with expressi...
static final int GL_DEPTH_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_BUFFER_BIT" wit...