PageRenderTime 33ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 0ms

/src/test/com/jogamp/opengl/test/bugs/Bug735Inv0AppletAWT.java

http://github.com/sgothel/jogl
Java | 430 lines | 346 code | 63 blank | 21 comment | 46 complexity | 62f806c01643978cd2bfded08b62d180 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1
  1. package com.jogamp.opengl.test.bugs;
  2. import java.applet.Applet;
  3. import java.awt.BorderLayout;
  4. import java.awt.Color;
  5. import java.awt.Dimension;
  6. import java.awt.EventQueue;
  7. import java.awt.Frame;
  8. import java.awt.GraphicsDevice;
  9. import java.awt.GraphicsEnvironment;
  10. import java.awt.Insets;
  11. import java.awt.Rectangle;
  12. import java.awt.event.WindowAdapter;
  13. import java.awt.event.WindowEvent;
  14. import java.nio.FloatBuffer;
  15. import java.util.concurrent.CountDownLatch;
  16. import java.util.concurrent.TimeUnit;
  17. import com.jogamp.opengl.GL;
  18. import com.jogamp.opengl.GL2ES2;
  19. import com.jogamp.opengl.GLAutoDrawable;
  20. import com.jogamp.opengl.GLCapabilities;
  21. import com.jogamp.opengl.GLContext;
  22. import com.jogamp.opengl.GLException;
  23. import com.jogamp.opengl.GLProfile;
  24. import com.jogamp.opengl.GLRunnable;
  25. import com.jogamp.opengl.GLUniformData;
  26. import com.jogamp.opengl.awt.GLCanvas;
  27. import com.jogamp.opengl.glu.GLU;
  28. import com.jogamp.common.util.InterruptSource;
  29. import com.jogamp.newt.awt.NewtCanvasAWT;
  30. import com.jogamp.newt.opengl.GLWindow;
  31. import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2;
  32. import com.jogamp.opengl.util.GLArrayDataServer;
  33. import com.jogamp.opengl.util.glsl.ShaderCode;
  34. import com.jogamp.opengl.util.glsl.ShaderProgram;
  35. import com.jogamp.opengl.util.glsl.ShaderState;
  36. /**
  37. * Original test case.
  38. * <br/>
  39. * OSX Results:
  40. * <pre>
  41. * - Visible content
  42. * - Fluent animation
  43. * </pre>
  44. */
  45. @SuppressWarnings("serial")
  46. public class Bug735Inv0AppletAWT extends Applet implements Runnable {
  47. static public final int AWT = 0;
  48. static public final int NEWT = 1;
  49. static public final int APPLET_WIDTH = 500;
  50. static public final int APPLET_HEIGHT = 290;
  51. static public final int TARGET_FPS = 120;
  52. static public final int TOOLKIT = NEWT;
  53. static public final boolean MANUAL_FRAME_HANDLING = true;
  54. //////////////////////////////////////////////////////////////////////////////
  55. static private Frame frame;
  56. static private Bug735Inv0AppletAWT applet;
  57. private GLCanvas awtCanvas;
  58. private GLWindow newtWindow;
  59. private NewtCanvasAWT newtCanvas;
  60. private DrawRunnable drawRunnable;
  61. private GLContext context;
  62. private GLU glu;
  63. private int width;
  64. private int height;
  65. private Thread thread;
  66. private boolean doneInit = false;
  67. private boolean doneSetup = false;
  68. private final long frameRatePeriod = 1000000000L / TARGET_FPS;
  69. private long millisOffset;
  70. private int frameCount;
  71. private float frameRate;
  72. private ShaderCode vertShader;
  73. private ShaderCode fragShader;
  74. private ShaderProgram shaderProg;
  75. private ShaderState shaderState;
  76. private GLUniformData resolution;
  77. private GLUniformData time;
  78. private GLArrayDataServer vertices;
  79. private int fcount = 0, lastm = 0;
  80. private final int fint = 1;
  81. public void init() {
  82. setSize(APPLET_WIDTH, APPLET_HEIGHT);
  83. setPreferredSize(new Dimension(APPLET_WIDTH, APPLET_HEIGHT));
  84. width = APPLET_WIDTH;
  85. height = APPLET_HEIGHT;
  86. }
  87. public void start() {
  88. thread = new InterruptSource.Thread(null, this, "Animation Thread");
  89. thread.start();
  90. }
  91. public void run() {
  92. int noDelays = 0;
  93. // Number of frames with a delay of 0 ms before the
  94. // animation thread yields to other running threads.
  95. final int NO_DELAYS_PER_YIELD = 15;
  96. final int TIMEOUT_SECONDS = 2;
  97. long beforeTime = System.nanoTime();
  98. long overSleepTime = 0L;
  99. millisOffset = System.currentTimeMillis();
  100. frameCount = 1;
  101. while (Thread.currentThread() == thread) {
  102. final CountDownLatch latch = new CountDownLatch(1);
  103. requestDraw(latch);
  104. try {
  105. latch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
  106. } catch (final InterruptedException e) {
  107. e.printStackTrace();
  108. }
  109. if (frameCount == 1) {
  110. EventQueue.invokeLater(new Runnable() {
  111. public void run() {
  112. requestFocusInWindow();
  113. }
  114. });
  115. }
  116. final long afterTime = System.nanoTime();
  117. final long timeDiff = afterTime - beforeTime;
  118. final long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
  119. if (sleepTime > 0) { // some time left in this cycle
  120. try {
  121. Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
  122. noDelays = 0; // Got some sleep, not delaying anymore
  123. } catch (final InterruptedException ex) { }
  124. overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
  125. } else { // sleepTime <= 0; the frame took longer than the period
  126. overSleepTime = 0L;
  127. noDelays++;
  128. if (noDelays > NO_DELAYS_PER_YIELD) {
  129. Thread.yield(); // give another thread a chance to run
  130. noDelays = 0;
  131. }
  132. }
  133. beforeTime = System.nanoTime();
  134. }
  135. }
  136. public void requestDraw(final CountDownLatch latch) {
  137. if (!doneInit) {
  138. initDraw();
  139. }
  140. if (TOOLKIT == AWT) {
  141. awtCanvas.invoke(true, drawRunnable);
  142. } else if (TOOLKIT == NEWT) {
  143. newtWindow.invoke(true, drawRunnable);
  144. }
  145. if (latch != null) {
  146. latch.countDown();
  147. }
  148. }
  149. private class DrawRunnable implements GLRunnable {
  150. private boolean notCurrent;
  151. @Override
  152. public boolean run(final GLAutoDrawable drawable) {
  153. if (MANUAL_FRAME_HANDLING) {
  154. makeContextCurrent();
  155. }
  156. if (doneSetup) {
  157. draw(drawable.getGL().getGL2ES2());
  158. } else {
  159. setup(drawable.getGL().getGL2ES2());
  160. }
  161. checkGLErrors(drawable.getGL());
  162. if (MANUAL_FRAME_HANDLING) {
  163. swapBuffers();
  164. releaseCurrentContext();
  165. }
  166. return true;
  167. }
  168. private void makeContextCurrent() {
  169. final int MAX_CONTEXT_GRAB_ATTEMPTS = 10;
  170. if (context.isCurrent()) {
  171. notCurrent = false;
  172. } else {
  173. notCurrent = true;
  174. int value = GLContext.CONTEXT_NOT_CURRENT;
  175. int attempt = 0;
  176. do {
  177. try {
  178. value = context.makeCurrent();
  179. System.out.println("Made context current");
  180. } catch (final GLException gle) {
  181. gle.printStackTrace();
  182. } finally {
  183. attempt++;
  184. if (attempt == MAX_CONTEXT_GRAB_ATTEMPTS) {
  185. throw new RuntimeException("Failed to claim OpenGL context.");
  186. }
  187. }
  188. try {
  189. Thread.sleep(5);
  190. } catch (final InterruptedException e) {
  191. e.printStackTrace();
  192. }
  193. } while (value == GLContext.CONTEXT_NOT_CURRENT);
  194. }
  195. }
  196. private void swapBuffers() {
  197. final GL gl = GLContext.getCurrentGL();
  198. gl.glFlush();
  199. GLContext.getCurrent().getGLDrawable().swapBuffers();
  200. }
  201. private void releaseCurrentContext() {
  202. if (notCurrent) {
  203. try {
  204. context.release();
  205. System.out.println("Released context");
  206. } catch (final GLException gle) {
  207. gle.printStackTrace();
  208. }
  209. }
  210. }
  211. }
  212. private void initGL() {
  213. final GLProfile profile = GLProfile.getDefault();
  214. final GLCapabilities caps = new GLCapabilities(profile);
  215. caps.setBackgroundOpaque(true);
  216. caps.setOnscreen(true);
  217. caps.setSampleBuffers(false);
  218. if (TOOLKIT == AWT) {
  219. awtCanvas = new GLCanvas(caps);
  220. awtCanvas.setBounds(0, 0, applet.width, applet.height);
  221. awtCanvas.setBackground(new Color(0xFFCCCCCC, true));
  222. awtCanvas.setFocusable(true);
  223. applet.setLayout(new BorderLayout());
  224. applet.add(awtCanvas, BorderLayout.CENTER);
  225. if (MANUAL_FRAME_HANDLING) {
  226. awtCanvas.setIgnoreRepaint(true);
  227. awtCanvas.setAutoSwapBufferMode(false);
  228. }
  229. } else if (TOOLKIT == NEWT) {
  230. newtWindow = GLWindow.create(caps);
  231. newtCanvas = new NewtCanvasAWT(newtWindow);
  232. newtCanvas.setBounds(0, 0, applet.width, applet.height);
  233. newtCanvas.setBackground(new Color(0xFFCCCCCC, true));
  234. newtCanvas.setFocusable(true);
  235. applet.setLayout(new BorderLayout());
  236. applet.add(newtCanvas, BorderLayout.CENTER);
  237. if (MANUAL_FRAME_HANDLING) {
  238. newtCanvas.setIgnoreRepaint(true);
  239. newtWindow.setAutoSwapBufferMode(false);
  240. }
  241. }
  242. }
  243. private void initDraw() {
  244. if (TOOLKIT == AWT) {
  245. awtCanvas.setVisible(true);
  246. // Force the realization
  247. awtCanvas.display();
  248. if (awtCanvas.getDelegatedDrawable().isRealized()) {
  249. // Request the focus here as it cannot work when the window is not visible
  250. awtCanvas.requestFocus();
  251. context = awtCanvas.getContext();
  252. }
  253. } else if (TOOLKIT == NEWT) {
  254. newtCanvas.setVisible(true);
  255. // Force the realization
  256. newtWindow.display();
  257. if (newtWindow.isRealized()) {
  258. // Request the focus here as it cannot work when the window is not visible
  259. newtCanvas.requestFocus();
  260. context = newtWindow.getContext();
  261. }
  262. }
  263. drawRunnable = new DrawRunnable();
  264. doneInit = true;
  265. }
  266. private void setup(final GL2ES2 gl) {
  267. if (60 < TARGET_FPS) {
  268. // Disables vsync
  269. gl.setSwapInterval(0);
  270. }
  271. glu = new GLU();
  272. vertShader = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
  273. fragShader = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, LandscapeES2.class, "shader", "shader/bin", "landscape", true);
  274. vertShader.defaultShaderCustomization(gl, true, true);
  275. fragShader.defaultShaderCustomization(gl, true, true);
  276. shaderProg = new ShaderProgram();
  277. shaderProg.add(gl, vertShader, System.err);
  278. shaderProg.add(gl, fragShader, System.err);
  279. shaderState = new ShaderState();
  280. shaderState.attachShaderProgram(gl, shaderProg, true);
  281. resolution = new GLUniformData("iResolution", 3, FloatBuffer.wrap(new float[] {width, height, 0}));
  282. shaderState.ownUniform(resolution);
  283. shaderState.uniform(gl, resolution);
  284. time = new GLUniformData("iGlobalTime", 0.0f);
  285. shaderState.ownUniform(time);
  286. vertices = GLArrayDataServer.createGLSL("inVertex", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
  287. vertices.putf(-1.0f); vertices.putf(-1.0f);
  288. vertices.putf(+1.0f); vertices.putf(-1.0f);
  289. vertices.putf(-1.0f); vertices.putf(+1.0f);
  290. vertices.putf(+1.0f); vertices.putf(+1.0f);
  291. vertices.seal(gl, true);
  292. shaderState.ownAttribute(vertices, true);
  293. shaderState.useProgram(gl, false);
  294. doneSetup = true;
  295. }
  296. private void draw(final GL2ES2 gl) {
  297. // gl.glClearColor(0.5f, 0.1f, 0.1f, 1);
  298. // gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT);
  299. shaderState.useProgram(gl, true);
  300. time.setData((System.currentTimeMillis() - millisOffset) / 1000.0f);
  301. shaderState.uniform(gl, time);
  302. vertices.enableBuffer(gl, true);
  303. gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
  304. vertices.enableBuffer(gl, false);
  305. shaderState.useProgram(gl, false);
  306. // Compute current framerate and printout.
  307. frameCount++;
  308. fcount += 1;
  309. final int m = (int) (System.currentTimeMillis() - millisOffset);
  310. if (m - lastm > 1000 * fint) {
  311. frameRate = (float)(fcount) / fint;
  312. fcount = 0;
  313. lastm = m;
  314. }
  315. if (frameCount % TARGET_FPS == 0) {
  316. System.out.println("FrameCount: " + frameCount + " - " +
  317. "FrameRate: " + frameRate);
  318. }
  319. }
  320. private void checkGLErrors(final GL gl) {
  321. final int err = gl.glGetError();
  322. if (err != 0) {
  323. final String errString = glu.gluErrorString(err);
  324. System.out.println(errString);
  325. }
  326. }
  327. static public void main(final String[] args) {
  328. final GraphicsEnvironment environment =
  329. GraphicsEnvironment.getLocalGraphicsEnvironment();
  330. final GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
  331. frame = new Frame(displayDevice.getDefaultConfiguration());
  332. frame.setBackground(new Color(0xCC, 0xCC, 0xCC));
  333. frame.setTitle("TestBug735Inv0AppletAWT");
  334. try {
  335. final Class<?> c = Thread.currentThread().getContextClassLoader().
  336. loadClass(Bug735Inv0AppletAWT.class.getName());
  337. applet = (Bug735Inv0AppletAWT) c.newInstance();
  338. } catch (final Exception e) {
  339. throw new RuntimeException(e);
  340. }
  341. frame.setLayout(null);
  342. frame.add(applet);
  343. frame.pack();
  344. frame.setResizable(false);
  345. applet.init();
  346. final Insets insets = frame.getInsets();
  347. final int windowW = applet.width + insets.left + insets.right;
  348. final int windowH = applet.height + insets.top + insets.bottom;
  349. frame.setSize(windowW, windowH);
  350. final Rectangle screenRect = displayDevice.getDefaultConfiguration().getBounds();
  351. frame.setLocation(screenRect.x + (screenRect.width - applet.width) / 2,
  352. screenRect.y + (screenRect.height - applet.height) / 2);
  353. final int usableWindowH = windowH - insets.top - insets.bottom;
  354. applet.setBounds((windowW - applet.width)/2,
  355. insets.top + (usableWindowH - applet.height)/2,
  356. applet.width, applet.height);
  357. // This allows to close the frame.
  358. frame.addWindowListener(new WindowAdapter() {
  359. public void windowClosing(final WindowEvent e) {
  360. System.exit(0);
  361. }
  362. });
  363. applet.initGL();
  364. frame.setVisible(true);
  365. applet.start();
  366. }
  367. }