JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
Bug735Inv2AppletAWT.java
Go to the documentation of this file.
1package com.jogamp.opengl.test.bugs;
2
3import java.applet.Applet;
4import java.awt.BorderLayout;
5import java.awt.Color;
6import java.awt.Dimension;
7import java.awt.EventQueue;
8import java.awt.Frame;
9import java.awt.GraphicsDevice;
10import java.awt.GraphicsEnvironment;
11import java.awt.Insets;
12import java.awt.Rectangle;
13import java.awt.event.WindowAdapter;
14import java.awt.event.WindowEvent;
15import java.util.concurrent.CountDownLatch;
16import java.util.concurrent.TimeUnit;
17
18import com.jogamp.opengl.GLAutoDrawable;
19import com.jogamp.opengl.GLCapabilities;
20import com.jogamp.opengl.GLEventListener;
21import com.jogamp.opengl.GLProfile;
22import com.jogamp.opengl.awt.GLCanvas;
23import com.jogamp.common.os.Clock;
24import com.jogamp.common.util.InterruptSource;
25import com.jogamp.junit.util.JunitTracer;
26import com.jogamp.newt.awt.NewtCanvasAWT;
27import com.jogamp.newt.opengl.GLWindow;
28import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
29import com.jogamp.opengl.test.junit.util.MiscUtils;
30import com.jogamp.opengl.test.junit.util.UITestCase;
31
32/**
33 * Difference to orig. Bug735Inv0AppletAWT:
34 * <pre>
35 * - Use GLEventListener
36 * - Add GLEventListener to GLAutoDrawable
37 * - Use GLAutoDrawable.display() instead of GLAutoDrawable.invoke(true, GLRunnable { init / render })
38 * - Removed MANUAL_FRAME_HANDLING, obsolete due to GLAutoDrawable/GLEventListener
39 * </pre>
40 * OSX Results:
41 * <pre>
42 * - Visible content
43 * - Fluent animation
44 * </pre>
45 */
46@SuppressWarnings("serial")
47public class Bug735Inv2AppletAWT extends Applet implements Runnable {
48 static public final int AWT = 0;
49 static public final int NEWT = 1;
50
51 static public final int APPLET_WIDTH = 500;
52 static public final int APPLET_HEIGHT = 290;
53 static public final int TARGET_FPS = 120;
54 static public final int TOOLKIT = NEWT;
55 static public final boolean IGNORE_AWT_REPAINT = false;
56 static public boolean USE_ECT = false;
57 static public int SWAP_INTERVAL = 1;
58
59 //////////////////////////////////////////////////////////////////////////////
60
61 static boolean waitForKey = false;
62 static private Frame frame;
63 static private Bug735Inv2AppletAWT applet;
64 private GLCanvas awtCanvas;
65 private GLWindow newtWindow;
66 private GLAutoDrawable glad;
67 private NewtCanvasAWT newtCanvas;
68 private GLEventListener demo;
69
70 private int width;
71 private int height;
72 private Thread thread;
73
74 private final long frameRatePeriod = 1000000000L / TARGET_FPS;
75 private int frameCount;
76
77 @Override
78public void init() {
79 setSize(APPLET_WIDTH, APPLET_HEIGHT);
80 setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
81 width = APPLET_WIDTH;
82 height = APPLET_HEIGHT;
83 initGL();
84 }
85
86 @Override
87public void start() {
88 initDraw();
89 thread = new InterruptSource.Thread(null, this, "Animation Thread");
90 thread.start();
91 }
92
93 @Override
94public void run() {
95 int noDelays = 0;
96 // Number of frames with a delay of 0 ms before the
97 // animation thread yields to other running threads.
98 final int NO_DELAYS_PER_YIELD = 15;
99 final int TIMEOUT_SECONDS = 2;
100
101 long beforeTime = Clock.currentNanos();
102 long overSleepTime = 0L;
103
104 frameCount = 1;
105 while (Thread.currentThread() == thread) {
106 if (frameCount == 1) {
107 EventQueue.invokeLater(new Runnable() {
108 @Override
109 public void run() {
110 requestFocusInWindow();
111 }
112 });
113 if( USE_ECT ) {
114 glad.setExclusiveContextThread(thread);
115 }
116 }
117 final CountDownLatch latch = new CountDownLatch(1);
118 requestDraw(latch);
119 try {
120 latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
121 } catch (final InterruptedException e) {
122 e.printStackTrace();
123 }
124
125 final long afterTime = Clock.currentNanos();
126 final long timeDiff = afterTime - beforeTime;
127 final long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
128 if (sleepTime > 0) { // some time left in this cycle
129 try {
130 Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
131 noDelays = 0; // Got some sleep, not delaying anymore
132 } catch (final InterruptedException ex) { }
133 overSleepTime = (Clock.currentNanos() - afterTime) - sleepTime;
134 } else { // sleepTime <= 0; the frame took longer than the period
135 overSleepTime = 0L;
136 noDelays++;
137 if (noDelays > NO_DELAYS_PER_YIELD) {
138 Thread.yield(); // give another thread a chance to run
139 noDelays = 0;
140 }
141 }
142 beforeTime = Clock.currentNanos();
143 }
144 }
145
146 public void requestDraw(final CountDownLatch latch) {
147 glad.display();
148
149 if (latch != null) {
150 latch.countDown();
151 }
152 }
153
154 private void initGL() {
155 final GLProfile profile = GLProfile.getDefault();
156 final GLCapabilities caps = new GLCapabilities(profile);
157 caps.setBackgroundOpaque(true);
158 caps.setOnscreen(true);
159 caps.setSampleBuffers(false);
160
161 if (TOOLKIT == AWT) {
162 awtCanvas = new GLCanvas(caps);
163 awtCanvas.setBounds(0, 0, applet.width, applet.height);
164 awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
165 awtCanvas.setFocusable(true);
166
167 applet.setLayout(new BorderLayout());
168 applet.add(awtCanvas, BorderLayout.CENTER);
169
170 if (IGNORE_AWT_REPAINT) {
171 awtCanvas.setIgnoreRepaint(true);
172 }
173 glad = awtCanvas;
174 } else if (TOOLKIT == NEWT) {
175 newtWindow = GLWindow.create(caps);
176 newtCanvas = new NewtCanvasAWT(newtWindow);
177 newtCanvas.setBounds(0, 0, applet.width, applet.height);
178 newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
179 newtCanvas.setFocusable(true);
180
181 applet.setLayout(new BorderLayout());
182 applet.add(newtCanvas, BorderLayout.CENTER);
183
184 if (IGNORE_AWT_REPAINT) {
185 newtCanvas.setIgnoreRepaint(true);
186 }
187 glad = newtWindow;
188 }
189
190 demo = new LandscapeES2(SWAP_INTERVAL);
191 glad.addGLEventListener(demo);
192 }
193
194 private void initDraw() {
195 if (TOOLKIT == AWT) {
196 awtCanvas.setVisible(true);
197 // Force the realization
198 awtCanvas.display();
199 if (awtCanvas.getDelegatedDrawable().isRealized()) {
200 // Request the focus here as it cannot work when the window is not visible
201 awtCanvas.requestFocus();
202 }
203 } else if (TOOLKIT == NEWT) {
204 newtCanvas.setVisible(true);
205 // Force the realization
206 newtWindow.display();
207 if (newtWindow.isRealized()) {
208 // Request the focus here as it cannot work when the window is not visible
209 newtCanvas.requestFocus();
210 }
211 }
212 }
213
214 static public void main(final String[] args) {
215 for(int i=0; i<args.length; i++) {
216 if(args[i].equals("-vsync")) {
217 i++;
218 SWAP_INTERVAL = MiscUtils.atoi(args[i], SWAP_INTERVAL);
219 } else if(args[i].equals("-exclctx")) {
220 USE_ECT = true;
221 } else if(args[i].equals("-wait")) {
222 waitForKey = true;
223 }
224 }
225 System.err.println("swapInterval "+SWAP_INTERVAL);
226 System.err.println("exclusiveContext "+USE_ECT);
227 if(waitForKey) {
228 JunitTracer.waitForKey("Start");
229 }
230
231 final GraphicsEnvironment environment =
232 GraphicsEnvironment.getLocalGraphicsEnvironment();
233 final GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
234
235 frame = new Frame(displayDevice.getDefaultConfiguration());
236 frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
237 frame.setTitle("TestBug735Inv2AppletAWT");
238
239 try {
240 final Class<?> c = Thread.currentThread().getContextClassLoader().
241 loadClass(Bug735Inv2AppletAWT.class.getName());
242 applet = (Bug735Inv2AppletAWT) c.newInstance();
243 } catch (final Exception e) {
244 throw new RuntimeException(e);
245 }
246
247 frame.setLayout(null);
248 frame.add(applet);
249 frame.pack();
250 frame.setResizable(false);
251
252 applet.init();
253
254 final Insets insets = frame.getInsets();
255 final int windowW = applet.width + insets.left + insets.right;
256 final int windowH = applet.height + insets.top + insets.bottom;
257 frame.setSize(windowW, windowH);
258
259 final Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
260 frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
261 screenRect.y + (screenRect.height - applet.height) / 2);
262
263 final int usableWindowH = windowH - insets.top - insets.bottom;
264 applet.setBounds((windowW - applet.width)/2,
265 insets.top + (usableWindowH - applet.height)/2,
266 applet.width, applet.height);
267
268 // This allows to close the frame.
269 frame.addWindowListener(new WindowAdapter() {
270 @Override
271 public void windowClosing(final WindowEvent e) {
272 System.exit(0);
273 }
274 });
275
276 frame.setVisible(true);
277 applet.start();
278 }
279}
void setBackgroundOpaque(final boolean opaque)
Sets whether the surface shall be opaque or translucent.
void setOnscreen(final boolean onscreen)
Sets whether the surface shall be on- or offscreen.
AWT Canvas containing a NEWT Window using native parenting.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
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.
void setSampleBuffers(final boolean enable)
Defaults to false.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getDefault(final AbstractGraphicsDevice device)
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:739
A heavyweight AWT component which provides OpenGL rendering support.
Definition: GLCanvas.java:170
final GLDrawable getDelegatedDrawable()
If the implementation uses delegation, return the delegated GLDrawable instance, otherwise return thi...
Definition: GLCanvas.java:1161
static int atoi(final String str, final int def)
Definition: MiscUtils.java:57
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
Thread setExclusiveContextThread(Thread t)
Dedicates this instance's GLContext to the given thread.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
boolean isRealized()
Returns true if this drawable is realized, otherwise false.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.