From 4fe6cf06f74085cc90d1f5b003fd717234d43ced Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 16 Jun 2013 04:14:56 +0200 Subject: Bug 735: Adding Andres test cases for analysis. OSX exposes diff. odd behaviors - See BugXYZ test cases. --- .../opengl/test/bugs/Bug735Inv0AppletAWT.java | 427 ++++++++++++++++++++ .../opengl/test/bugs/Bug735Inv1AppletAWT.java | 429 +++++++++++++++++++++ .../opengl/test/bugs/Bug735Inv2AppletAWT.java | 253 ++++++++++++ .../opengl/test/bugs/Bug735Inv3AppletAWT.java | 203 ++++++++++ .../com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java | 188 +++++++++ .../test/junit/jogl/demos/es2/LandscapeES2.java | 184 +++++++++ .../jogl/demos/es2/newt/TestLandscapeES2NEWT.java | 175 +++++++++ .../es2/newt/TestLandscapeES2NewtCanvasAWT.java | 258 +++++++++++++ .../test/junit/jogl/demos/es2/shader/landscape.fp | 339 ++++++++++++++++ .../test/junit/jogl/demos/es2/shader/landscape.vp | 11 + 10 files changed, 2467 insertions(+) create mode 100644 src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java create mode 100644 src/test/com/jogamp/opengl/test/bugs/Bug735Inv1AppletAWT.java create mode 100644 src/test/com/jogamp/opengl/test/bugs/Bug735Inv2AppletAWT.java create mode 100644 src/test/com/jogamp/opengl/test/bugs/Bug735Inv3AppletAWT.java create mode 100644 src/test/com/jogamp/opengl/test/bugs/Bug735Inv4AWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/LandscapeES2.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.fp create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/landscape.vp (limited to 'src') 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. + *
+ * OSX Results: + *
+ *   - Only RED Clear Color
+ * 
+ */ +@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: + *
+ *   - MANUAL_FRAME_HANDLING false
+ *   - MANUAL_FRAME_HANDLING: impl using pass through GLContext instead of static
+ * 
+ * OSX Results: + *
+ *   - Only RED Clear Color
+ * 
+ */ +@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: + *
+ *   - 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 
+ * 
+ * OSX Results: + *
+ *   - Visible content
+ *   - Stuttering, non-fluent and slow animation
+ * 
+ */ +@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: + *
+ *   - 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)
+ * 
+ * OSX Results: + *
+ *   - Visible content
+ *   - Stuttering, non-fluent and slow animation
+ * 
+ */ +@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: + *
+ *   - 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!
+ * 
+ * OSX Results: + *
+ *   - Visible content
+ *   - Fluent animation
+ * 
+ */ +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()= 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 -- cgit v1.2.3