diff options
author | Sven Gothel <[email protected]> | 2019-07-08 05:10:02 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2019-07-08 05:10:02 +0200 |
commit | 0f97d9292cc7ff97f61f68b69c5a375cc023a5af (patch) | |
tree | 9e669aff05ec49482db63e0f5fe608e8744f153a /src/demos | |
parent | d488ff097fc329a3185c6c64a8a6908e1f9f63d6 (diff) |
NEWT iOS: Support Multi-Touch Events, PixelScale, ..
Note: Two subsequent commit will add some required change in the
native UIWindow/UIView creation methods to actually make the NEWT view being displayed ;-)
The demo 'com.jogamp.opengl.demos.ios.Hello' demonstrated a standard NEWT application
running on iOS.
Previous NativeWindow wrap-around demo is preserved in 'com.jogamp.opengl.demos.ios.Hello1'.
Tested on ipad 11'inch arm64 and x86_64 simulation:
- Using GearsES2 demo
- PixelScale 1f, 2f and 0f - last two using max pixel scale
- Touch w/ GearsES2 works:
-- 1 finger rotate
-- 2 finger drag
-- 2 finger pinch-zoom gesture detection
Diffstat (limited to 'src/demos')
-rw-r--r-- | src/demos/com/jogamp/opengl/demos/ios/Hello.java | 137 | ||||
-rw-r--r-- | src/demos/com/jogamp/opengl/demos/ios/Hello1.java | 234 |
2 files changed, 321 insertions, 50 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/ios/Hello.java b/src/demos/com/jogamp/opengl/demos/ios/Hello.java index 9982d7d1f..378868bea 100644 --- a/src/demos/com/jogamp/opengl/demos/ios/Hello.java +++ b/src/demos/com/jogamp/opengl/demos/ios/Hello.java @@ -29,26 +29,20 @@ package com.jogamp.opengl.demos.ios; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.VersionUtil; -import com.jogamp.nativewindow.AbstractGraphicsScreen; -import com.jogamp.nativewindow.MutableGraphicsConfiguration; -import com.jogamp.nativewindow.NativeWindowFactory; -import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos; - +import com.jogamp.nativewindow.ScalableSurface; +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.opengl.GLWindow; import com.jogamp.common.GlueGenVersion; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.demos.es2.RedSquareES2; import com.jogamp.opengl.util.Animator; -import com.jogamp.opengl.util.AnimatorBase; -import jogamp.nativewindow.WrappedWindow; import jogamp.nativewindow.ios.IOSUtil; -import jogamp.opengl.GLDrawableFactoryImpl; -import com.jogamp.opengl.GLAutoDrawableDelegate; +import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; -import com.jogamp.opengl.GLCapabilitiesImmutable; -import com.jogamp.opengl.GLDrawable; -import com.jogamp.opengl.GLDrawableFactory; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.GLProfile; @@ -60,8 +54,17 @@ public class Hello { } catch (final NumberFormatException nfe) {} return def; } + private static float parseFloat(final String s, final float def) { + try { + return Float.parseFloat(s); + } catch (final NumberFormatException nfe) {} + return def; + } public static void main(final String[] args) { + final float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + + int secondsDuration = 10; // 10s int width = 832, height = 480; // ipad pro 11: 2388x1668 px (scale: 2) int fboDepthBits = -1; // CAEAGLLayer fails with depth 16 + 24 in Simulation; -1 means don't change boolean exitJVM = false; @@ -77,6 +80,11 @@ public class Hello { height = parseInt(args[++i], height); } else if(args[i].equals("-fboDepthBits") && i+1<args.length) { fboDepthBits = parseInt(args[++i], fboDepthBits); + } else if(args[i].equals("-pixelScale") && i+1<args.length) { + reqSurfacePixelScale[0] = parseFloat(args[++i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[1] = reqSurfacePixelScale[0]; + } else if(args[i].equals("-seconds") && i+1<args.length) { + secondsDuration = parseInt(args[++i], secondsDuration); } else { System.err.println("ignoring arg["+i+"]: "+args[i]); } @@ -115,8 +123,7 @@ public class Hello { System.err.println("mark-04"); System.err.println(""); - GLAutoDrawableDelegate glad = null; - final long uiWindow = IOSUtil.CreateUIWindow(0, 0, width, height); + GLWindow glWindow = null; try { // 1) Config .. final GLProfile glp = GLProfile.getGL2ES2(); @@ -125,39 +132,44 @@ public class Hello { reqCaps.setDepthBits(fboDepthBits); } System.out.println("Requested GL Caps: "+reqCaps); - final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(glp); - - // 2) Create native window and wrap it around out NativeWindow structure - final long uiView = IOSUtil.GetUIView(uiWindow, true); - final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView); - System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow)); - System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView)); - System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer)); - System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+ - ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer)); - final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(NativeWindowFactory.createDevice(null, true /* own */), -1); - final UpstreamWindowHookMutableSizePos hook = new UpstreamWindowHookMutableSizePos(0, 0, width, height, width, height); - final MutableGraphicsConfiguration config = new MutableGraphicsConfiguration(aScreen, reqCaps, reqCaps); - final WrappedWindow nativeWindow = new WrappedWindow(config, uiView, hook, true, uiWindow); - - // 3) Create a GLDrawable .. - final GLDrawable drawable = factory.createGLDrawable(nativeWindow); - drawable.setRealized(true); - // final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(aScreen.getDevice(), reqCaps, null, width, height); - glad = new GLAutoDrawableDelegate(drawable, null, nativeWindow, false, null) { - @Override - protected void destroyImplInLock() { - super.destroyImplInLock(); // destroys drawable/context - nativeWindow.destroy(); // destroys the actual window, incl. the device - IOSUtil.DestroyUIWindow(uiWindow); + + // 2) Create newt native window + final Display dpy = NewtFactory.createDisplay(null); + final Screen screen = NewtFactory.createScreen(dpy, 0); + glWindow = GLWindow.create(screen, reqCaps); + glWindow.setSurfaceScale(reqSurfacePixelScale); + final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]); + glWindow.setSize(width, height); + glWindow.setPosition(0, 0); + final GLEventListener tracker = new GLEventListener() { + void printInfo(final String prefix, final GLAutoDrawable d, final String postfix) { + System.out.print(prefix+": drawable "+d.getSurfaceWidth()+"x"+d.getSurfaceHeight()); + if(null != postfix) { + System.out.println(" - "+postfix); + } else { + System.out.println(); } - }; - glad.display(); // force native context creation + } + @Override + public void init(final GLAutoDrawable drawable) { + printInfo("GLEvent::Init", drawable, null); + } - // Check caps of GLDrawable after realization - final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); - System.out.println("Choosen GL Caps: "+chosenCaps); + @Override + public void dispose(final GLAutoDrawable drawable) { + printInfo("GLEvent::Dispose", drawable, null); + } + + @Override + public void display(final GLAutoDrawable drawable) { + } + @Override + public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { + printInfo("GLEvent::Reshape", drawable, "reshape["+x+"/"+y+" "+width+"x"+height+"]"); + } + }; + glWindow.addGLEventListener(tracker); GLEventListener demo = null; { try { @@ -170,15 +182,36 @@ public class Hello { } } System.out.println("Choosen demo "+demo.getClass().getName()); - glad.addGLEventListener(demo); + glWindow.addGLEventListener(demo); + glWindow.setVisible(true); // force native context creation + + // Check caps of GLDrawable after realization + System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); + System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); + System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+"[wu] "+glWindow.getWidth()+"x"+glWindow.getHeight()+"[wu] "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+"[px], "+glWindow.getInsets()); + + final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + { + final long uiWindow = glWindow.getWindowHandle(); + final long uiView = IOSUtil.GetUIView(uiWindow, true); + final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView); + System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow)); + System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView)); + System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer)); + System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+ + ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer)); + } final Animator animator = new Animator(); // animator.setExclusiveContext(exclusiveContext); animator.setUpdateFPSFrames(60, System.err); - animator.add(glad); + animator.add(glWindow); animator.start(); - for(int i=0; i<10; i++) { // 10s + for(int i=0; i<secondsDuration; i++) { try { Thread.sleep(1000); } catch (final InterruptedException e) { @@ -188,13 +221,17 @@ public class Hello { animator.stop(); } finally { - if( null != glad ) { - glad.destroy(); + System.err.println(""); + System.err.println("mark-05"); + System.err.println(""); + + if( null != glWindow ) { + glWindow.destroy(); } } System.err.println(""); - System.err.println("mark-05"); + System.err.println("mark-06"); System.err.println(""); if( exitJVM ) { diff --git a/src/demos/com/jogamp/opengl/demos/ios/Hello1.java b/src/demos/com/jogamp/opengl/demos/ios/Hello1.java new file mode 100644 index 000000000..e0c3be871 --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/ios/Hello1.java @@ -0,0 +1,234 @@ +/** + * Copyright 2019 Gothel Software e.K. 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 Gothel Software e.K. ``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 Gothel Software e.K. 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 Gothel Software e.K. + */ +package com.jogamp.opengl.demos.ios; + +import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.nativewindow.AbstractGraphicsScreen; +import com.jogamp.nativewindow.MutableGraphicsConfiguration; +import com.jogamp.nativewindow.NativeWindowFactory; +import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos; + +import com.jogamp.common.GlueGenVersion; +import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.demos.es2.RedSquareES2; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; + +import jogamp.nativewindow.WrappedWindow; +import jogamp.nativewindow.ios.IOSUtil; +import jogamp.opengl.GLDrawableFactoryImpl; + +import com.jogamp.opengl.GLAutoDrawable; +import com.jogamp.opengl.GLAutoDrawableDelegate; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.GLDrawable; +import com.jogamp.opengl.GLDrawableFactory; +import com.jogamp.opengl.GLEventListener; +import com.jogamp.opengl.GLProfile; + +public class Hello1 { + + private static int parseInt(final String s, final int def) { + try { + return Integer.parseInt(s); + } catch (final NumberFormatException nfe) {} + return def; + } + + public static void main(final String[] args) { + int width = 832, height = 480; // ipad pro 11: 2388x1668 px (scale: 2) + int fboDepthBits = -1; // CAEAGLLayer fails with depth 16 + 24 in Simulation; -1 means don't change + boolean exitJVM = false; + String demoName = "com.jogamp.opengl.demos.es2.GearsES2"; + for(int i=0; i<args.length; i++) { + if(args[i].equals("-exit")) { + exitJVM = true; + } else if(args[i].equals("-demo") && i+1<args.length) { + demoName = args[++i]; + } else if(args[i].equals("-width") && i+1<args.length) { + width = parseInt(args[++i], width); + } else if(args[i].equals("-height") && i+1<args.length) { + height = parseInt(args[++i], height); + } else if(args[i].equals("-fboDepthBits") && i+1<args.length) { + fboDepthBits = parseInt(args[++i], fboDepthBits); + } else { + System.err.println("ignoring arg["+i+"]: "+args[i]); + } + } + System.out.println("Hello JogAmp World: exitJVM "+exitJVM+", size "+width+"x"+height+", fboDepthBits "+fboDepthBits+", demo "+demoName); + System.out.println("os.name: <"+System.getProperty("os.name")+">"); + System.out.println("os.version: <"+System.getProperty("os.version")+">"); + System.out.println("os.arch: <"+System.getProperty("os.arch")+">"); + System.out.println("java.vendor: <"+System.getProperty("java.vendor")+">"); + System.out.println("java.vendor.url: <"+System.getProperty("java.vendor.url")+">"); + System.out.println("java.version: <"+System.getProperty("java.version")+">"); + System.out.println("java.vm.name: <"+System.getProperty("java.vm.name")+">"); + System.out.println("java.runtime.name: <"+System.getProperty("java.runtime.name")+">"); + System.out.println(""); + System.out.println(VersionUtil.getPlatformInfo()); + System.out.println(""); + System.out.println("Version Info:"); + System.out.println(GlueGenVersion.getInstance()); + System.out.println(""); + System.out.println("Full Manifest:"); + System.out.println(GlueGenVersion.getInstance().getFullManifestInfo(null)); + + System.out.println(""); + System.err.println("mark-01"); + System.err.println(""); + System.err.println(JoglVersion.getInstance()); + System.err.println(""); + System.err.println("mark-02"); + System.err.println(""); + GLProfile.initSingleton(); + System.err.println(""); + System.err.println("mark-03"); + System.out.println(""); + System.out.println(JoglVersion.getDefaultOpenGLInfo(GLProfile.getDefaultDevice(), null, true)); + System.out.println(""); + System.err.println("mark-04"); + System.err.println(""); + + GLAutoDrawableDelegate glad = null; + final long uiWindow = IOSUtil.CreateUIWindow(0, 0, width, height); + try { + // 1) Config .. + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities reqCaps = new GLCapabilities(glp); + if( 0 <= fboDepthBits) { + reqCaps.setDepthBits(fboDepthBits); + } + System.out.println("Requested GL Caps: "+reqCaps); + final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(glp); + + // 2) Create native window and wrap it around out NativeWindow structure + final long uiView = IOSUtil.GetUIView(uiWindow, true); + final long caeaglLayer = IOSUtil.GetCAEAGLLayer(uiView); + System.out.println("EAGL: UIWindow 0x"+Long.toHexString(uiWindow)); + System.out.println("EAGL: UIView 0x"+Long.toHexString(uiView)); + System.out.println("EAGL: EAGLLayer 0x"+Long.toHexString(caeaglLayer)); + System.out.println("isUIWindow "+IOSUtil.isUIWindow(uiWindow)+", isUIView "+IOSUtil.isUIView(uiView)+ + ", isCAEAGLLayer "+IOSUtil.isCAEAGLLayer(caeaglLayer)); + final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(NativeWindowFactory.createDevice(null, true /* own */), -1); + final UpstreamWindowHookMutableSizePos hook = new UpstreamWindowHookMutableSizePos(0, 0, width, height, width, height); + final MutableGraphicsConfiguration config = new MutableGraphicsConfiguration(aScreen, reqCaps, reqCaps); + final WrappedWindow nativeWindow = new WrappedWindow(config, uiView, hook, true, uiWindow); + + // 3) Create a GLDrawable .. + final GLDrawable drawable = factory.createGLDrawable(nativeWindow); + drawable.setRealized(true); + // final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(aScreen.getDevice(), reqCaps, null, width, height); + glad = new GLAutoDrawableDelegate(drawable, null, nativeWindow, false, null) { + @Override + protected void destroyImplInLock() { + super.destroyImplInLock(); // destroys drawable/context + nativeWindow.destroy(); // destroys the actual window, incl. the device + IOSUtil.DestroyUIWindow(uiWindow); + } + }; + final GLEventListener tracker = new GLEventListener() { + void printInfo(final String prefix, final GLAutoDrawable d, final String postfix) { + System.out.print(prefix+": drawable "+d.getSurfaceWidth()+"x"+d.getSurfaceHeight()); + if(null != postfix) { + System.out.println(" - "+postfix); + } else { + System.out.println(); + } + } + @Override + public void init(final GLAutoDrawable drawable) { + printInfo("GLEvent::Init", drawable, null); + } + + @Override + public void dispose(final GLAutoDrawable drawable) { + printInfo("GLEvent::Dispose", drawable, null); + } + + @Override + public void display(final GLAutoDrawable drawable) { + } + + @Override + public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { + printInfo("GLEvent::Reshape", drawable, "reshape["+x+"/"+y+" "+width+"x"+height+"]"); + } + }; + glad.addGLEventListener(tracker); + glad.display(); // force native context creation + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); + System.out.println("Choosen GL Caps: "+chosenCaps); + + GLEventListener demo = null; + { + try { + demo = (GLEventListener) ReflectionUtil.createInstance(demoName, Hello1.class.getClassLoader()); + } catch( final Exception e ) { + System.err.println(e.getMessage()+" using: <"+demoName+">"); + } + if( null == demo ) { + demo = new RedSquareES2(); + } + } + System.out.println("Choosen demo "+demo.getClass().getName()); + glad.addGLEventListener(demo); + + final Animator animator = new Animator(); + // animator.setExclusiveContext(exclusiveContext); + animator.setUpdateFPSFrames(60, System.err); + animator.add(glad); + animator.start(); + + for(int i=0; i<10; i++) { // 10s + try { + Thread.sleep(1000); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + } + animator.stop(); + + } finally { + if( null != glad ) { + glad.destroy(); + } + } + + System.err.println(""); + System.err.println("mark-05"); + System.err.println(""); + + if( exitJVM ) { + System.exit(0); + } + } +} |