JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestRandomTiledRendering3GL2AWT.java
Go to the documentation of this file.
1/**
2 * Copyright 2013 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.test.junit.jogl.tile;
29
30import com.jogamp.newt.event.TraceKeyAdapter;
31import com.jogamp.newt.event.TraceWindowAdapter;
32import com.jogamp.newt.event.awt.AWTKeyAdapter;
33import com.jogamp.newt.event.awt.AWTWindowAdapter;
34import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
35import com.jogamp.opengl.test.junit.util.QuitAdapter;
36import com.jogamp.opengl.test.junit.util.UITestCase;
37import com.jogamp.opengl.util.Animator;
38import com.jogamp.opengl.util.GLPixelBuffer;
39import com.jogamp.opengl.util.RandomTileRenderer;
40import com.jogamp.opengl.util.TileRendererBase;
41import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
42import com.jogamp.opengl.util.texture.TextureData;
43import com.jogamp.opengl.util.texture.TextureIO;
44
45import java.awt.Dimension;
46import java.awt.Frame;
47import java.io.File;
48import java.io.IOException;
49import java.lang.reflect.InvocationTargetException;
50
51import com.jogamp.nativewindow.util.PixelFormat;
52import com.jogamp.opengl.GL;
53import com.jogamp.opengl.GLAutoDrawable;
54import com.jogamp.opengl.GLCapabilities;
55import com.jogamp.opengl.GLEventListener;
56import com.jogamp.opengl.awt.GLCanvas;
57
58import org.junit.Assert;
59import org.junit.FixMethodOrder;
60import org.junit.Test;
61import org.junit.runners.MethodSorters;
62
63/**
64 * Demos an onscreen AWT {@link GLCanvas} being used for
65 * {@link RandomTileRenderer} rendering to produce a PNG file.
66 * <p>
67 * {@link RandomTileRenderer} is being kicked off from the main thread.
68 * </p>
69 * <p>
70 * {@link RandomTileRenderer} setup and finishing is performed
71 * within the pre- and post {@link GLEventListener}
72 * set via {@link TileRendererBase#setGLEventListener(GLEventListener, GLEventListener)}
73 * on the animation thread.
74 * </p>
75 * <p>
76 * At tile rendering finish, the viewport and
77 * and the original {@link GLEventListener}'s PMV matrix as well.
78 * The latter is done by calling it's {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape} method.
79 * </p>
80 */
81@FixMethodOrder(MethodSorters.NAME_ASCENDING)
83 static long duration = 3500; // ms
84 static int width = 512;
85 static int height = 512;
86
87 @Test
88 public void test01_aa0() throws IOException, InterruptedException, InvocationTargetException {
89 doTest(0);
90 }
91 @Test
92 public void test02_aa8() throws IOException, InterruptedException, InvocationTargetException {
93 doTest(8);
94 }
95
96 void doTest(final int msaaCount) throws IOException, InterruptedException, InvocationTargetException {
97 final GLCapabilities caps = new GLCapabilities(null);
98 if( msaaCount > 0 ) {
99 caps.setSampleBuffers(true);
100 caps.setNumSamples(msaaCount);
101 }
102
103 final Frame frame = new Frame("Gears AWT Test");
104 Assert.assertNotNull(frame);
105
106 final GLCanvas glad = new GLCanvas(caps);
107 Assert.assertNotNull(glad);
108 final Dimension glc_sz = new Dimension(width, height);
109 glad.setMinimumSize(glc_sz);
110 glad.setPreferredSize(glc_sz);
111 glad.setSize(glc_sz);
112 frame.add(glad);
113
114 final Gears gears = new Gears();
115 glad.addGLEventListener( gears );
116
117 final QuitAdapter quitAdapter = new QuitAdapter();
118 new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter), glad).addTo(glad);
119 new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glad).addTo(frame);
120
121 // Fix the image size for now
122 final int maxTileSize = 64;
123 final int imageWidth = 256 * 6;
124 final int imageHeight = 256 * 4;
125
126 // Initialize the tile rendering library
127 final RandomTileRenderer renderer = new RandomTileRenderer();
128 renderer.setImageSize(imageWidth, imageHeight);
129 final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride;
130 final boolean[] flipVertically = { false };
131 final boolean[] rendererActive = { true };
132
133 final GLEventListener preTileGLEL = new GLEventListener() {
134 final int w = maxTileSize, h = maxTileSize;
135 int dx = 0, dy = 0;
136
137 @Override
138 public void init(final GLAutoDrawable drawable) {
139 final GL gl = drawable.getGL();
140 final PixelFormat.Composition hostPixelComp = pixelBufferProvider.getHostPixelComp(gl.getGLProfile(), 3);
141 final GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3, true);
142 final GLPixelBuffer pixelBuffer = pixelBufferProvider.allocate(gl, hostPixelComp, pixelAttribs, true, imageWidth, imageHeight, 1, 0);
143 renderer.setImageBuffer(pixelBuffer);
144 if( drawable.isGLOriented() ) {
145 flipVertically[0] = false;
146 } else {
147 flipVertically[0] = true;
148 }
149 System.err.println("XXX pre-init: "+renderer);
150 }
151 @Override
152 public void dispose(final GLAutoDrawable drawable) {}
153 @Override
154 public void display(final GLAutoDrawable drawable) {
155 if( dx+w <= imageWidth && dy+h <= imageHeight ) {
156 renderer.setTileRect(dx, dy, w, h);
157 dx+=w+w/2;
158 if( dx + w > imageWidth ) {
159 dx = 0;
160 dy+=h+h/2;
161 }
162 } else if( rendererActive[0] ) {
163 rendererActive[0] = false;
164 }
165 System.err.println("XXX pre-display: "+renderer);
166 }
167 @Override
168 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {}
169 };
170 final GLEventListener postTileGLEL = new GLEventListener() {
171 @Override
172 public void init(final GLAutoDrawable drawable) {}
173 @Override
174 public void dispose(final GLAutoDrawable drawable) {}
175 @Override
176 public void display(final GLAutoDrawable drawable) {
177 if( !rendererActive[0] ) {
178 final GLPixelBuffer imageBuffer = renderer.getImageBuffer();
179 imageBuffer.clear(); // full size available
180 System.err.println("XXX !active -> save");
181 System.err.println("XXX post-display: "+renderer);
182 final TextureData textureData = new TextureData(
183 caps.getGLProfile(),
184 0 /* internalFormat */,
185 imageWidth, imageHeight,
186 0,
187 imageBuffer.pixelAttributes,
188 false, false,
189 flipVertically[0],
190 imageBuffer.buffer,
191 null /* Flusher */);
192 try {
193 final String filename = getSnapshotFilename(0, "-tile", glad.getChosenGLCapabilities(), imageWidth, imageHeight, false, TextureIO.PNG, null);
194 final File file = new File(filename);
195 TextureIO.write(textureData, file);
196 } catch (final IOException e) {
197 e.printStackTrace();
198 }
199 renderer.detachAutoDrawable();
200 System.err.println("XXX post-display detached: "+renderer);
201 drawable.getGL().glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
202 glad.getGLEventListener(0).reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
203 }
204 }
205 @Override
206 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {}
207 };
208 renderer.setGLEventListener(preTileGLEL, postTileGLEL);
209
210 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
211 public void run() {
212 frame.pack();
213 frame.setVisible(true);
214 }});
215
216 final Animator animator = new Animator(glad);
217 animator.setUpdateFPSFrames(60, System.err);
218 animator.start();
219
220 boolean signalTileRenderer = true;
221
222 while(!quitAdapter.shouldQuit() && animator.isAnimating() &&
223 ( rendererActive[0] || animator.getTotalFPSDuration()<duration ) )
224 {
225 if( signalTileRenderer && animator.getTotalFPSDuration() > 90 ) {
226 signalTileRenderer = false;
227 // tile rendering !
228 System.err.println("XXX START TILE RENDERING");
229 renderer.attachAutoDrawable(glad);
230 }
231 Thread.sleep(100);
232 }
233
234 Assert.assertNotNull(frame);
235 Assert.assertNotNull(glad);
236 Assert.assertNotNull(animator);
237
238 animator.stop();
239 Assert.assertEquals(false, animator.isAnimating());
240 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
241 public void run() {
242 frame.setVisible(false);
243 }});
244 Assert.assertEquals(false, frame.isVisible());
245 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
246 public void run() {
247 frame.remove(glad);
248 frame.dispose();
249 }});
250 }
251
252 public static void main(final String args[]) {
253 for(int i=0; i<args.length; i++) {
254 if(args[i].equals("-time")) {
255 i++;
256 try {
257 duration = Integer.parseInt(args[i]);
258 } catch (final Exception ex) { ex.printStackTrace(); }
259 }
260 }
261 org.junit.runner.JUnitCore.main(TestRandomTiledRendering3GL2AWT.class.getName());
262 }
263}
Specifies a set of OpenGL capabilities.
void setNumSamples(final int numSamples)
If sample buffers are enabled, indicates the number of buffers to be allocated.
final GLProfile getGLProfile()
Returns the GL profile you desire or used by the drawable.
void setSampleBuffers(final boolean enable)
Defaults to false.
Demos an onscreen AWT GLCanvas being used for RandomTileRenderer rendering to produce a PNG file.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
GLProfile getGLProfile()
Returns the GLProfile associated with this GL object.
boolean isGLOriented()
Returns true if the drawable is rendered in OpenGL's coordinate system, origin at bottom left.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.