aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-06-16 04:14:56 +0200
committerSven Gothel <[email protected]>2013-06-16 04:14:56 +0200
commit4fe6cf06f74085cc90d1f5b003fd717234d43ced (patch)
tree07fce156c9e6bdb400c734dca74d98513fcf2e40 /src
parentea85d60b854e2b6720dc0ef2b43c783074a66abf (diff)
Bug 735: Adding Andres test cases for analysis. OSX exposes diff. odd behaviors - See BugXYZ test cases.
Diffstat (limited to 'src')
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java427
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java429
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java253
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv3AppletAWT.java203
-rw-r--r--src/test/com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java188
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java184
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java175
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java258
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.fp339
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.vp11
10 files changed, 2467 insertions, 0 deletions
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java
new file mode 100644
index 000000000..b240f0cfb
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java
@@ -0,0 +1,427 @@
+package com.jogamp.opengl.test.bugs;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.nio.FloatBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.awt.GLCanvas;
+import javax.media.opengl.glu.GLU;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+/**
+ * Original test case.
+ * <br/>
+ * OSX Results:
+ * <pre>
+ * - Only RED Clear Color
+ * </pre>
+ */
+@SuppressWarnings("serial")
+public class Bug735Inv0AppletAWT extends Applet implements Runnable {
+ static public int AWT = 0;
+ static public int NEWT = 1;
+
+ static public int APPLET_WIDTH = 500;
+ static public int APPLET_HEIGHT = 290;
+ static public int TARGET_FPS = 120;
+ static public int TOOLKIT = NEWT;
+ static public boolean MANUAL_FRAME_HANDLING = true;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ static private Frame frame;
+ static private Bug735Inv0AppletAWT applet;
+ private GLCanvas awtCanvas;
+ private GLWindow newtWindow;
+ private NewtCanvasAWT newtCanvas;
+ private DrawRunnable drawRunnable;
+ private GLContext context;
+ private GLU glu;
+
+ private int width;
+ private int height;
+ private Thread thread;
+
+ private boolean doneInit = false;
+ private boolean doneSetup = false;
+
+ private long frameRatePeriod = 1000000000L / TARGET_FPS;
+ private long millisOffset;
+ private int frameCount;
+ private float frameRate;
+
+ private ShaderCode vertShader;
+ private ShaderCode fragShader;
+ private ShaderProgram shaderProg;
+ private ShaderState shaderState;
+ private GLUniformData resolution;
+ private GLUniformData time;
+ private GLArrayDataServer vertices;
+
+ private int fcount = 0, lastm = 0;
+ private int fint = 1;
+
+ public void init() {
+ setSize(APPLET_WIDTH, APPLET_HEIGHT);
+ setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
+ width = APPLET_WIDTH;
+ height = APPLET_HEIGHT;
+ }
+
+ public void start() {
+ thread = new Thread(this, "Animation Thread");
+ thread.start();
+ }
+
+ public void run() {
+ int noDelays = 0;
+ // Number of frames with a delay of 0 ms before the
+ // animation thread yields to other running threads.
+ final int NO_DELAYS_PER_YIELD = 15;
+ final int TIMEOUT_SECONDS = 2;
+
+ long beforeTime = System.nanoTime();
+ long overSleepTime = 0L;
+
+ millisOffset = System.currentTimeMillis();
+ frameCount = 1;
+ while (Thread.currentThread() == thread) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ requestDraw(latch);
+ try {
+ latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ if (frameCount == 1) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ requestFocusInWindow();
+ }
+ });
+ }
+
+ long afterTime = System.nanoTime();
+ long timeDiff = afterTime - beforeTime;
+ long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
+ if (sleepTime > 0) { // some time left in this cycle
+ try {
+ Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
+ noDelays = 0; // Got some sleep, not delaying anymore
+ } catch (InterruptedException ex) { }
+ overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
+ } else { // sleepTime <= 0; the frame took longer than the period
+ overSleepTime = 0L;
+ noDelays++;
+ if (noDelays > NO_DELAYS_PER_YIELD) {
+ Thread.yield(); // give another thread a chance to run
+ noDelays = 0;
+ }
+ }
+ beforeTime = System.nanoTime();
+ }
+ }
+
+ public void requestDraw(CountDownLatch latch) {
+ if (!doneInit) {
+ initDraw();
+ }
+
+ if (TOOLKIT == AWT) {
+ awtCanvas.invoke(true, drawRunnable);
+ } else if (TOOLKIT == NEWT) {
+ newtWindow.invoke(true, drawRunnable);
+ }
+
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+
+ private class DrawRunnable implements GLRunnable {
+ private boolean notCurrent;
+
+ @Override
+ public boolean run(GLAutoDrawable drawable) {
+ if (MANUAL_FRAME_HANDLING) {
+ makeContextCurrent();
+ }
+
+ if (doneSetup) {
+ draw(drawable.getGL().getGL2ES2());
+ } else {
+ setup(drawable.getGL().getGL2ES2());
+ }
+ checkGLErrors(drawable.getGL());
+
+ if (MANUAL_FRAME_HANDLING) {
+ swapBuffers();
+ releaseCurrentContext();
+ }
+
+ return true;
+ }
+
+ private void makeContextCurrent() {
+ int MAX_CONTEXT_GRAB_ATTEMPTS = 10;
+
+ if (context.isCurrent()) {
+ notCurrent = false;
+ } else {
+ notCurrent = true;
+ int value = GLContext.CONTEXT_NOT_CURRENT;
+ int attempt = 0;
+ do {
+ try {
+ value = context.makeCurrent();
+ System.out.println("Made context current");
+ } catch (final GLException gle) {
+ gle.printStackTrace();
+ } finally {
+ attempt++;
+ if (attempt == MAX_CONTEXT_GRAB_ATTEMPTS) {
+ throw new RuntimeException("Failed to claim OpenGL context.");
+ }
+ }
+ try {
+ Thread.sleep(5);
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ } while (value == GLContext.CONTEXT_NOT_CURRENT);
+ }
+ }
+
+ private void swapBuffers() {
+ final GL gl = GLContext.getCurrentGL();
+ gl.glFlush();
+ GLContext.getCurrent().getGLDrawable().swapBuffers();
+ }
+
+ private void releaseCurrentContext() {
+ if (notCurrent) {
+ try {
+ context.release();
+ System.out.println("Released context");
+ } catch (final GLException gle) {
+ gle.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void initGL() {
+ GLProfile profile = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(profile);
+ caps.setBackgroundOpaque(true);
+ caps.setOnscreen(true);
+ caps.setSampleBuffers(false);
+
+ if (TOOLKIT == AWT) {
+ awtCanvas = new GLCanvas(caps);
+ awtCanvas.setBounds(0, 0, applet.width, applet.height);
+ awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ awtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(awtCanvas, BorderLayout.CENTER);
+
+ if (MANUAL_FRAME_HANDLING) {
+ awtCanvas.setIgnoreRepaint(true);
+ awtCanvas.setAutoSwapBufferMode(false);
+ }
+ } else if (TOOLKIT == NEWT) {
+ newtWindow = GLWindow.create(caps);
+ newtCanvas = new NewtCanvasAWT(newtWindow);
+ newtCanvas.setBounds(0, 0, applet.width, applet.height);
+ newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ newtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(newtCanvas, BorderLayout.CENTER);
+
+ if (MANUAL_FRAME_HANDLING) {
+ newtCanvas.setIgnoreRepaint(true);
+ newtWindow.setAutoSwapBufferMode(false);
+ }
+ }
+ }
+
+ private void initDraw() {
+ if (TOOLKIT == AWT) {
+ awtCanvas.setVisible(true);
+ // Force the realization
+ awtCanvas.display();
+ if (awtCanvas.getDelegatedDrawable().isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ awtCanvas.requestFocus();
+ context = awtCanvas.getContext();
+ }
+ } else if (TOOLKIT == NEWT) {
+ newtCanvas.setVisible(true);
+ // Force the realization
+ newtWindow.display();
+ if (newtWindow.isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ newtCanvas.requestFocus();
+ context = newtWindow.getContext();
+ }
+ }
+
+ drawRunnable = new DrawRunnable();
+
+ doneInit = true;
+ }
+
+ private void setup(GL2ES2 gl) {
+ if (60 < TARGET_FPS) {
+ // Disables vsync
+ gl.setSwapInterval(0);
+ }
+ glu = new GLU();
+
+ vertShader = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
+ fragShader = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
+ shaderProg = new ShaderProgram();
+ shaderProg.add(gl, vertShader, System.err);
+ shaderProg.add(gl, fragShader, System.err);
+
+ shaderState = new ShaderState();
+ shaderState.attachShaderProgram(gl, shaderProg, true);
+
+ resolution = new GLUniformData("iResolution", 3, FloatBuffer.wrap(new float[] {width, height, 0}));
+ shaderState.ownUniform(resolution);
+ shaderState.uniform(gl, resolution);
+
+ time = new GLUniformData("iGlobalTime", 0.0f);
+ shaderState.ownUniform(time);
+
+ vertices = GLArrayDataServer.createGLSL("inVertex", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ vertices.putf(-1.0f); vertices.putf(-1.0f);
+ vertices.putf(+1.0f); vertices.putf(-1.0f);
+ vertices.putf(-1.0f); vertices.putf(+1.0f);
+ vertices.putf(+1.0f); vertices.putf(+1.0f);
+ vertices.seal(gl, true);
+ shaderState.ownAttribute(vertices, true);
+ shaderState.useProgram(gl, false);
+
+ doneSetup = true;
+ }
+
+ private void draw(GL2ES2 gl) {
+ gl.glClearColor(0.5f, 0.1f, 0.1f, 1);
+ gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT);
+
+ shaderState.useProgram(gl, true);
+
+ time.setData((System.currentTimeMillis() - millisOffset) / 1000.0f);
+ shaderState.uniform(gl, time);
+ vertices.enableBuffer(gl, true);
+ gl.glDrawArrays(GL2ES2.GL_TRIANGLE_STRIP, 0, 4);
+ vertices.enableBuffer(gl, false);
+
+ shaderState.useProgram(gl, false);
+
+ // Compute current framerate and printout.
+ frameCount++;
+ fcount += 1;
+ int m = (int) (System.currentTimeMillis() - millisOffset);
+ if (m - lastm > 1000 * fint) {
+ frameRate = (float)(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ }
+ if (frameCount % TARGET_FPS == 0) {
+ System.out.println("FrameCount: " + frameCount + " - " +
+ "FrameRate: " + frameRate);
+ }
+ }
+
+ private void checkGLErrors(GL gl) {
+ int err = gl.glGetError();
+ if (err != 0) {
+ String errString = glu.gluErrorString(err);
+ System.out.println(errString);
+ }
+ }
+
+ static public void main(String[] args) {
+ GraphicsEnvironment environment =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
+
+ frame = new Frame(displayDevice.getDefaultConfiguration());
+ frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
+ frame.setTitle("TestBug735InvAppletAWT");
+
+ try {
+ Class<?> c = Thread.currentThread().getContextClassLoader().
+ loadClass(Bug735Inv0AppletAWT.class.getName());
+ applet = (Bug735Inv0AppletAWT) c.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ frame.setLayout(null);
+ frame.add(applet);
+ frame.pack();
+ frame.setResizable(false);
+
+ applet.init();
+
+ Insets insets = frame.getInsets();
+ int windowW = applet.width + insets.left + insets.right;
+ int windowH = applet.height + insets.top + insets.bottom;
+ frame.setSize(windowW, windowH);
+
+ Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
+ frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
+ screenRect.y + (screenRect.height - applet.height) / 2);
+
+ int usableWindowH = windowH - insets.top - insets.bottom;
+ applet.setBounds((windowW - applet.width)/2,
+ insets.top + (usableWindowH - applet.height)/2,
+ applet.width, applet.height);
+
+ // This allows to close the frame.
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ applet.initGL();
+ frame.setVisible(true);
+ applet.start();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java
new file mode 100644
index 000000000..e1bdbba77
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java
@@ -0,0 +1,429 @@
+package com.jogamp.opengl.test.bugs;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.nio.FloatBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.awt.GLCanvas;
+import javax.media.opengl.glu.GLU;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+/**
+ * Difference to orig. Bug735Inv0AppletAWT:
+ * <pre>
+ * - MANUAL_FRAME_HANDLING false
+ * - MANUAL_FRAME_HANDLING: impl using pass through GLContext instead of static
+ * </pre>
+ * OSX Results:
+ * <pre>
+ * - Only RED Clear Color
+ * </pre>
+ */
+@SuppressWarnings("serial")
+public class Bug735Inv1AppletAWT extends Applet implements Runnable {
+ static public int AWT = 0;
+ static public int NEWT = 1;
+
+ static public int APPLET_WIDTH = 500;
+ static public int APPLET_HEIGHT = 290;
+ static public int TARGET_FPS = 120;
+ static public int TOOLKIT = NEWT;
+ static public boolean MANUAL_FRAME_HANDLING = false;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ static private Frame frame;
+ static private Bug735Inv1AppletAWT applet;
+ private GLCanvas awtCanvas;
+ private GLWindow newtWindow;
+ private NewtCanvasAWT newtCanvas;
+ private DrawRunnable drawRunnable;
+ // JAU private GLContext context;
+ private GLU glu;
+
+ private int width;
+ private int height;
+ private Thread thread;
+
+ private boolean doneInit = false;
+ private boolean doneSetup = false;
+
+ private long frameRatePeriod = 1000000000L / TARGET_FPS;
+ private long millisOffset;
+ private int frameCount;
+ private float frameRate;
+
+ private ShaderCode vertShader;
+ private ShaderCode fragShader;
+ private ShaderProgram shaderProg;
+ private ShaderState shaderState;
+ private GLUniformData resolution;
+ private GLUniformData time;
+ private GLArrayDataServer vertices;
+
+ private int fcount = 0, lastm = 0;
+ private int fint = 1;
+
+ public void init() {
+ setSize(APPLET_WIDTH, APPLET_HEIGHT);
+ setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
+ width = APPLET_WIDTH;
+ height = APPLET_HEIGHT;
+ }
+
+ public void start() {
+ thread = new Thread(this, "Animation Thread");
+ thread.start();
+ }
+
+ public void run() {
+ int noDelays = 0;
+ // Number of frames with a delay of 0 ms before the
+ // animation thread yields to other running threads.
+ final int NO_DELAYS_PER_YIELD = 15;
+ final int TIMEOUT_SECONDS = 2;
+
+ long beforeTime = System.nanoTime();
+ long overSleepTime = 0L;
+
+ millisOffset = System.currentTimeMillis();
+ frameCount = 1;
+ while (Thread.currentThread() == thread) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ requestDraw(latch);
+ try {
+ latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ if (frameCount == 1) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ requestFocusInWindow();
+ }
+ });
+ }
+
+ long afterTime = System.nanoTime();
+ long timeDiff = afterTime - beforeTime;
+ long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
+ if (sleepTime > 0) { // some time left in this cycle
+ try {
+ Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
+ noDelays = 0; // Got some sleep, not delaying anymore
+ } catch (InterruptedException ex) { }
+ overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
+ } else { // sleepTime <= 0; the frame took longer than the period
+ overSleepTime = 0L;
+ noDelays++;
+ if (noDelays > NO_DELAYS_PER_YIELD) {
+ Thread.yield(); // give another thread a chance to run
+ noDelays = 0;
+ }
+ }
+ beforeTime = System.nanoTime();
+ }
+ }
+
+ public void requestDraw(CountDownLatch latch) {
+ if (!doneInit) {
+ initDraw();
+ }
+
+ if (TOOLKIT == AWT) {
+ awtCanvas.invoke(true, drawRunnable);
+ } else if (TOOLKIT == NEWT) {
+ newtWindow.invoke(true, drawRunnable);
+ }
+
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+
+ private class DrawRunnable implements GLRunnable {
+ private boolean notCurrent;
+
+ @Override
+ public boolean run(GLAutoDrawable drawable) {
+ if (MANUAL_FRAME_HANDLING) {
+ makeContextCurrent(drawable.getContext());
+ }
+
+ if (!doneSetup) {
+ setup(drawable.getGL().getGL2ES2());
+ }
+ draw(drawable.getGL().getGL2ES2());
+ checkGLErrors(drawable.getGL());
+
+ if (MANUAL_FRAME_HANDLING) {
+ swapBuffers(drawable.getContext());
+ releaseCurrentContext(drawable.getContext());
+ }
+
+ return true;
+ }
+
+ private void makeContextCurrent(GLContext context) {
+ int MAX_CONTEXT_GRAB_ATTEMPTS = 10;
+
+ if (context.isCurrent()) {
+ notCurrent = false;
+ } else {
+ notCurrent = true;
+ int value = GLContext.CONTEXT_NOT_CURRENT;
+ int attempt = 0;
+ do {
+ try {
+ value = context.makeCurrent();
+ System.out.println("Made context current");
+ } catch (final GLException gle) {
+ gle.printStackTrace();
+ } finally {
+ attempt++;
+ if (attempt == MAX_CONTEXT_GRAB_ATTEMPTS) {
+ throw new RuntimeException("Failed to claim OpenGL context.");
+ }
+ }
+ try {
+ Thread.sleep(5);
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ } while (value == GLContext.CONTEXT_NOT_CURRENT);
+ }
+ }
+
+ private void swapBuffers(GLContext context) {
+ final GL gl = context.getGL();
+ gl.glFlush();
+ context.getGLDrawable().swapBuffers();
+ }
+
+ private void releaseCurrentContext(GLContext context) {
+ if (notCurrent) {
+ try {
+ context.release();
+ System.out.println("Released context");
+ } catch (final GLException gle) {
+ gle.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void initGL() {
+ GLProfile profile = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(profile);
+ caps.setBackgroundOpaque(true);
+ caps.setOnscreen(true);
+ caps.setSampleBuffers(false);
+
+ if (TOOLKIT == AWT) {
+ awtCanvas = new GLCanvas(caps);
+ awtCanvas.setBounds(0, 0, applet.width, applet.height);
+ awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ awtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(awtCanvas, BorderLayout.CENTER);
+
+ if (MANUAL_FRAME_HANDLING) {
+ awtCanvas.setIgnoreRepaint(true);
+ awtCanvas.setAutoSwapBufferMode(false);
+ }
+ } else if (TOOLKIT == NEWT) {
+ newtWindow = GLWindow.create(caps);
+ newtCanvas = new NewtCanvasAWT(newtWindow);
+ newtCanvas.setBounds(0, 0, applet.width, applet.height);
+ newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ newtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(newtCanvas, BorderLayout.CENTER);
+
+ if (MANUAL_FRAME_HANDLING) {
+ newtCanvas.setIgnoreRepaint(true);
+ newtWindow.setAutoSwapBufferMode(false);
+ }
+ }
+ }
+
+ private void initDraw() {
+ if (TOOLKIT == AWT) {
+ awtCanvas.setVisible(true);
+ // Force the realization
+ awtCanvas.display();
+ if (awtCanvas.getDelegatedDrawable().isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ awtCanvas.requestFocus();
+ }
+ } else if (TOOLKIT == NEWT) {
+ newtCanvas.setVisible(true);
+ // Force the realization
+ newtWindow.display();
+ if (newtWindow.isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ newtCanvas.requestFocus();
+ }
+ }
+
+ drawRunnable = new DrawRunnable();
+
+ doneInit = true;
+ }
+
+ private void setup(GL2ES2 gl) {
+ if (60 < TARGET_FPS) {
+ // Disables vsync
+ gl.setSwapInterval(0);
+ }
+ glu = new GLU();
+
+ vertShader = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
+ fragShader = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
+ vertShader.defaultShaderCustomization(gl, true, true);
+ fragShader.defaultShaderCustomization(gl, true, true);
+ shaderProg = new ShaderProgram();
+ shaderProg.add(gl, vertShader, System.err);
+ shaderProg.add(gl, fragShader, System.err);
+
+ shaderState = new ShaderState();
+ shaderState.attachShaderProgram(gl, shaderProg, true);
+
+ resolution = new GLUniformData("iResolution", 3, FloatBuffer.wrap(new float[] {width, height, 0}));
+ shaderState.ownUniform(resolution);
+ shaderState.uniform(gl, resolution);
+
+ time = new GLUniformData("iGlobalTime", 0.0f);
+ shaderState.ownUniform(time);
+
+ vertices = GLArrayDataServer.createGLSL("inVertex", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ vertices.putf(-1.0f); vertices.putf(-1.0f);
+ vertices.putf(+1.0f); vertices.putf(-1.0f);
+ vertices.putf(-1.0f); vertices.putf(+1.0f);
+ vertices.putf(+1.0f); vertices.putf(+1.0f);
+ vertices.seal(gl, true);
+ shaderState.ownAttribute(vertices, true);
+ shaderState.useProgram(gl, false);
+
+ doneSetup = true;
+ }
+
+ private void draw(GL2ES2 gl) {
+ gl.glClearColor(0.5f, 0.1f, 0.1f, 1);
+ gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT);
+
+ shaderState.useProgram(gl, true);
+
+ time.setData((System.currentTimeMillis() - millisOffset) / 1000.0f);
+ shaderState.uniform(gl, time);
+ vertices.enableBuffer(gl, true);
+ gl.glDrawArrays(GL2ES2.GL_TRIANGLE_STRIP, 0, 4);
+ vertices.enableBuffer(gl, false);
+
+ shaderState.useProgram(gl, false);
+
+ // Compute current framerate and printout.
+ frameCount++;
+ fcount += 1;
+ int m = (int) (System.currentTimeMillis() - millisOffset);
+ if (m - lastm > 1000 * fint) {
+ frameRate = (float)(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ }
+ if (frameCount % TARGET_FPS == 0) {
+ System.out.println("FrameCount: " + frameCount + " - " +
+ "FrameRate: " + frameRate);
+ }
+ }
+
+ private void checkGLErrors(GL gl) {
+ int err = gl.glGetError();
+ if (err != 0) {
+ String errString = glu.gluErrorString(err);
+ System.out.println(errString);
+ }
+ }
+
+ static public void main(String[] args) {
+ GraphicsEnvironment environment =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
+
+ frame = new Frame(displayDevice.getDefaultConfiguration());
+ frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
+ frame.setTitle("TestBug735InvAppletAWT");
+
+ try {
+ Class<?> c = Thread.currentThread().getContextClassLoader().
+ loadClass(Bug735Inv1AppletAWT.class.getName());
+ applet = (Bug735Inv1AppletAWT) c.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ frame.setLayout(null);
+ frame.add(applet);
+ frame.pack();
+ frame.setResizable(false);
+
+ applet.init();
+
+ Insets insets = frame.getInsets();
+ int windowW = applet.width + insets.left + insets.right;
+ int windowH = applet.height + insets.top + insets.bottom;
+ frame.setSize(windowW, windowH);
+
+ Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
+ frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
+ screenRect.y + (screenRect.height - applet.height) / 2);
+
+ int usableWindowH = windowH - insets.top - insets.bottom;
+ applet.setBounds((windowW - applet.width)/2,
+ insets.top + (usableWindowH - applet.height)/2,
+ applet.width, applet.height);
+
+ // This allows to close the frame.
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ applet.initGL();
+ frame.setVisible(true);
+ applet.start();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java
new file mode 100644
index 000000000..34a3513ce
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java
@@ -0,0 +1,253 @@
+package com.jogamp.opengl.test.bugs;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+
+/**
+ * Difference to orig. Bug735Inv0AppletAWT:
+ * <pre>
+ * - Use GLEventListener
+ * - Add GLEventListener to GLAutoDrawable
+ * - Use GLAutoDrawable.display() instead of GLAutoDrawable.invoke(true, GLRunnable { init / render })
+ * - Removed MANUAL_FRAME_HANDLING, obsolete due to GLAutoDrawable/GLEventListener
+ * </pre>
+ * OSX Results:
+ * <pre>
+ * - Visible content
+ * - Stuttering, non-fluent and slow animation
+ * </pre>
+ */
+@SuppressWarnings("serial")
+public class Bug735Inv2AppletAWT extends Applet implements Runnable {
+ static public int AWT = 0;
+ static public int NEWT = 1;
+
+ static public int APPLET_WIDTH = 500;
+ static public int APPLET_HEIGHT = 290;
+ static public int TARGET_FPS = 120;
+ static public int TOOLKIT = NEWT;
+ static public boolean IGNORE_AWT_REPAINT = false;
+ static public boolean USE_ECT = false;
+ static public int SWAP_INTERVAL = 0;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ static private Frame frame;
+ static private Bug735Inv2AppletAWT applet;
+ private GLCanvas awtCanvas;
+ private GLWindow newtWindow;
+ private GLAutoDrawable glad;
+ private NewtCanvasAWT newtCanvas;
+ private GLEventListener demo;
+
+ private int width;
+ private int height;
+ private Thread thread;
+
+ private long frameRatePeriod = 1000000000L / TARGET_FPS;
+ private int frameCount;
+
+ public void init() {
+ setSize(APPLET_WIDTH, APPLET_HEIGHT);
+ setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
+ width = APPLET_WIDTH;
+ height = APPLET_HEIGHT;
+ initGL();
+ }
+
+ public void start() {
+ initDraw();
+ thread = new Thread(this, "Animation Thread");
+ thread.start();
+ }
+
+ public void run() {
+ int noDelays = 0;
+ // Number of frames with a delay of 0 ms before the
+ // animation thread yields to other running threads.
+ final int NO_DELAYS_PER_YIELD = 15;
+ final int TIMEOUT_SECONDS = 2;
+
+ long beforeTime = System.nanoTime();
+ long overSleepTime = 0L;
+
+ frameCount = 1;
+ while (Thread.currentThread() == thread) {
+ if (frameCount == 1) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ requestFocusInWindow();
+ }
+ });
+ if( USE_ECT ) {
+ glad.setExclusiveContextThread(thread);
+ }
+ }
+ final CountDownLatch latch = new CountDownLatch(1);
+ requestDraw(latch);
+ try {
+ latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ long afterTime = System.nanoTime();
+ long timeDiff = afterTime - beforeTime;
+ long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
+ if (sleepTime > 0) { // some time left in this cycle
+ try {
+ Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
+ noDelays = 0; // Got some sleep, not delaying anymore
+ } catch (InterruptedException ex) { }
+ overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
+ } else { // sleepTime <= 0; the frame took longer than the period
+ overSleepTime = 0L;
+ noDelays++;
+ if (noDelays > NO_DELAYS_PER_YIELD) {
+ Thread.yield(); // give another thread a chance to run
+ noDelays = 0;
+ }
+ }
+ beforeTime = System.nanoTime();
+ }
+ }
+
+ public void requestDraw(CountDownLatch latch) {
+ glad.display();
+
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+
+ private void initGL() {
+ GLProfile profile = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(profile);
+ caps.setBackgroundOpaque(true);
+ caps.setOnscreen(true);
+ caps.setSampleBuffers(false);
+
+ if (TOOLKIT == AWT) {
+ awtCanvas = new GLCanvas(caps);
+ awtCanvas.setBounds(0, 0, applet.width, applet.height);
+ awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ awtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(awtCanvas, BorderLayout.CENTER);
+
+ if (IGNORE_AWT_REPAINT) {
+ awtCanvas.setIgnoreRepaint(true);
+ }
+ glad = awtCanvas;
+ } else if (TOOLKIT == NEWT) {
+ newtWindow = GLWindow.create(caps);
+ newtCanvas = new NewtCanvasAWT(newtWindow);
+ newtCanvas.setBounds(0, 0, applet.width, applet.height);
+ newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ newtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(newtCanvas, BorderLayout.CENTER);
+
+ if (IGNORE_AWT_REPAINT) {
+ newtCanvas.setIgnoreRepaint(true);
+ }
+ glad = newtWindow;
+ }
+
+ demo = new LandscapeES2(SWAP_INTERVAL);
+ glad.addGLEventListener(demo);
+ }
+
+ private void initDraw() {
+ if (TOOLKIT == AWT) {
+ awtCanvas.setVisible(true);
+ // Force the realization
+ awtCanvas.display();
+ if (awtCanvas.getDelegatedDrawable().isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ awtCanvas.requestFocus();
+ }
+ } else if (TOOLKIT == NEWT) {
+ newtCanvas.setVisible(true);
+ // Force the realization
+ newtWindow.display();
+ if (newtWindow.isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ newtCanvas.requestFocus();
+ }
+ }
+ }
+
+ static public void main(String[] args) {
+ GraphicsEnvironment environment =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
+
+ frame = new Frame(displayDevice.getDefaultConfiguration());
+ frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
+ frame.setTitle("TestBug735Inv2AppletAWT");
+
+ try {
+ Class<?> c = Thread.currentThread().getContextClassLoader().
+ loadClass(Bug735Inv2AppletAWT.class.getName());
+ applet = (Bug735Inv2AppletAWT) c.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ frame.setLayout(null);
+ frame.add(applet);
+ frame.pack();
+ frame.setResizable(false);
+
+ applet.init();
+
+ Insets insets = frame.getInsets();
+ int windowW = applet.width + insets.left + insets.right;
+ int windowH = applet.height + insets.top + insets.bottom;
+ frame.setSize(windowW, windowH);
+
+ Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
+ frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
+ screenRect.y + (screenRect.height - applet.height) / 2);
+
+ int usableWindowH = windowH - insets.top - insets.bottom;
+ applet.setBounds((windowW - applet.width)/2,
+ insets.top + (usableWindowH - applet.height)/2,
+ applet.width, applet.height);
+
+ // This allows to close the frame.
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+ applet.start();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv3AppletAWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv3AppletAWT.java
new file mode 100644
index 000000000..132a6e464
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv3AppletAWT.java
@@ -0,0 +1,203 @@
+package com.jogamp.opengl.test.bugs;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.SwingUtilities;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.AnimatorBase;
+
+/**
+ * Difference to orig. Bug735Inv0AppletAWT:
+ * <pre>
+ * - Use GLEventListener
+ * - Add GLEventListener to GLAutoDrawable
+ * - Use GLAutoDrawable.display() instead of GLAutoDrawable.invoke(true, GLRunnable { init / render })
+ * - Removed MANUAL_FRAME_HANDLING, obsolete due to GLAutoDrawable/GLEventListener
+ * - Use Animator
+ * - Remove applet, component sizes, use frame based size via validate
+ * - Run frame validation/visibility on AWT-EDT
+ * - Add Wait-For-Key after init (perf-test)
+ * </pre>
+ * OSX Results:
+ * <pre>
+ * - Visible content
+ * - Stuttering, non-fluent and slow animation
+ * </pre>
+ */
+@SuppressWarnings("serial")
+public class Bug735Inv3AppletAWT extends Applet {
+ static public int AWT = 0;
+ static public int NEWT = 1;
+
+ static public int APPLET_WIDTH = 500;
+ static public int APPLET_HEIGHT = 290;
+ static public int TOOLKIT = NEWT;
+ static public boolean IGNORE_AWT_REPAINT = false;
+ static public boolean USE_ECT = false;
+ static public int SWAP_INTERVAL = 0;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ static boolean waitForKey = true;
+ static private Frame frame;
+ static private Bug735Inv3AppletAWT applet;
+ private GLCanvas awtCanvas;
+ private GLWindow newtWindow;
+ private GLAutoDrawable glad;
+ private NewtCanvasAWT newtCanvas;
+ private GLEventListener demo;
+ private AnimatorBase animator;
+
+ private int width;
+ private int height;
+
+ public void init() {
+ setSize(APPLET_WIDTH, APPLET_HEIGHT);
+ // JAU setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
+ width = APPLET_WIDTH;
+ height = APPLET_HEIGHT;
+ initGL();
+ }
+
+ public void start() {
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ initDraw();
+ animator.start();
+ }
+
+ private void initGL() {
+ GLProfile profile = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(profile);
+ caps.setBackgroundOpaque(true);
+ caps.setOnscreen(true);
+ caps.setSampleBuffers(false);
+
+ if (TOOLKIT == AWT) {
+ awtCanvas = new GLCanvas(caps);
+ // JAU awtCanvas.setBounds(0, 0, applet.width, applet.height);
+ awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ awtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(awtCanvas, BorderLayout.CENTER);
+
+ if (IGNORE_AWT_REPAINT) {
+ awtCanvas.setIgnoreRepaint(true);
+ }
+ glad = awtCanvas;
+ } else if (TOOLKIT == NEWT) {
+ newtWindow = GLWindow.create(caps);
+ newtCanvas = new NewtCanvasAWT(newtWindow);
+ // JAU newtCanvas.setBounds(0, 0, applet.width, applet.height);
+ newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ newtCanvas.setFocusable(true);
+
+ applet.setLayout(new BorderLayout());
+ applet.add(newtCanvas, BorderLayout.CENTER);
+
+ if (IGNORE_AWT_REPAINT) {
+ newtCanvas.setIgnoreRepaint(true);
+ }
+ glad = newtWindow;
+ }
+
+ demo = new LandscapeES2(SWAP_INTERVAL);
+ glad.addGLEventListener(demo);
+ animator = new Animator(glad);
+ animator.setExclusiveContext(USE_ECT);
+ }
+
+ private void initDraw() {
+ if (TOOLKIT == AWT) {
+ // JAU awtCanvas.setVisible(true);
+ if (awtCanvas.getDelegatedDrawable().isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ awtCanvas.requestFocus();
+ }
+ } else if (TOOLKIT == NEWT) {
+ // JAU newtCanvas.setVisible(true);
+ // Force the realization
+ // JAU newtWindow.display();
+ if (newtWindow.isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ newtCanvas.requestFocus();
+ }
+ }
+ }
+
+ static public void main(String[] args) {
+ final GraphicsEnvironment environment =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
+
+ frame = new Frame(displayDevice.getDefaultConfiguration());
+ frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
+ frame.setTitle("TestBug735Inv3AppletAWT");
+
+ // This allows to close the frame.
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ try {
+ Class<?> c = Thread.currentThread().getContextClassLoader().
+ loadClass(Bug735Inv3AppletAWT.class.getName());
+ applet = (Bug735Inv3AppletAWT) c.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ // JAU frame.setLayout(null);
+ frame.add(applet);
+
+ applet.init();
+
+ Insets insets = frame.getInsets();
+ final int windowW = applet.width + insets.left + insets.right;
+ final int windowH = applet.height + insets.top + insets.bottom;
+
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setSize(windowW, windowH);
+ frame.validate();
+ // JAU frame.pack();
+ Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
+ frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
+ screenRect.y + (screenRect.height - applet.height) / 2);
+
+ frame.setResizable(false);
+ frame.setVisible(true);
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ applet.start();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java
new file mode 100644
index 000000000..1c98af7d4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java
@@ -0,0 +1,188 @@
+package com.jogamp.opengl.test.bugs;
+
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.SwingUtilities;
+
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.AnimatorBase;
+
+/**
+ * Difference to orig. Bug735Inv0AppletAWT:
+ * <pre>
+ * - Use GLEventListener
+ * - Add GLEventListener to GLAutoDrawable
+ * - Use GLAutoDrawable.display() instead of GLAutoDrawable.invoke(true, GLRunnable { init / render })
+ * - Removed MANUAL_FRAME_HANDLING, obsolete due to GLAutoDrawable/GLEventListener
+ * - Use Animator
+ * - Remove component sizes, use frame based size via validate
+ * - Run frame validation/visibility on AWT-EDT
+ * - Add Wait-For-Key after init (perf-test)
+ * - Remove intermediate applet!
+ * </pre>
+ * OSX Results:
+ * <pre>
+ * - Visible content
+ * - Fluent animation
+ * </pre>
+ */
+public class Bug735Inv4AWT {
+ static public int AWT = 0;
+ static public int NEWT = 1;
+
+ static public int APPLET_WIDTH = 500;
+ static public int APPLET_HEIGHT = 290;
+ static public int TOOLKIT = NEWT;
+ static public boolean NEWT_ROOT = false;
+ static public boolean IGNORE_AWT_REPAINT = false;
+ static public boolean USE_ECT = false;
+ static public int SWAP_INTERVAL = 0;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ static boolean waitForKey = true;
+ static private Frame frame;
+ static private Bug735Inv4AWT applet;
+ private GLCanvas awtCanvas;
+ private GLWindow newtWindow;
+ private GLAutoDrawable glad;
+ private NewtCanvasAWT newtCanvas;
+ private GLEventListener demo;
+ private AnimatorBase animator;
+
+ private int width;
+ private int height;
+
+ public void init() {
+ width = APPLET_WIDTH;
+ height = APPLET_HEIGHT;
+ initGL();
+ }
+
+ public void start() {
+ if(waitForKey) {
+ UITestCase.waitForKey("Start");
+ }
+ initDraw();
+ animator.start();
+ }
+
+ private void initGL() {
+ GLProfile profile = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(profile);
+ caps.setBackgroundOpaque(true);
+ caps.setOnscreen(true);
+ caps.setSampleBuffers(false);
+
+ if (TOOLKIT == AWT) {
+ awtCanvas = new GLCanvas(caps);
+ awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ awtCanvas.setFocusable(true);
+
+ if (IGNORE_AWT_REPAINT) {
+ awtCanvas.setIgnoreRepaint(true);
+ }
+ glad = awtCanvas;
+ } else if (TOOLKIT == NEWT) {
+ newtWindow = GLWindow.create(caps);
+ newtCanvas = new NewtCanvasAWT(newtWindow);
+ newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
+ newtCanvas.setFocusable(true);
+
+ if (IGNORE_AWT_REPAINT) {
+ newtCanvas.setIgnoreRepaint(true);
+ }
+ glad = newtWindow;
+ }
+
+ demo = new LandscapeES2(SWAP_INTERVAL);
+ // demo = new GearsES2(SWAP_INTERVAL);
+ glad.addGLEventListener(demo);
+ animator = new Animator(glad);
+ animator.setExclusiveContext(USE_ECT);
+ }
+
+ private void initDraw() {
+ if (TOOLKIT == AWT) {
+ if (awtCanvas.getDelegatedDrawable().isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ awtCanvas.requestFocus();
+ }
+ } else if (TOOLKIT == NEWT) {
+ // newtCanvas.repaint();
+ // Force the realization
+ // newtWindow.display();
+ if (newtWindow.isRealized()) {
+ // Request the focus here as it cannot work when the window is not visible
+ newtCanvas.requestFocus();
+ }
+ }
+ }
+
+ static public void main(String[] args) {
+ final GraphicsEnvironment environment =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
+
+ frame = new Frame(displayDevice.getDefaultConfiguration());
+ // JAU frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
+ frame.setTitle("TestBug735Inv3AppletAWT");
+
+ // This allows to close the frame.
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ applet = new Bug735Inv4AWT();
+ applet.init();
+
+ if (TOOLKIT == AWT) {
+ frame.add(applet.awtCanvas);
+ } else if (TOOLKIT == NEWT) {
+ frame.add(applet.newtCanvas);
+ }
+ // frame.pack();
+ // frame.setResizable(false);
+
+ Insets insets = frame.getInsets();
+ final int windowW = applet.width + insets.left + insets.right;
+ final int windowH = applet.height + insets.top + insets.bottom;
+
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setSize(windowW, windowH);
+ frame.validate();
+ // frame.pack();
+ Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
+ frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
+ screenRect.y + (screenRect.height - applet.height) / 2);
+
+ frame.setVisible(true);
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ applet.start();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java
new file mode 100644
index 000000000..3b4187045
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java
@@ -0,0 +1,184 @@
+/**
+ * Copyright (C) 2013 JogAmp Community. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+
+/**
+ * LandscapeES2
+ */
+public class LandscapeES2 implements GLEventListener {
+ private int swapInterval = 0;
+ private boolean verbose = true;
+
+ static public int TARGET_FPS = 120;
+ private long millisOffset;
+ private int frameCount;
+ private float frameRate;
+ private ShaderCode vertShader;
+ private ShaderCode fragShader;
+ private ShaderProgram shaderProg;
+ private ShaderState shaderState;
+ private float[] resolution;
+ private GLUniformData resolutionUni;
+ private GLUniformData timeUni;
+ private GLArrayDataServer vertices;
+
+ private int fcount = 0, lastm = 0;
+ private int fint = 1;
+
+ public LandscapeES2(int swapInterval) {
+ this.swapInterval = swapInterval;
+ }
+
+ public LandscapeES2() {
+ this.swapInterval = 1;
+ }
+
+ public void setVerbose(boolean v) { verbose = v; }
+
+ public void init(GLAutoDrawable drawable) {
+ System.err.println(Thread.currentThread()+" LandscapeES2.init ...");
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if(verbose) {
+ System.err.println("LandscapeES2 init on "+Thread.currentThread());
+ System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
+ System.err.println("INIT GL IS: " + gl.getClass().getName());
+ System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
+ System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
+ System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL GLSL: "+gl.hasGLSL()+", has-compiler-func: "+gl.isFunctionAvailable("glCompileShader")+", version "+(gl.hasGLSL() ? gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION) : "none")+", "+gl.getContext().getGLSLVersionNumber());
+ System.err.println("GL FBO: basic "+ gl.hasBasicFBOSupport()+", full "+gl.hasFullFBOSupport());
+ System.err.println("GL Profile: "+gl.getGLProfile());
+ System.err.println("GL Renderer Quirks:" + gl.getContext().getRendererQuirks().toString());
+ System.err.println("GL:" + gl + ", " + gl.getContext().getGLVersion());
+ }
+
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+
+ vertShader = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader", "shader/bin", "landscape", true);
+ fragShader = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader", "shader/bin", "landscape", true);
+ vertShader.defaultShaderCustomization(gl, true, true);
+ fragShader.defaultShaderCustomization(gl, true, true);
+ shaderProg = new ShaderProgram();
+ shaderProg.add(gl, vertShader, System.err);
+ shaderProg.add(gl, fragShader, System.err);
+
+ shaderState = new ShaderState();
+ shaderState.attachShaderProgram(gl, shaderProg, true);
+
+ resolution = new float[] { drawable.getWidth(), drawable.getHeight(), 0};
+ resolutionUni = new GLUniformData("iResolution", 3, FloatBuffer.wrap(resolution));
+ shaderState.ownUniform(resolutionUni);
+ shaderState.uniform(gl, resolutionUni);
+
+ timeUni = new GLUniformData("iGlobalTime", 0.0f);
+ shaderState.ownUniform(timeUni);
+
+ vertices = GLArrayDataServer.createGLSL("inVertex", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ vertices.putf(-1.0f); vertices.putf(-1.0f);
+ vertices.putf(+1.0f); vertices.putf(-1.0f);
+ vertices.putf(-1.0f); vertices.putf(+1.0f);
+ vertices.putf(+1.0f); vertices.putf(+1.0f);
+ vertices.seal(gl, true);
+ shaderState.ownAttribute(vertices, true);
+ shaderState.useProgram(gl, false);
+
+ millisOffset = System.currentTimeMillis();
+
+ System.err.println(Thread.currentThread()+" LandscapeES2.init FIN");
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ System.err.println(Thread.currentThread()+" LandscapeES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
+
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
+
+ shaderState.useProgram(gl, true);
+
+ resolution[0] = drawable.getWidth();
+ resolution[1] = drawable.getHeight();
+ shaderState.uniform(gl, resolutionUni);
+
+ shaderState.useProgram(gl, false);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ System.err.println(Thread.currentThread()+" LandscapeES2.dispose ... ");
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ shaderState.useProgram(gl, false);
+ shaderState.destroy(gl);
+ shaderState = null;
+
+ System.err.println(Thread.currentThread()+" LandscapeES2.dispose FIN");
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ // gl.glClearColor(0.5f, 0.1f, 0.1f, 1);
+ // gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+ // gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ shaderState.useProgram(gl, true);
+
+ timeUni.setData((System.currentTimeMillis() - millisOffset) / 1000.0f);
+ shaderState.uniform(gl, timeUni);
+ vertices.enableBuffer(gl, true);
+ gl.glDrawArrays(GL2ES2.GL_TRIANGLE_STRIP, 0, 4);
+ vertices.enableBuffer(gl, false);
+
+ shaderState.useProgram(gl, false);
+
+ // Compute current framerate and printout.
+ frameCount++;
+ fcount += 1;
+ int m = (int) (System.currentTimeMillis() - millisOffset);
+ if (m - lastm > 1000 * fint) {
+ frameRate = (float)(fcount) / fint;
+ fcount = 0;
+ lastm = m;
+ }
+ if (frameCount % TARGET_FPS == 0) {
+ System.out.println("FrameCount: " + frameCount + " - " + "FrameRate: " + frameRate);
+ }
+ }
+
+ boolean confinedFixedCenter = false;
+
+ public void setConfinedFixedCenter(boolean v) {
+ confinedFixedCenter = v;
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java
new file mode 100644
index 000000000..4ca70d7d3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
+
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+public class TestLandscapeES2NEWT extends UITestCase {
+ static int width = 500, height = 290;
+ static int swapInterval = 1;
+ static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
+ static boolean exclusiveContext = false;
+ static boolean useAnimator = true;
+
+ protected void runTestGL(GLCapabilities caps) throws InterruptedException {
+ System.err.println("requested: swapInterval "+swapInterval+", "+caps);
+ final GLWindow glWindow = GLWindow.create(caps);
+ glWindow.setTitle(getSimpleTestName("."));
+ glWindow.setSize(width, height);
+
+ final LandscapeES2 demo = new LandscapeES2(swapInterval);
+ glWindow.addGLEventListener(demo);
+
+ final SnapshotGLEventListener snap = new SnapshotGLEventListener();
+ snap.setPostSNDetail(demo.getClass().getSimpleName());
+ glWindow.addGLEventListener(snap);
+
+ final Animator animator = useAnimator ? new Animator() : null;
+ if( useAnimator ) {
+ animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD);
+ animator.setExclusiveContext(exclusiveContext);
+ }
+
+ QuitAdapter quitAdapter = new QuitAdapter();
+
+ //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
+ //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+ glWindow.addKeyListener(quitAdapter);
+ glWindow.addWindowListener(quitAdapter);
+
+ glWindow.addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar()=='f') {
+ new Thread() {
+ public void run() {
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ } }.start();
+ } else if(e.getKeyChar()=='d') {
+ new Thread() {
+ public void run() {
+ glWindow.setUndecorated(!glWindow.isUndecorated());
+ } }.start();
+ }
+ }
+ });
+
+ if( useAnimator ) {
+ animator.add(glWindow);
+ animator.start();
+ }
+ glWindow.setVisible(true);
+ if( useAnimator ) {
+ animator.setUpdateFPSFrames(60, System.err);
+ }
+
+ 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()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+
+ snap.setMakeSnapshot();
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ if( useAnimator ) {
+ animator.stop();
+ }
+ glWindow.destroy();
+ }
+
+ @Test
+ public void test01GL2ES2() throws InterruptedException {
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+ runTestGL(caps);
+ }
+
+ @Test
+ public void test02GL3() throws InterruptedException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ return;
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
+
+ static long duration = 500; // ms
+
+ public static void main(String args[]) {
+ mainRun = true;
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-exclctx")) {
+ exclusiveContext = true;
+ } else if(args[i].equals("-noanim")) {
+ useAnimator = false;
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
+ }
+ }
+ System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
+ org.junit.runner.JUnitCore.main(TestLandscapeES2NEWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java
new file mode 100644
index 000000000..c1df18c19
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java
@@ -0,0 +1,258 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.demos.es2.newt;
+
+import java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
+
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.DimensionImmutable;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLProfile;
+import javax.swing.SwingUtilities;
+
+import org.junit.Test;
+
+public class TestLandscapeES2NewtCanvasAWT extends UITestCase {
+ static DimensionImmutable wsize = new Dimension(500, 290);
+
+ static long duration = 500; // ms
+ static int swapInterval = 1;
+ static boolean shallUseOffscreenFBOLayer = false;
+ static boolean forceES2 = false;
+ static boolean forceGL3 = false;
+ static boolean mainRun = false;
+ static boolean exclusiveContext = false;
+ static boolean useAnimator = true;
+
+ // public enum ResizeBy { GLWindow, Component, Frame };
+ protected void runTestGL(final GLCapabilitiesImmutable caps) throws InterruptedException, InvocationTargetException {
+ System.err.println("requested: vsync "+swapInterval+", "+caps);
+ Display dpy = NewtFactory.createDisplay(null);
+ Screen screen = NewtFactory.createScreen(dpy, 0);
+ final GLWindow glWindow = GLWindow.create(screen, caps);
+
+ final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ if ( shallUseOffscreenFBOLayer ) {
+ newtCanvasAWT.setShallUseOffscreenLayer(true);
+ }
+
+ final Frame frame = new Frame("AWT Parent Frame");
+ {
+ java.awt.Dimension d = new java.awt.Dimension(wsize.getWidth(), wsize.getHeight());
+ frame.setSize(d);
+ }
+ frame.add(newtCanvasAWT);
+ frame.setTitle("Gears NewtCanvasAWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval+", size "+wsize);
+
+ final LandscapeES2 demo = new LandscapeES2(swapInterval);
+ glWindow.addGLEventListener(demo);
+
+ final Animator animator = useAnimator ? new Animator() : null;
+ if( useAnimator ) {
+ animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD);
+ animator.setExclusiveContext(exclusiveContext);
+ }
+
+ final QuitAdapter quitAdapter = new QuitAdapter();
+ //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
+ //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+ glWindow.addKeyListener(quitAdapter);
+ glWindow.addWindowListener(quitAdapter);
+
+ glWindow.addWindowListener(new WindowAdapter() {
+ public void windowResized(WindowEvent e) {
+ System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ public void windowMoved(WindowEvent e) {
+ System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ });
+
+ glWindow.addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar()=='f') {
+ quitAdapter.enable(false);
+ new Thread() {
+ public void run() {
+ final Thread t = glWindow.setExclusiveContextThread(null);
+ System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+ glWindow.setExclusiveContextThread(t);
+ quitAdapter.clear();
+ quitAdapter.enable(true);
+ } }.start();
+ } else if(e.getKeyChar()=='r') {
+ quitAdapter.enable(false);
+ if(glWindow.getParent()==null) {
+ System.err.println("XXX glWin to home");
+ glWindow.reparentWindow(newtCanvasAWT.getNativeWindow());
+ } else {
+ final InsetsImmutable nInsets = glWindow.getInsets();
+ java.awt.Insets aInsets = frame.getInsets();
+ System.err.println("XXX glWin to TOP - insets " + nInsets + ", " + aInsets);
+ glWindow.reparentWindow(null);
+ int dx, dy;
+ if(nInsets.getTotalHeight()==0) {
+ dx = aInsets.left;
+ dy = aInsets.top;
+ } else {
+ dx = nInsets.getLeftWidth();
+ dy = nInsets.getTopHeight();
+ }
+ glWindow.setPosition(frame.getX()+frame.getWidth()+dx, frame.getY()+dy);
+ }
+ glWindow.requestFocus();
+ quitAdapter.clear();
+ quitAdapter.enable(true);
+ }
+ }
+ });
+
+ if( useAnimator ) {
+ animator.add(glWindow);
+ animator.start();
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.validate();
+ frame.setVisible(true);
+ }
+ });
+
+ if( useAnimator ) {
+ animator.setUpdateFPSFrames(60, System.err);
+ }
+
+ 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()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+
+ final long t0 = System.currentTimeMillis();
+ long t1 = t0;
+ while(!quitAdapter.shouldQuit() && t1-t0<duration) {
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ if( useAnimator ) {
+ animator.stop();
+ }
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.dispose();
+ }
+ });
+ glWindow.destroy();
+ }
+
+ @Test
+ public void test01GL2ES2() throws InterruptedException, InvocationTargetException {
+ final GLProfile glp;
+ if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getGL2ES2();
+ }
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
+
+ @Test
+ public void test02GL3() throws InterruptedException, InvocationTargetException {
+ if(mainRun) return;
+
+ if( !GLProfile.isAvailable(GLProfile.GL3) ) {
+ System.err.println("GL3 n/a");
+ return;
+ }
+ final GLProfile glp = GLProfile.get(GLProfile.GL3);
+ final GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL(caps);
+ }
+
+ public static void main(String args[]) throws IOException {
+ mainRun = true;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
+ } else if(args[i].equals("-layeredFBO")) {
+ shallUseOffscreenFBOLayer = true;
+ } else if(args[i].equals("-exclctx")) {
+ exclusiveContext = true;
+ } else if(args[i].equals("-noanim")) {
+ useAnimator = false;
+ } else if(args[i].equals("-es2")) {
+ forceES2 = true;
+ } else if(args[i].equals("-gl3")) {
+ forceGL3 = true;
+ }
+ }
+
+ System.err.println("size "+wsize);
+ System.err.println("shallUseOffscreenFBOLayer "+shallUseOffscreenFBOLayer);
+ System.err.println("forceES2 "+forceES2);
+ System.err.println("forceGL3 "+forceGL3);
+ System.err.println("swapInterval "+swapInterval);
+ System.err.println("exclusiveContext "+exclusiveContext);
+ System.err.println("useAnimator "+useAnimator);
+
+ org.junit.runner.JUnitCore.main(TestLandscapeES2NewtCanvasAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.fp
new file mode 100644
index 000000000..b19c057d3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.fp
@@ -0,0 +1,339 @@
+// Elevated shader
+// https://www.shadertoy.com/view/MdX3Rr by inigo quilez
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+uniform vec3 iResolution;
+uniform float iGlobalTime;
+
+// Created by inigo quilez - iq/2013
+// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
+
+//stereo thanks to Croqueteer
+//#define STEREO
+
+mat3 m = mat3( 0.00, 0.80, 0.60,
+ -0.80, 0.36, -0.48,
+ -0.60, -0.48, 0.64 );
+
+float hash( float n )
+{
+ return fract(sin(n)*43758.5453123);
+}
+
+
+float noise( in vec3 x )
+{
+ vec3 p = floor(x);
+ vec3 f = fract(x);
+
+ f = f*f*(3.0-2.0*f);
+
+ float n = p.x + p.y*57.0 + 113.0*p.z;
+
+ float res = mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
+ mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y),
+ mix(mix( hash(n+113.0), hash(n+114.0),f.x),
+ mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
+ return res;
+}
+
+
+
+
+vec3 noised( in vec2 x )
+{
+ vec2 p = floor(x);
+ vec2 f = fract(x);
+
+ vec2 u = f*f*(3.0-2.0*f);
+
+ float n = p.x + p.y*57.0;
+
+ float a = hash(n+ 0.0);
+ float b = hash(n+ 1.0);
+ float c = hash(n+ 57.0);
+ float d = hash(n+ 58.0);
+ return vec3(a+(b-a)*u.x+(c-a)*u.y+(a-b-c+d)*u.x*u.y,
+ 30.0*f*f*(f*(f-2.0)+1.0)*(vec2(b-a,c-a)+(a-b-c+d)*u.yx));
+
+}
+
+float noise( in vec2 x )
+{
+ vec2 p = floor(x);
+ vec2 f = fract(x);
+
+ f = f*f*(3.0-2.0*f);
+
+ float n = p.x + p.y*57.0;
+
+ float res = mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
+ mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y);
+
+ return res;
+}
+
+float fbm( vec3 p )
+{
+ float f = 0.0;
+
+ f += 0.5000*noise( p ); p = m*p*2.02;
+ f += 0.2500*noise( p ); p = m*p*2.03;
+ f += 0.1250*noise( p ); p = m*p*2.01;
+ f += 0.0625*noise( p );
+
+ return f/0.9375;
+}
+
+mat2 m2 = mat2(1.6,-1.2,1.2,1.6);
+
+float fbm( vec2 p )
+{
+ float f = 0.0;
+
+ f += 0.5000*noise( p ); p = m2*p*2.02;
+ f += 0.2500*noise( p ); p = m2*p*2.03;
+ f += 0.1250*noise( p ); p = m2*p*2.01;
+ f += 0.0625*noise( p );
+
+ return f/0.9375;
+}
+
+float terrain( in vec2 x )
+{
+ vec2 p = x*0.003;
+ float a = 0.0;
+ float b = 1.0;
+ vec2 d = vec2(0.0);
+ for(int i=0;i<5; i++)
+ {
+ vec3 n = noised(p);
+ d += n.yz;
+ a += b*n.x/(1.0+dot(d,d));
+ b *= 0.5;
+ p=mat2(1.6,-1.2,1.2,1.6)*p;
+ }
+
+ return 140.0*a;
+}
+
+float terrain2( in vec2 x )
+{
+ vec2 p = x*0.003;
+ float a = 0.0;
+ float b = 1.0;
+ vec2 d = vec2(0.0);
+ for(int i=0;i<14; i++)
+ {
+ vec3 n = noised(p);
+ d += n.yz;
+ a += b*n.x/(1.0+dot(d,d));
+ b *= 0.5;
+ p=m2*p;
+ }
+
+ return 140.0*a;
+}
+
+
+float map( in vec3 p )
+{
+ float h = terrain(p.xz);
+
+ float ss = 0.03;
+ float hh = h*ss;
+ float fh = fract(hh);
+ float ih = floor(hh);
+ fh = mix( sqrt(fh), fh, smoothstep(50.0,140.0,h) );
+ h = (ih+fh)/ss;
+
+ return p.y - h;
+}
+
+float map2( in vec3 p )
+{
+ float h = terrain2(p.xz);
+
+
+ float ss = 0.03;
+ float hh = h*ss;
+ float fh = fract(hh);
+ float ih = floor(hh);
+ fh = mix( sqrt(fh), fh, smoothstep(50.0,140.0,h) );
+ h = (ih+fh)/ss;
+
+ return p.y - h;
+}
+
+bool jinteresct(in vec3 rO, in vec3 rD, out float resT )
+{
+ float h = 0.0;
+ float t = 0.0;
+ for( int j=0; j<120; j++ )
+ {
+ //if( t>2000.0 ) break;
+
+ vec3 p = rO + t*rD;
+if( p.y>300.0 ) break;
+ h = map( p );
+
+ if( h<0.1 )
+ {
+ resT = t;
+ return true;
+ }
+ t += max(0.1,0.5*h);
+
+ }
+
+ if( h<5.0 )
+ {
+ resT = t;
+ return true;
+ }
+ return false;
+}
+
+float sinteresct(in vec3 rO, in vec3 rD )
+{
+ float res = 1.0;
+ float t = 0.0;
+ for( int j=0; j<50; j++ )
+ {
+ //if( t>1000.0 ) break;
+ vec3 p = rO + t*rD;
+
+ float h = map( p );
+
+ if( h<0.1 )
+ {
+ return 0.0;
+ }
+ res = min( res, 16.0*h/t );
+ t += h;
+
+ }
+
+ return clamp( res, 0.0, 1.0 );
+}
+
+vec3 calcNormal( in vec3 pos, float t )
+{
+ float e = 0.001;
+ e = 0.001*t;
+ vec3 eps = vec3(e,0.0,0.0);
+ vec3 nor;
+ nor.x = map2(pos+eps.xyy) - map2(pos-eps.xyy);
+ nor.y = map2(pos+eps.yxy) - map2(pos-eps.yxy);
+ nor.z = map2(pos+eps.yyx) - map2(pos-eps.yyx);
+ return normalize(nor);
+}
+
+vec3 camPath( float time )
+{
+ vec2 p = 600.0*vec2( cos(1.4+0.37*time),
+ cos(3.2+0.31*time) );
+
+ return vec3( p.x, 0.0, p.y );
+}
+
+void main(void)
+{
+ vec2 xy = -1.0 + 2.0*gl_FragCoord.xy / iResolution.xy;
+
+ vec2 s = xy*vec2(1.75,1.0);
+
+ #ifdef STEREO
+ float isCyan = mod(gl_FragCoord.x + mod(gl_FragCoord.y,2.0),2.0);
+ #endif
+
+ float time = iGlobalTime*.15;
+
+ vec3 light1 = normalize( vec3( 0.4, 0.22, 0.6 ) );
+ vec3 light2 = vec3( -0.707, 0.000, -0.707 );
+
+
+ vec3 campos = camPath( time );
+ vec3 camtar = camPath( time + 3.0 );
+ campos.y = terrain( campos.xz ) + 15.0;
+ camtar.y = campos.y*0.5;
+
+ float roll = 0.1*cos(0.1*time);
+ vec3 cw = normalize(camtar-campos);
+ vec3 cp = vec3(sin(roll), cos(roll),0.0);
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = normalize(cross(cu,cw));
+ vec3 rd = normalize( s.x*cu + s.y*cv + 1.6*cw );
+
+ #ifdef STEREO
+ campos += 2.0*cu*isCyan; // move camera to the right - the rd vector is still good
+ #endif
+
+ float sundot = clamp(dot(rd,light1),0.0,1.0);
+ vec3 col;
+ float t;
+ if( !jinteresct(campos,rd,t) )
+ {
+ col = 0.9*vec3(0.97,.99,1.0)*(1.0-0.3*rd.y);
+ col += 0.2*vec3(0.8,0.7,0.5)*pow( sundot, 4.0 );
+ }
+ else
+ {
+ vec3 pos = campos + t*rd;
+
+ vec3 nor = calcNormal( pos, t );
+
+ float dif1 = clamp( dot( light1, nor ), 0.0, 1.0 );
+ float dif2 = clamp( 0.2 + 0.8*dot( light2, nor ), 0.0, 1.0 );
+ float sh = 1.0;
+ if( dif1>0.001 )
+ sh = sinteresct(pos+light1*20.0,light1);
+
+ vec3 dif1v = vec3(dif1);
+ dif1v *= vec3( sh, sh*sh*0.5+0.5*sh, sh*sh );
+
+ float r = noise( 7.0*pos.xz );
+
+ col = (r*0.25+0.75)*0.9*mix( vec3(0.10,0.05,0.03), vec3(0.13,0.10,0.08), clamp(terrain2( vec2(pos.x,pos.y*48.0))/200.0,0.0,1.0) );
+ col = mix( col, 0.17*vec3(0.5,.23,0.04)*(0.50+0.50*r),smoothstep(0.70,0.9,nor.y) );
+ col = mix( col, 0.10*vec3(0.2,.30,0.00)*(0.25+0.75*r),smoothstep(0.95,1.0,nor.y) );
+ col *= 0.75;
+ // snow
+ #if 1
+ float h = smoothstep(55.0,80.0,pos.y + 25.0*fbm(0.01*pos.xz) );
+ float e = smoothstep(1.0-0.5*h,1.0-0.1*h,nor.y);
+ float o = 0.3 + 0.7*smoothstep(0.0,0.1,nor.x+h*h);
+ float s = h*e*o;
+ s = smoothstep( 0.1, 0.9, s );
+ col = mix( col, 0.4*vec3(0.6,0.65,0.7), s );
+ #endif
+
+
+ vec3 brdf = 2.0*vec3(0.17,0.19,0.20)*clamp(nor.y,0.0,1.0);
+ brdf += 6.0*vec3(1.00,0.95,0.80)*dif1v;
+ brdf += 2.0*vec3(0.20,0.20,0.20)*dif2;
+
+ col *= brdf;
+
+ float fo = 1.0-exp(-pow(0.0015*t,1.5));
+ vec3 fco = vec3(0.7) + 0.6*vec3(0.8,0.7,0.5)*pow( sundot, 4.0 );
+ col = mix( col, fco, fo );
+ }
+
+ col = sqrt(col);
+
+ vec2 uv = xy*0.5+0.5;
+ col *= 0.7 + 0.3*pow(16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y),0.1);
+
+ #ifdef STEREO
+ col *= vec3( isCyan, 1.0-isCyan, 1.0-isCyan );
+ #endif
+
+ mgl_FragColor = vec4(col,1.0);
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.vp
new file mode 100644
index 000000000..fc698f2a8
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.vp
@@ -0,0 +1,11 @@
+
+#if __VERSION__ >= 130
+ #define attribute in
+ #define varying out
+#endif
+
+attribute vec2 inVertex;
+
+void main() {
+ gl_Position = vec4(inVertex, 0, 1);
+} \ No newline at end of file