diff options
author | Sven Gothel <[email protected]> | 2013-09-05 08:32:31 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-09-05 08:32:31 +0200 |
commit | 604434f8a1ea43f306e21fe81ac7471f27e3c9cf (patch) | |
tree | 97818c8a9d50dff97804be45531ad69c18763596 /src/test/com/jogamp/opengl | |
parent | 58682d84c09462b1f2798b847ade6624b89d962f (diff) |
TileRenderer*: Enhance API Doc; Cleanup OO; Remove PMVMatrixCallback, use GLEventListener reshape(..) or manual reshape after beginTile(..) method.
GLEventListener reshape(..) method should be aware of TileRenderer usage
and get the missing tile position and image size from it (-> see Gears example).
TestRandomTiledRendering3GL2AWT demos AWT GLCanvas onscreen
being used for random tile rendering to produce a PNG file.
TestTiledRendering1GL2 is now GLAutoDrawable/GLEventListener agnostic,
hence demos plain GLDrawable tile rendering usage.
Diffstat (limited to 'src/test/com/jogamp/opengl')
5 files changed, 568 insertions, 207 deletions
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java index d3ab05e82..0c84fac39 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java @@ -17,6 +17,7 @@ import com.jogamp.newt.event.MouseListener; import com.jogamp.newt.event.awt.AWTKeyAdapter; import com.jogamp.newt.event.awt.AWTMouseAdapter; import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.util.TileRendererBase; /** * Gears.java <BR> @@ -33,7 +34,8 @@ public class Gears implements GLEventListener { private int swapInterval; private MouseListener gearsMouse = new GearsMouseAdapter(); private KeyListener gearsKeys = new GearsKeyAdapter(); - + private TileRendererBase tileRendererInUse = null; + // private boolean mouseRButtonDown = false; private int prevMouseX, prevMouseY; @@ -45,6 +47,10 @@ public class Gears implements GLEventListener { this.swapInterval = 1; } + public void setTileRenderer(TileRendererBase tileRenderer) { + tileRendererInUse = tileRenderer; + } + public void setDoRotation(boolean rotate) { this.doRotate = rotate; } public void setGears(int g1, int g2, int g3) { @@ -75,7 +81,22 @@ public class Gears implements GLEventListener { System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities()); System.err.println("INIT GL IS: " + gl.getClass().getName()); System.err.println(JoglVersion.getGLStrings(gl, null, false).toString()); + + init(gl); + + final Object upstreamWidget = drawable.getUpstreamWidget(); + if (upstreamWidget instanceof Window) { + final Window window = (Window) upstreamWidget; + window.addMouseListener(gearsMouse); + window.addKeyListener(gearsKeys); + } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) { + final java.awt.Component comp = (java.awt.Component) upstreamWidget; + new AWTMouseAdapter(gearsMouse).addTo(comp); + new AWTKeyAdapter(gearsKeys).addTo(comp); + } + } + public void init(GL2 gl) { float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; float red[] = { 0.8f, 0.1f, 0.0f, 0.7f }; float green[] = { 0.0f, 0.8f, 0.2f, 0.7f }; @@ -122,36 +143,64 @@ public class Gears implements GLEventListener { } gl.glEnable(GL2.GL_NORMALIZE); - - final Object upstreamWidget = drawable.getUpstreamWidget(); - if (upstreamWidget instanceof Window) { - final Window window = (Window) upstreamWidget; - window.addMouseListener(gearsMouse); - window.addKeyListener(gearsKeys); - } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) { - final java.awt.Component comp = (java.awt.Component) upstreamWidget; - new AWTMouseAdapter(gearsMouse).addTo(comp); - new AWTKeyAdapter(gearsKeys).addTo(comp); - } } - + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { - System.err.println("Gears: Reshape "+x+"/"+y+" "+width+"x"+height); - GL2 gl = drawable.getGL().getGL2(); - - gl.setSwapInterval(swapInterval); + GL2 gl = drawable.getGL().getGL2(); + this.reshape(gl, x, y, width, height); + } + + public void reshape(GL2 gl, int x, int y, int width, int height) { + System.err.println("Gears: Reshape "+x+"/"+y+" "+width+"x"+height+", tileRendererInUse "+tileRendererInUse); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); - if(height>width) { - float h = (float)height / (float)width; - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); + + final int tileWidth = width; + final int tileHeight = height; + final int tileX, tileY, imageWidth, imageHeight; + if( null == tileRendererInUse ) { + gl.setSwapInterval(swapInterval); + tileX = 0; + tileY = 0; + imageWidth = width; + imageHeight = height; + } else { + gl.setSwapInterval(0); + tileX = tileRendererInUse.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS); + tileY = tileRendererInUse.getParam(TileRendererBase.TR_CURRENT_TILE_Y_POS); + imageWidth = tileRendererInUse.getParam(TileRendererBase.TR_IMAGE_WIDTH); + imageHeight = tileRendererInUse.getParam(TileRendererBase.TR_IMAGE_HEIGHT); + } + /* compute projection parameters */ + float left, right, bottom, top; + if( imageHeight > imageWidth ) { + float a = (float)imageHeight / (float)imageWidth; + left = -1.0f; + right = 1.0f; + bottom = -a; + top = a; } else { - float h = (float)width / (float)height; - gl.glFrustum(-h, h, -1.0f, 1.0f, 5.0f, 60.0f); + float a = (float)imageWidth / (float)imageHeight; + left = -a; + right = a; + bottom = -1.0f; + top = 1.0f; } - gl.glMatrixMode(GL2.GL_MODELVIEW); + final float w = right - left; + final float h = top - bottom; + final float l = left + w * tileX / imageWidth; + final float r = l + w * tileWidth / imageWidth; + final float b = bottom + h * tileY / imageHeight; + final float t = b + h * tileHeight / imageHeight; + + final float _w = r - l; + final float _h = t - b; + System.err.println(">> angle "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); + gl.glFrustum(l, r, b, t, 5.0f, 60.0f); + + gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -40.0f); } @@ -170,11 +219,6 @@ public class Gears implements GLEventListener { } public void display(GLAutoDrawable drawable) { - if( doRotate ) { - // Turn the gears' teeth - angle += 2.0f; - } - // Get the GL corresponding to the drawable we are animating GL2 gl = drawable.getGL().getGL2(); @@ -190,7 +234,18 @@ public class Gears implements GLEventListener { } else { gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); } - + displayImpl(gl); + } + public void display(GL2 gl) { + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); + displayImpl(gl); + } + private void displayImpl(GL2 gl) { + if( doRotate ) { + // Turn the gears' teeth + angle += 2.0f; + } // Rotate the entire assembly of gears based on how the user // dragged the mouse around gl.glPushMatrix(); @@ -221,7 +276,7 @@ public class Gears implements GLEventListener { // Remember that every push needs a pop; this one is paired with // rotating the entire gear assembly - gl.glPopMatrix(); + gl.glPopMatrix(); } public static void gear(GL2 gl, diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java index d1fabfa6b..1efc95c9e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java @@ -1,9 +1,37 @@ +/** + * 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.tile; import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.GLPixelBuffer; import com.jogamp.opengl.util.RandomTileRenderer; +import com.jogamp.opengl.util.TileRendererBase; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.texture.TextureData; import com.jogamp.opengl.util.texture.TextureIO; @@ -11,19 +39,35 @@ import com.jogamp.opengl.util.texture.TextureIO; import java.io.File; import java.io.IOException; import javax.media.opengl.GL; -import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLRunnable; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; -/** Demonstrates the RandomTileRenderer class by rendering a large version - of the Gears demo to the specified file. */ +/** + * Demos offscreen {@link GLAutoDrawable} being used for + * {@link RandomTileRenderer} rendering to produce a PNG file. + * <p> + * {@link RandomTileRenderer} is being kicked off from the main thread. + * </p> + * <p> + * {@link RandomTileRenderer} buffer allocation is performed + * within the pre {@link GLEventListener} + * set via {@link TileRendererBase#setGLEventListener(GLEventListener, GLEventListener)} + * on the main thread. + * </p> + * <p> + * At tile rendering finish, the viewport and + * and the original {@link GLEventListener}'s PMV matrix as well. + * The latter is done by calling it's {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape} method. + * </p> +*/ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestRandomTiledRendering2GL2 extends UITestCase { static long duration = 500; // ms @@ -37,7 +81,6 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { GLCapabilities caps = new GLCapabilities(null); caps.setDoubleBuffered(false); - // Use a pbuffer for rendering final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null); @@ -54,43 +97,8 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { // Initialize the tile rendering library final RandomTileRenderer renderer = new RandomTileRenderer(); - final RandomTileRenderer.PMVMatrixCallback pmvMatrixCallback = new RandomTileRenderer.PMVMatrixCallback() { - public void reshapePMVMatrix(GL _gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { - final GL2 gl = _gl.getGL2(); - gl.glMatrixMode( GL2.GL_PROJECTION ); - gl.glLoadIdentity(); - - /* compute projection parameters */ - float left, right, bottom, top; - if( imageHeight > imageWidth ) { - float a = (float)imageHeight / (float)imageWidth; - left = -1.0f; - right = 1.0f; - bottom = -a; - top = a; - } else { - float a = (float)imageWidth / (float)imageHeight; - left = -a; - right = a; - bottom = -1.0f; - top = 1.0f; - } - final float w = right - left; - final float h = top - bottom; - final float l = left + w * tileX / imageWidth; - final float r = l + w * tileWidth / imageWidth; - final float b = bottom + h * tileY / imageHeight; - final float t = b + h * tileHeight / imageHeight; - - final float _w = r - l; - final float _h = t - b; - System.err.println(">> [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); - gl.glFrustum(l, r, b, t, 5.0f, 60.0f); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - } - }; - renderer.attachToAutoDrawable(glad, pmvMatrixCallback); + gears.setTileRenderer(renderer); + renderer.attachToAutoDrawable(glad); renderer.setImageSize(imageWidth, imageHeight); final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; @@ -130,6 +138,18 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { } renderer.detachFromAutoDrawable(); + gears.setTileRenderer(null); + + // Restore viewport and Gear's PMV matrix + // .. even though we close the demo, this is for documentation! + glad.invoke(true, new GLRunnable() { + @Override + public boolean run(GLAutoDrawable drawable) { + drawable.getGL().glViewport(0, 0, drawable.getWidth(), drawable.getHeight()); + gears.reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight()); + return false; + } + }); glad.destroy(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering3GL2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering3GL2AWT.java new file mode 100644 index 000000000..26e53c17b --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering3GL2AWT.java @@ -0,0 +1,261 @@ +/** + * 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.tile; + +import com.jogamp.newt.event.TraceKeyAdapter; +import com.jogamp.newt.event.TraceWindowAdapter; +import com.jogamp.newt.event.awt.AWTKeyAdapter; +import com.jogamp.newt.event.awt.AWTWindowAdapter; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; +import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.GLPixelBuffer; +import com.jogamp.opengl.util.RandomTileRenderer; +import com.jogamp.opengl.util.TileRendererBase; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.texture.TextureData; +import com.jogamp.opengl.util.texture.TextureIO; + +import java.awt.Dimension; +import java.awt.Frame; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.awt.GLCanvas; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** + * Demos an onscreen AWT {@link GLCanvas} being used for + * {@link RandomTileRenderer} rendering to produce a PNG file. + * <p> + * {@link RandomTileRenderer} is being kicked off from the main thread. + * </p> + * <p> + * {@link RandomTileRenderer} setup and finishing is performed + * within the pre- and post {@link GLEventListener} + * set via {@link TileRendererBase#setGLEventListener(GLEventListener, GLEventListener)} + * on the animation thread. + * </p> + * <p> + * At tile rendering finish, the viewport and + * and the original {@link GLEventListener}'s PMV matrix as well. + * The latter is done by calling it's {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape} method. + * </p> + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestRandomTiledRendering3GL2AWT extends UITestCase { + static long duration = 3500; // ms + static int width = 640; + static int height = 480; + + @Test + public void test01() throws IOException, InterruptedException, InvocationTargetException { + doTest(); + } + + void doTest() throws IOException, InterruptedException, InvocationTargetException { + final GLCapabilities caps = new GLCapabilities(null); + caps.setDoubleBuffered(false); + + final Frame frame = new Frame("Gears AWT Test"); + Assert.assertNotNull(frame); + + final GLCanvas glad = new GLCanvas(caps); + Assert.assertNotNull(glad); + Dimension glc_sz = new Dimension(width, height); + glad.setMinimumSize(glc_sz); + glad.setPreferredSize(glc_sz); + glad.setSize(glc_sz); + frame.add(glad); + + final Gears gears = new Gears(); + glad.addGLEventListener( gears ); + + final Animator animator = new Animator(glad); + final QuitAdapter quitAdapter = new QuitAdapter(); + + new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter)).addTo(glad); + new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter)).addTo(frame); + + // Fix the image size for now + final int imageWidth = glad.getWidth() * 3; + final int imageHeight = glad.getHeight() * 2; + + // Initialize the tile rendering library + final RandomTileRenderer renderer = new RandomTileRenderer(); + renderer.setImageSize(imageWidth, imageHeight); + final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; + final boolean[] flipVertically = { false }; + final boolean[] rendererActive = { true }; + + final GLEventListener preTileGLEL = new GLEventListener() { + final int w = 50, h = 50; + int dx = 0, dy = 0; + + @Override + public void init(GLAutoDrawable drawable) { + gears.setDoRotation(false); + final GL gl = drawable.getGL(); + GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3); + GLPixelBuffer pixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0); + renderer.setImageBuffer(pixelBuffer); + if( drawable.isGLOriented() ) { + flipVertically[0] = false; + } else { + flipVertically[0] = true; + } + } + @Override + public void dispose(GLAutoDrawable drawable) {} + @Override + public void display(GLAutoDrawable drawable) { + if( dx+w <= imageWidth && dy+h <= imageHeight ) { + System.err.println("XXX setTileRect["+dx+"/"+dy+" "+w+"x"+h+"]"); + renderer.setTileRect(dx, dy, w, h); + dx+=w+w/2; + if( dx + w > imageWidth ) { + dx = 0; + dy+=h+h/2; + } + } else if( rendererActive[0] ) { + System.err.println("XXX active -> false"); + rendererActive[0] = false; + } + } + @Override + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + }; + final GLEventListener postTileGLEL = new GLEventListener() { + @Override + public void init(GLAutoDrawable drawable) {} + @Override + public void dispose(GLAutoDrawable drawable) {} + @Override + public void display(GLAutoDrawable drawable) { + if( !rendererActive[0] ) { + final GLPixelBuffer imageBuffer = renderer.getImageBuffer(); + imageBuffer.clear(); // full size available + System.err.println("XXX !active -> save"); + System.err.println("XXX2: "+imageBuffer); + final TextureData textureData = new TextureData( + caps.getGLProfile(), + 0 /* internalFormat */, + imageWidth, imageHeight, + 0, + imageBuffer.pixelAttributes, + false, false, + flipVertically[0], + imageBuffer.buffer, + null /* Flusher */); + System.err.println("XXX3: "+textureData.getPixelFormat()+", "+textureData.getPixelAttributes()); + try { + final String filename = getSnapshotFilename(0, "-tile", glad.getChosenGLCapabilities(), imageWidth, imageHeight, false, TextureIO.PNG, null); + final File file = new File(filename); + TextureIO.write(textureData, file); + } catch (IOException e) { + e.printStackTrace(); + } + gears.setTileRenderer(null); + renderer.detachFromAutoDrawable(); + System.err.println("XXX detach: glel "+glad.getGLEventListener(0)); + System.err.println("XXX detach: "+animator); + drawable.getGL().glViewport(0, 0, drawable.getWidth(), drawable.getHeight()); + glad.getGLEventListener(0).reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight()); + gears.setDoRotation(true); + } + } + @Override + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + }; + renderer.setGLEventListener(preTileGLEL, postTileGLEL); + + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.pack(); + frame.setVisible(true); + }}); + animator.setUpdateFPSFrames(60, System.err); + animator.start(); + + boolean signalTileRenderer = true; + + while(!quitAdapter.shouldQuit() && animator.isAnimating() && + ( rendererActive[0] || animator.getTotalFPSDuration()<duration ) ) + { + if( signalTileRenderer && animator.getTotalFPSDuration() > 90 ) { + signalTileRenderer = false; + // tile rendering ! + System.err.println("XXX START TILE RENDERING"); + gears.setTileRenderer(renderer); + renderer.attachToAutoDrawable(glad); + System.err.println("XXX attach: glel "+glad.getGLEventListener(0)); + System.err.println("XXX attach: "+animator); + } + Thread.sleep(100); + } + + Assert.assertNotNull(frame); + Assert.assertNotNull(glad); + Assert.assertNotNull(animator); + + animator.stop(); + Assert.assertEquals(false, animator.isAnimating()); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.setVisible(false); + }}); + Assert.assertEquals(false, frame.isVisible()); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.remove(glad); + frame.dispose(); + }}); + } + + public static void main(String args[]) { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + org.junit.runner.JUnitCore.main(TestRandomTiledRendering3GL2AWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java index 5b628091b..24466e32e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java @@ -1,3 +1,30 @@ +/** + * 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.tile; import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; @@ -5,26 +32,37 @@ import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.GLPixelBuffer; import com.jogamp.opengl.util.TileRenderer; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.TileRendererBase; import com.jogamp.opengl.util.texture.TextureData; import com.jogamp.opengl.util.texture.TextureIO; import java.io.File; import java.io.IOException; -import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; -import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; -/** Demonstrates the TileRenderer class by rendering a large version - of the Gears demo to the specified file. */ +/** + * Demos offscreen {@link GLDrawable} being used for + * {@link TileRenderer} rendering to produce a PNG file. + * <p> + * All {@link TileRenderer} operations are + * being performed from the main thread sequentially + * without {@link GLAutoDrawable} or {@link GLEventListener}. + * </p> +*/ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestTiledRendering1GL2 extends UITestCase { static long duration = 500; // ms @@ -34,110 +72,78 @@ public class TestTiledRendering1GL2 extends UITestCase { doTest(); } - void doTest() throws IOException { - GLCapabilities caps = new GLCapabilities(null); - caps.setDoubleBuffered(false); + static class DrawableContext { + DrawableContext(GLDrawable d, GLContext glc) { + this.d = d; + this.glc = glc; + } + GLDrawable d; + GLContext glc; + } + + private static DrawableContext createDrawableAndCurrentCtx(GLCapabilities glCaps, int width, int height) { + GLDrawableFactory factory = GLDrawableFactory.getFactory(glCaps.getGLProfile()); + GLDrawable d = factory.createOffscreenDrawable(null, glCaps, null, width, height); + d.setRealized(true); + GLContext glc = null; + glc = d.createContext(null); + Assert.assertTrue("Context could not be made current", GLContext.CONTEXT_NOT_CURRENT < glc.makeCurrent()); + return new DrawableContext(d, glc); + } + + private static void destroyDrawableContext(DrawableContext dc) { + if(null != dc.glc) { + dc.glc.destroy(); + dc.glc = null; + } + if(null != dc.d) { + dc.d.setRealized(false); + dc.d = null; + } + } - // Use a pbuffer for rendering - final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); - final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null); - + void doTest() throws GLException, IOException { + GLProfile glp = GLProfile.getMaxFixedFunc(true); + GLCapabilities caps = new GLCapabilities(glp); + caps.setOnscreen(false); + + DrawableContext dc = createDrawableAndCurrentCtx(caps, 256, 256); + final GL2 gl = dc.glc.getGL().getGL2(); + // Fix the image size for now - final int imageWidth = glad.getWidth() * 6; - final int imageHeight = glad.getHeight() * 4; + final int imageWidth = dc.d.getWidth() * 6; + final int imageHeight = dc.d.getHeight() * 4; - final String filename = this.getSnapshotFilename(0, "-tile", glad.getChosenGLCapabilities(), imageWidth, imageHeight, false, TextureIO.PNG, null); + final String filename = this.getSnapshotFilename(0, "-tile", dc.d.getChosenGLCapabilities(), imageWidth, imageHeight, false, TextureIO.PNG, null); final File file = new File(filename); // Initialize the tile rendering library - final TileRenderer renderer = new com.jogamp.opengl.util.TileRenderer(); - final TileRenderer.PMVMatrixCallback pmvMatrixCallback = new TileRenderer.PMVMatrixCallback() { - public void reshapePMVMatrix(GL _gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { - final GL2 gl = _gl.getGL2(); - gl.glMatrixMode( GL2.GL_PROJECTION ); - gl.glLoadIdentity(); - - /* compute projection parameters */ - float left, right, bottom, top; - if( imageHeight > imageWidth ) { - float a = (float)imageHeight / (float)imageWidth; - left = -1.0f; - right = 1.0f; - bottom = -a; - top = a; - } else { - float a = (float)imageWidth / (float)imageHeight; - left = -a; - right = a; - bottom = -1.0f; - top = 1.0f; - } - final float w = right - left; - final float h = top - bottom; - final float l = left + w * tileX / imageWidth; - final float r = l + w * tileWidth / imageWidth; - final float b = bottom + h * tileY / imageHeight; - final float t = b + h * tileHeight / imageHeight; - - final float _w = r - l; - final float _h = t - b; - System.err.println(">> [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); - gl.glFrustum(l, r, b, t, 5.0f, 60.0f); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - } - }; - - renderer.setTileSize(glad.getWidth(), glad.getHeight(), 0); - renderer.setPMVMatrixCallback(pmvMatrixCallback); + final TileRenderer renderer = new com.jogamp.opengl.util.TileRenderer(); + renderer.setTileSize(dc.d.getWidth(), dc.d.getHeight(), 0); renderer.setImageSize(imageWidth, imageHeight); final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; final boolean[] flipVertically = { false }; - glad.addGLEventListener( new GLEventListener() { - @Override - public void init(GLAutoDrawable drawable) { - final GL gl = drawable.getGL(); - GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3); - GLPixelBuffer pixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0); - renderer.setImageBuffer(pixelBuffer); - if( drawable.isGLOriented() ) { - flipVertically[0] = false; - } else { - flipVertically[0] = true; - } - } - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - renderer.beginTile(drawable.getGL().getGL2()); - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }); + GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3); + GLPixelBuffer pixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0); + renderer.setImageBuffer(pixelBuffer); + flipVertically[0] = false; + final Gears gears = new Gears(); gears.setDoRotation(false); - glad.addGLEventListener( gears ); - glad.addGLEventListener( new GLEventListener() { - @Override - public void init(GLAutoDrawable drawable) {} - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - renderer.endTile(drawable.getGL().getGL2()); - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }); - - do { - glad.display(); + gears.init(gl); + + gears.setTileRenderer(renderer); + do { + renderer.beginTile(dc.glc.getGL().getGL2ES3()); + gears.reshape(gl, 0, 0, renderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH), renderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT)); + gears.display(gl); + renderer.endTile(dc.glc.getGL().getGL2ES3()); } while ( !renderer.eot() ); - - glad.destroy(); + gears.setTileRenderer(null); + + destroyDrawableContext(dc); final GLPixelBuffer imageBuffer = renderer.getImageBuffer(); final TextureData textureData = new TextureData( diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java index d750ca853..6fd13538b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java @@ -1,9 +1,37 @@ +/** + * 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.tile; import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.GLPixelBuffer; import com.jogamp.opengl.util.TileRenderer; +import com.jogamp.opengl.util.TileRendererBase; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.texture.TextureData; import com.jogamp.opengl.util.texture.TextureIO; @@ -11,19 +39,35 @@ import com.jogamp.opengl.util.texture.TextureIO; import java.io.File; import java.io.IOException; import javax.media.opengl.GL; -import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLRunnable; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; -/** Demonstrates the TileRenderer class by rendering a large version - of the Gears demo to the specified file. */ +/** + * Demos offscreen {@link GLAutoDrawable} being used for + * {@link TileRenderer} rendering to produce a PNG file. + * <p> + * {@link TileRenderer} is being kicked off from the main thread. + * </p> + * <p> + * {@link TileRenderer} buffer allocation is performed + * within the pre {@link GLEventListener} + * set via {@link TileRendererBase#setGLEventListener(GLEventListener, GLEventListener)} + * on the main thread. + * </p> + * <p> + * At tile rendering finish, the viewport and + * and the original {@link GLEventListener}'s PMV matrix as well. + * The latter is done by calling it's {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape} method. + * </p> +*/ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestTiledRendering2GL2 extends UITestCase { static long duration = 500; // ms @@ -37,7 +81,6 @@ public class TestTiledRendering2GL2 extends UITestCase { GLCapabilities caps = new GLCapabilities(null); caps.setDoubleBuffered(false); - // Use a pbuffer for rendering final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null); @@ -54,44 +97,8 @@ public class TestTiledRendering2GL2 extends UITestCase { // Initialize the tile rendering library final TileRenderer renderer = new TileRenderer(); - final TileRenderer.PMVMatrixCallback pmvMatrixCallback = new TileRenderer.PMVMatrixCallback() { - public void reshapePMVMatrix(GL _gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { - final GL2 gl = _gl.getGL2(); - gl.glMatrixMode( GL2.GL_PROJECTION ); - gl.glLoadIdentity(); - - /* compute projection parameters */ - float left, right, bottom, top; - if( imageHeight > imageWidth ) { - float a = (float)imageHeight / (float)imageWidth; - left = -1.0f; - right = 1.0f; - bottom = -a; - top = a; - } else { - float a = (float)imageWidth / (float)imageHeight; - left = -a; - right = a; - bottom = -1.0f; - top = 1.0f; - } - final float w = right - left; - final float h = top - bottom; - final float l = left + w * tileX / imageWidth; - final float r = l + w * tileWidth / imageWidth; - final float b = bottom + h * tileY / imageHeight; - final float t = b + h * tileHeight / imageHeight; - - final float _w = r - l; - final float _h = t - b; - System.err.println(">> [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); - gl.glFrustum(l, r, b, t, 5.0f, 60.0f); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - } - }; - - renderer.attachToAutoDrawable(glad, pmvMatrixCallback); + gears.setTileRenderer(renderer); + renderer.attachToAutoDrawable(glad); renderer.setImageSize(imageWidth, imageHeight); final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; @@ -124,6 +131,18 @@ public class TestTiledRendering2GL2 extends UITestCase { } while ( !renderer.eot() ); renderer.detachFromAutoDrawable(); + gears.setTileRenderer(null); + + // Restore viewport and Gear's PMV matrix + // .. even though we close the demo, this is for documentation! + glad.invoke(true, new GLRunnable() { + @Override + public boolean run(GLAutoDrawable drawable) { + drawable.getGL().glViewport(0, 0, drawable.getWidth(), drawable.getHeight()); + gears.reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight()); + return false; + } + }); glad.destroy(); |