JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestFBOOnThreadSharedContext1DemoES2NEWT.java
Go to the documentation of this file.
1/**
2 * Copyright 2012 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 */
28
29package com.jogamp.opengl.test.junit.jogl.acore;
30
31import java.io.BufferedReader;
32import java.io.IOException;
33import java.io.InputStreamReader;
34
35import com.jogamp.newt.event.WindowEvent;
36import com.jogamp.newt.event.WindowAdapter;
37import com.jogamp.newt.opengl.GLWindow;
38import com.jogamp.opengl.test.junit.util.MiscUtils;
39import com.jogamp.opengl.test.junit.util.NewtTestUtil;
40import com.jogamp.opengl.test.junit.util.UITestCase;
41import com.jogamp.opengl.test.junit.util.QuitAdapter;
42
43import com.jogamp.opengl.util.Animator;
44import com.jogamp.opengl.util.GLReadBufferUtil;
45import com.jogamp.opengl.util.texture.TextureIO;
46import com.jogamp.opengl.test.junit.jogl.demos.GLFinishOnDisplay;
47import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
48import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2;
49import com.jogamp.common.util.InterruptSource;
50import com.jogamp.nativewindow.NativeSurface;
51import com.jogamp.nativewindow.SurfaceUpdatedListener;
52import com.jogamp.opengl.GL;
53import com.jogamp.opengl.GLAutoDrawable;
54import com.jogamp.opengl.GLCapabilities;
55import com.jogamp.opengl.GLCapabilitiesImmutable;
56import com.jogamp.opengl.GLContext;
57import com.jogamp.opengl.GLDrawableFactory;
58import com.jogamp.opengl.GLEventListener;
59import com.jogamp.opengl.GLOffscreenAutoDrawable;
60import com.jogamp.opengl.GLProfile;
61
62import org.junit.Assert;
63import org.junit.AfterClass;
64import org.junit.Test;
65import org.junit.FixMethodOrder;
66import org.junit.runners.MethodSorters;
67
68/**
69 * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the
70 * {@link GLDrawableFactory#createOffscreenAutoDrawable(com.jogamp.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, com.jogamp.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}.
71 * <p>
72 * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}.
73 * </p>
74 * <p>
75 * This test simulates shared on-thread GL context / texture usage,
76 * where the producer uses an FBO and delivers a shared texture.
77 * The receiver draws the shared texture onscreen.
78 * In detail the test consist of:
79 * <ul>
80 * <li>1 {@link GLOffscreenAutoDrawable.FBO} double buffered
81 * <ul>
82 * <liwith its own {@link GLContext}, which is shares the {@link GLWindow} one (see below)</li>
83 * <li>running within common {@link Animator} @ 60fps</li>
84 * <li>produce a texture</li>
85 * <li>notify the onscreen renderer about new textureID (swapping double buffer)</li>
86 * </ul></li>
87 * <li>1 onscreen {@link GLWindow}
88 * <ul>
89 * <li>shares it's {@link GLContext} w/ above FBO</li>
90 * <li>running within common {@link Animator} @ 60fps</li>
91 * <li>uses the shared FBO texture and draws it onscreen</li>
92 * </ul></li>
93 * </ul>
94 * </p>
95 */
96@FixMethodOrder(MethodSorters.NAME_ASCENDING)
98 static long duration = 500; // ms
99 static int swapInterval = 1;
100 static boolean showFPS = false;
101 static boolean forceES2 = false;
102 static boolean mainRun = false;
103
104 @AfterClass
105 public static void releaseClass() {
106 }
107
108 protected void runTestGL(final GLCapabilitiesImmutable caps) throws InterruptedException {
109 final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
110 System.err.println("requested: vsync "+swapInterval+", "+caps);
111
112 final GLWindow glWindow = GLWindow.create(caps);
113 Assert.assertNotNull(glWindow);
114 glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
115 if(mainRun) {
116 glWindow.setSize(512, 512);
117 } else {
118 glWindow.setSize(256, 256);
119 }
120 // eager initialization of context
121 glWindow.setVisible(true);
122 glWindow.display();
123
124 final int fbod1_texUnit = 0;
125
126 final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
127 final GLCapabilities fbodCaps = (GLCapabilities) caps.cloneMutable();
128 // fbodCaps.setDoubleBuffered(false);
129
130 final Mix2TexturesES2 mixerDemo = new Mix2TexturesES2(1, fbod1_texUnit, 0);
131
132 // FBOD1
133 final GLOffscreenAutoDrawable.FBO fbod1 = (GLOffscreenAutoDrawable.FBO)
134 factory.createOffscreenAutoDrawable(null, fbodCaps, null, glWindow.getSurfaceWidth(), glWindow.getSurfaceHeight());
135 fbod1.setSharedAutoDrawable(glWindow);
136 fbod1.setUpstreamWidget(glWindow); // connect the real GLWindow (mouse/key) to offscreen!
137 fbod1.setTextureUnit(fbod1_texUnit);
138 {
139 final GearsES2 demo0 = new GearsES2(-1);
140 fbod1.addGLEventListener(demo0);
141 fbod1.addGLEventListener(new GLFinishOnDisplay());
142 demo0.setIgnoreFocus(true);
143 }
144 fbod1.getNativeSurface().addSurfaceUpdatedListener(new SurfaceUpdatedListener() {
145 @Override
146 public void surfaceUpdated(final Object updater, final NativeSurface ns, final long when) {
147 mixerDemo.setTexID0(fbod1.getColorbuffer(GL.GL_FRONT).getName());
148 } });
149 fbod1.display(); // init
150 System.err.println("FBOD1 "+fbod1);
151 Assert.assertTrue(fbod1.isInitialized());
152
153 // preinit texIDs
154 mixerDemo.setTexID0(fbod1.getColorbuffer(GL.GL_FRONT).getName());
155
156 glWindow.addWindowListener(new WindowAdapter() {
157 @Override
158 public void windowResized(final WindowEvent e) {
159 fbod1.setSurfaceSize(glWindow.getSurfaceWidth(), glWindow.getSurfaceHeight());
160 }
161 });
162 glWindow.addGLEventListener(mixerDemo);
163 glWindow.addGLEventListener(new GLEventListener() {
164 int i=0, c=0;
165 @Override
166 public void init(final GLAutoDrawable drawable) {}
167 @Override
168 public void dispose(final GLAutoDrawable drawable) {}
169 @Override
170 public void display(final GLAutoDrawable drawable) {
171 if(mainRun) return;
172
173 final int dw = drawable.getSurfaceWidth();
174 final int dh = drawable.getSurfaceHeight();
175 c++;
176
177 if(dw<800) {
178 System.err.println("XXX: "+dw+"x"+dh+", c "+c);
179 if(8 == c) {
180 snapshot(i++, "msaa"+fbod1.getNumSamples(), drawable.getGL(), screenshot, TextureIO.PNG, null);
181 }
182 if(9 == c) {
183 c=0;
184 new InterruptSource.Thread() {
185 @Override
186 public void run() {
187 glWindow.setSize(dw+256, dh+256);
188 } }.start();
189 }
190 }
191 }
192 @Override
193 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { }
194 });
195
196 final Animator animator1 = new Animator(0 /* w/o AWT */);
197 animator1.add(fbod1);
198 animator1.add(glWindow);
199
200 final QuitAdapter quitAdapter = new QuitAdapter();
201
202 //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
203 //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
204 glWindow.addKeyListener(quitAdapter);
205 glWindow.addWindowListener(quitAdapter);
206
207 glWindow.addWindowListener(new WindowAdapter() {
208 @Override
209 public void windowResized(final WindowEvent e) {
210 System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
211 }
212 @Override
213 public void windowMoved(final WindowEvent e) {
214 System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight());
215 }
216 });
217
218 animator1.start();
219 // glWindow.setSkipContextReleaseThread(animator.getThread());
220
221 glWindow.setVisible(true);
222
223 System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
224 System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
225 System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets());
226
227 animator1.setUpdateFPSFrames(60, showFPS ? System.err : null);
228
229 while(!quitAdapter.shouldQuit() && animator1.isAnimating() && animator1.getTotalFPSDuration()<duration) {
230 Thread.sleep(100);
231 }
232
233 animator1.stop();
234 Assert.assertFalse(animator1.isAnimating());
235 Assert.assertFalse(animator1.isStarted());
236
237 fbod1.destroy();
238
239 glWindow.destroy();
240 Assert.assertEquals(true, NewtTestUtil.waitForRealized(glWindow, false, null));
241 }
242
243 @Test
244 public void test01() throws InterruptedException {
246 caps.setAlphaBits(1);
247 runTestGL(caps);
248 }
249
250 public static void main(final String args[]) throws IOException {
251 boolean waitForKey = false;
252
253 mainRun = true;
254
255 for(int i=0; i<args.length; i++) {
256 if(args[i].equals("-time")) {
257 i++;
258 duration = MiscUtils.atol(args[i], duration);
259 } else if(args[i].equals("-vsync")) {
260 i++;
261 swapInterval = MiscUtils.atoi(args[i], swapInterval);
262 } else if(args[i].equals("-es2")) {
263 forceES2 = true;
264 } else if(args[i].equals("-showFPS")) {
265 showFPS = true;
266 } else if(args[i].equals("-wait")) {
267 waitForKey = true;
268 } else if(args[i].equals("-nomain")) {
269 mainRun = false;
270 }
271 }
272
273 System.err.println("swapInterval "+swapInterval);
274 System.err.println("forceES2 "+forceES2);
275
276 if(waitForKey) {
277 final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
278 System.err.println("Press enter to continue");
279 try {
280 System.err.println(stdin.readLine());
281 } catch (final IOException e) { }
282 }
283 org.junit.runner.JUnitCore.main(TestFBOOnThreadSharedContext1DemoES2NEWT.class.getName());
284 }
285}
void setAlphaBits(final int alphaBits)
Sets the number of bits requested for the color buffer's alpha component.
NEWT Window events are provided for notification purposes ONLY.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Definition: GLWindow.java:466
final void setTitle(final String title)
Definition: GLWindow.java:297
final int getX()
Returns the current x position of this window, relative to it's parent.
Definition: GLWindow.java:436
final void addKeyListener(final KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
Definition: GLWindow.java:902
final int getY()
Returns the current y position of the top-left corner of the client area relative to it's parent in w...
Definition: GLWindow.java:441
final int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
Definition: GLWindow.java:461
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final void addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
Definition: GLWindow.java:882
final CapabilitiesImmutable getChosenCapabilities()
Gets an immutable set of chosen capabilities.
Definition: GLWindow.java:266
final InsetsImmutable getInsets()
Returns the insets defined as the width and height of the window decoration on the left,...
Definition: GLWindow.java:431
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
final Window getDelegatedWindow()
If the implementation uses delegation, return the delegated Window instance, otherwise return this in...
Definition: GLWindow.java:277
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, int width, int height)
Creates a realized GLOffscreenAutoDrawable incl it's offscreen NativeSurface with the given capabilit...
static GLDrawableFactory getFactory(final GLProfile glProfile)
Returns the sole GLDrawableFactory instance.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static final String GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition: GLProfile.java:585
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
Toolkit agnostic GLOffscreenAutoDrawable.FBO tests using the factory model.
static int atoi(final String str, final int def)
Definition: MiscUtils.java:57
static long atol(final String str, final long def)
Definition: MiscUtils.java:66
static boolean waitForRealized(final Screen screen, final boolean realized, final Runnable waitAction)
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final void setUpdateFPSFrames(final int frames, final PrintStream out)
synchronized boolean isStarted()
Indicates whether this animator has been started.
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
Utility to read out the current FB to TextureData, optionally writing the data back to a texture obje...
static final String PNG
Constant which can be used as a file suffix to indicate a PNG file, value {@value}.
Definition: TextureIO.java:171
Provides low-level information required for hardware-accelerated rendering using a surface in a platf...
Clients may add their SurfaceUpdateListener implementation to a com.jogamp.nativewindow....
CapabilitiesImmutable getChosenCapabilities()
Gets an immutable set of chosen capabilities.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Specifies an immutable set of OpenGL capabilities.
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
FBObject based GLOffscreenAutoDrawable specialization
Platform-independent GLAutoDrawable specialization, exposing offscreen functionality.
void setSharedAutoDrawable(GLAutoDrawable sharedAutoDrawable)
Specifies an GLAutoDrawable, which OpenGL context shall be shared by this GLAutoDrawable's GLContext.
static final int GL_FRONT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_FRONT" with expressio...
Definition: GL.java:597