codeanticode

Thread blocking issue - NEWT

Oct 31st, 2012
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.90 KB | None | 0 0
  1. package p5.test_newt_applet;
  2.  
  3. import java.applet.Applet;
  4. import java.awt.BorderLayout;
  5. import java.awt.Color;
  6. import java.awt.DisplayMode;
  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.KeyEvent;
  13. import java.awt.event.KeyListener;
  14. import java.awt.event.MouseEvent;
  15. import java.awt.event.MouseMotionListener;
  16. import java.awt.event.WindowAdapter;
  17. import java.awt.event.WindowEvent;
  18. import java.util.Timer;
  19. import java.util.TimerTask;
  20.  
  21. import javax.media.opengl.*;
  22.  
  23. import com.jogamp.newt.awt.NewtCanvasAWT;
  24. import com.jogamp.newt.opengl.GLWindow;
  25. import com.jogamp.opengl.util.AnimatorBase;
  26.  
  27. // Sample program that relies on JOGL's mechanism to handle the OpenGL context  
  28. // and rendering loop when using a NEWT window attached to an Applet.
  29. public class MiniPApplet extends Applet implements MouseMotionListener,
  30.                                                    KeyListener {
  31.   private static final long serialVersionUID = 1L;
  32.  
  33.   /////////////////////////////////////////////////////////////
  34.   //
  35.   // Test parameters  
  36.  
  37.   public int frameRate           = 120;
  38.   public int numSamples          = 4;
  39.  
  40.   public boolean fullScreen      = false;  
  41.   public boolean useAnimator     = true;
  42.   public boolean resizeableFrame = false;
  43.  
  44.   public boolean restartCanvas   = true;
  45.   public int restartTimeout      = 100; // in number of frames.
  46.  
  47.   public boolean printThreadInfo = false;
  48.   public boolean printEventInfo  = false;
  49.  
  50.   /////////////////////////////////////////////////////////////
  51.   //
  52.   // Internal variables
  53.  
  54.   int width;
  55.   int height;
  56.  
  57.   String OPENGL_VENDOR;  
  58.   String OPENGL_RENDERER;
  59.   String OPENGL_VERSION;    
  60.   String OPENGL_EXTENSIONS;
  61.  
  62.   int currentSamples = -1;  
  63.  
  64.   private Frame frame;
  65.   private GLProfile profile;
  66.   private GLCapabilities capabilities;
  67.   private NewtCanvasAWT canvas;
  68.   private GLWindow window;
  69.  
  70.   private SimpleListener listener;
  71.   private CustomAnimator animator;
  72.  
  73.   private long beforeTime;
  74.   private long overSleepTime;
  75.   private long frameRatePeriod = 1000000000L / frameRate;
  76.  
  77.   private boolean initialized = false;  
  78.  
  79.   private double theta = 0;
  80.   private double s = 0;
  81.   private double c = 0;  
  82.  
  83.   private long millisOffset;
  84.   private int fcount, lastm;
  85.   private float frate;
  86.   private int fint = 3;
  87.  
  88.   private boolean setFramerate = false;
  89.   private boolean restarted = false;  
  90.  
  91.   private int frameCount = 0;
  92.  
  93.   void run() {
  94.     Thread loop = new Thread("Animation Thread") {
  95.       public void run() {        
  96.         frameCount = 0;
  97.         while (true) {          
  98.           if (!initialized) {
  99.             setup();            
  100.           }
  101.          
  102.           if (restartCanvas && restartTimeout == frameCount) {
  103.             restart();
  104.           }          
  105.          
  106.           if (useAnimator) {
  107.             animator.requestRender();
  108.           } else {
  109.             window.display();
  110.           }
  111.          
  112.           clock();
  113.          
  114.           frameCount++;
  115.         }
  116.       }
  117.     };
  118.     loop.start();        
  119.   }
  120.  
  121.   void setup() {
  122.     if (printThreadInfo) System.out.println("Current thread at setup(): " + Thread.currentThread());
  123.    
  124.     millisOffset = System.currentTimeMillis();    
  125.  
  126.     // Frame setup ----------------------------------------------------------
  127.    
  128.     width = 300;
  129.     height = 300;    
  130.     MiniPApplet applet = this;
  131.     Rectangle fullScreenRect = null;
  132.    
  133.     GraphicsEnvironment environment =
  134.       GraphicsEnvironment.getLocalGraphicsEnvironment();
  135.     GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
  136.     frame = new Frame(displayDevice.getDefaultConfiguration());
  137.    
  138.     frame.setTitle("MiniPApplet");
  139.     if (fullScreen) {
  140.       frame.setUndecorated(true);
  141.       frame.setBackground(Color.GRAY);
  142.       DisplayMode mode = displayDevice.getDisplayMode();
  143.       fullScreenRect = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());
  144.       frame.setBounds(fullScreenRect);
  145.       frame.setVisible(true);
  146.     }
  147.     frame.setLayout(null);
  148.     frame.add(applet);
  149.     if (fullScreen) {
  150.       frame.invalidate();
  151.     } else {
  152.       frame.pack();
  153.     }
  154.     frame.setResizable(resizeableFrame);
  155.    
  156.     if (fullScreen) {
  157.       // After the pack(), the screen bounds are gonna be 0s
  158.       frame.setBounds(fullScreenRect);
  159.       applet.setBounds((fullScreenRect.width - applet.width) / 2,
  160.                        (fullScreenRect.height - applet.height) / 2,
  161.                        applet.width, applet.height);
  162.     } else {
  163.       Insets insets = frame.getInsets();
  164.  
  165.       int windowW = applet.width + insets.left + insets.right;
  166.       int windowH = applet.height + insets.top + insets.bottom;
  167.       int locationX = 100;
  168.       int locationY = 100;
  169.      
  170.       frame.setSize(windowW, windowH);
  171.       frame.setLocation(locationX, locationY);
  172.      
  173.       int usableWindowH = windowH - insets.top - insets.bottom;
  174.       applet.setBounds((windowW - width)/2, insets.top + (usableWindowH - height)/2, width, height);      
  175.     }
  176.    
  177.     frame.add(this);
  178.     frame.addWindowListener(new WindowAdapter() {
  179.       public void windowClosing(WindowEvent e) {
  180.           System.exit(0);
  181.       }
  182.     });    
  183.    
  184.     frame.setVisible(true);
  185.  
  186.     // Canvas setup ----------------------------------------------------------
  187.    
  188.     profile = GLProfile.getDefault();
  189.     capabilities = new GLCapabilities(profile);
  190.     capabilities.setSampleBuffers(false);
  191.    
  192.     window = GLWindow.create(capabilities);
  193.     canvas = new NewtCanvasAWT(window);
  194.    
  195.     this.setLayout(new BorderLayout());
  196.     this.add(canvas, BorderLayout.CENTER);
  197.     canvas.addMouseMotionListener(this);
  198.     canvas.addKeyListener(this);
  199.    
  200.     // Setting up animation
  201.     listener = new SimpleListener();
  202.     window.addGLEventListener(listener);    
  203.     if (useAnimator) {
  204.       animator = new CustomAnimator(window);
  205.       animator.start();
  206.     }
  207.     initialized = true;    
  208.   }
  209.  
  210.   void restart() {
  211.     System.out.println("Restarting surface...");
  212.    
  213.     // Stopping animation, removing current canvas.
  214.     animator.stop();
  215.     animator.remove(window);    
  216.     window.removeGLEventListener(listener);
  217.     this.remove(canvas);    
  218.        
  219.     capabilities = new GLCapabilities(profile);
  220.     capabilities.setSampleBuffers(true);
  221.     capabilities.setNumSamples(numSamples);
  222.    
  223.     window = GLWindow.create(capabilities);
  224.     canvas = new NewtCanvasAWT(window);
  225.    
  226.     // Setting up animation again
  227.     this.setLayout(new BorderLayout());
  228.     this.add(canvas, BorderLayout.CENTER);
  229.     canvas.addMouseMotionListener(this);
  230.     canvas.addKeyListener(this);
  231.    
  232.     window.addGLEventListener(listener);
  233.     if (useAnimator) {
  234.       animator.add(window);
  235.       animator.start();
  236.     }
  237.    
  238.     setFramerate = false;
  239.     restarted = true;
  240.    
  241.     System.out.println("Done");
  242.   }
  243.  
  244.   void draw(GL2 gl) {
  245.     frame.setTitle("frame " + frameCount);  
  246.    
  247.     if (printThreadInfo) System.out.println("Current thread at draw(): " + Thread.currentThread());          
  248.      
  249.     if (OPENGL_VENDOR == null) {
  250.       OPENGL_VENDOR     = gl.glGetString(GL.GL_VENDOR);  
  251.       OPENGL_RENDERER   = gl.glGetString(GL.GL_RENDERER);
  252.       OPENGL_VERSION    = gl.glGetString(GL.GL_VERSION);    
  253.       OPENGL_EXTENSIONS = gl.glGetString(GL.GL_EXTENSIONS);
  254.       System.out.println(OPENGL_VENDOR);
  255.       System.out.println(OPENGL_RENDERER);
  256.       System.out.println(OPENGL_VERSION);
  257.       System.out.println(OPENGL_EXTENSIONS);
  258.      
  259.       int[] temp = { 0 };
  260.       gl.glGetIntegerv(GL2.GL_MAX_SAMPLES, temp, 0);
  261.       System.out.println("Maximum number of samples supported by the hardware: " + temp[0]);
  262.     }
  263.    
  264.     if (currentSamples == -1) {
  265.       int[] temp = { 0 };
  266.       gl.glGetIntegerv(GL.GL_SAMPLES, temp, 0);
  267.       currentSamples = temp[0];
  268.       if (numSamples != currentSamples) {
  269.         System.err.println("Requested sampling level " + numSamples + " not supported. Using " + currentSamples + " samples instead.");
  270.       }
  271.     }
  272.    
  273.     if (!setFramerate) {      
  274.       if (60 < frameRate) {
  275.         // Disables vsync
  276.         gl.setSwapInterval(0);  
  277.       } else if (30 < frameRate) {        
  278.         gl.setSwapInterval(1);
  279.       } else {
  280.         gl.setSwapInterval(2);
  281.       }      
  282.       setFramerate = true;      
  283.     }
  284.    
  285.     if (restarted) {
  286.       int[] temp = { 0 };
  287.       gl.glGetIntegerv(GL.GL_SAMPLES, temp, 0);    
  288.       if (numSamples != temp[0]) {
  289.         System.err.println("Multisampling level requested " + numSamples + " not supported. Using " + temp[0] + " samples instead.");
  290.       }    
  291.     }
  292.        
  293.     gl.glClearColor(0, 0, 0, 1);
  294.     gl.glClear(GL.GL_COLOR_BUFFER_BIT);
  295.    
  296.     theta += 0.01;
  297.     s = Math.sin(theta);
  298.     c = Math.cos(theta);      
  299.    
  300.     gl.glBegin(GL.GL_TRIANGLES);
  301.     gl.glColor3f(1, 0, 0);
  302.     gl.glVertex2d(-c, -c);
  303.     gl.glColor3f(0, 1, 0);
  304.     gl.glVertex2d(0, c);
  305.     gl.glColor3f(0, 0, 1);
  306.     gl.glVertex2d(s, -s);
  307.     gl.glEnd();    
  308.    
  309.     gl.glFlush();
  310.    
  311.     fcount += 1;
  312.     int m = (int) (System.currentTimeMillis() - millisOffset);
  313.     if (m - lastm > 1000 * fint) {
  314.       frate = (float)(fcount) / fint;
  315.       fcount = 0;
  316.       lastm = m;
  317.       System.err.println("fps: " + frate);
  318.     }    
  319.   }
  320.  
  321.   void clock() {
  322.     long afterTime = System.nanoTime();
  323.     long timeDiff = afterTime - beforeTime;
  324.     long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime;
  325.  
  326.     if (sleepTime > 0) {  // some time left in this cycle
  327.       try {
  328.         Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L));
  329.       } catch (InterruptedException ex) { }
  330.  
  331.       overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
  332.  
  333.     } else {    // sleepTime <= 0; the frame took longer than the period
  334.       overSleepTime = 0L;
  335.     }
  336.  
  337.     beforeTime = System.nanoTime();    
  338.   }  
  339.  
  340.   class SimpleListener implements GLEventListener {
  341.     @Override
  342.     public void display(GLAutoDrawable drawable) {
  343.       draw(drawable.getGL().getGL2());
  344.     }
  345.  
  346.     @Override
  347.     public void dispose(GLAutoDrawable drawable) { }
  348.  
  349.     @Override
  350.     public void init(GLAutoDrawable drawable) { }
  351.  
  352.     @Override
  353.     public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { }    
  354.   }
  355.  
  356.   public void mouseDragged(MouseEvent ev) {
  357.     if (printEventInfo) {
  358.       System.err.println("Mouse dragged event: " + ev);
  359.     }        
  360.   }
  361.  
  362.   public void mouseMoved(MouseEvent ev) {
  363.     if (printEventInfo) {
  364.       System.err.println("Mouse dragged event: " + ev);
  365.     }    
  366.   }    
  367.  
  368.   public void keyPressed(KeyEvent ev) {
  369.     if (printEventInfo) {
  370.       System.err.println("Key pressed event: " + ev);
  371.     }
  372.   }
  373.  
  374.   public void keyReleased(KeyEvent ev) {
  375.     if (printEventInfo) {
  376.       System.err.println("Key released event: " + ev);
  377.     }  
  378.   }
  379.  
  380.   public void keyTyped(KeyEvent ev) {
  381.     if (printEventInfo) {
  382.       System.err.println("Key typed event: " + ev);
  383.     }  
  384.   }  
  385.  
  386.   public static void main(String[] args) {
  387.     MiniPApplet mini;
  388.     try {
  389.       Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(MiniPApplet.class.getName());
  390.       mini = (MiniPApplet) c.newInstance();
  391.     } catch (Exception e) {
  392.       throw new RuntimeException(e);
  393.     }    
  394.     if (mini != null) {
  395.       mini.run();
  396.     }
  397.   }      
  398.  
  399.   /** An Animator subclass which renders one frame at the time
  400.    *  upon calls to the requestRender() method.
  401.    **/
  402.   public class CustomAnimator extends AnimatorBase {    
  403.       private Timer timer = null;
  404.       private TimerTask task = null;
  405.       private volatile boolean shouldRun;
  406.  
  407.       protected String getBaseName(String prefix) {
  408.           return "Custom" + prefix + "Animator" ;
  409.       }
  410.  
  411.       /** Creates an CustomAnimator with an initial drawable to
  412.        * animate. */
  413.       public CustomAnimator(GLAutoDrawable drawable) {
  414.           if (drawable != null) {
  415.               add(drawable);
  416.           }
  417.       }
  418.  
  419.       public synchronized void requestRender() {
  420.           shouldRun = true;
  421.       }
  422.  
  423.       public final boolean isStarted() {
  424.           stateSync.lock();
  425.           try {
  426.               return (timer != null);
  427.           } finally {
  428.               stateSync.unlock();
  429.           }
  430.       }
  431.  
  432.       public final boolean isAnimating() {
  433.           stateSync.lock();
  434.           try {
  435.               return (timer != null) && (task != null);
  436.           } finally {
  437.               stateSync.unlock();
  438.           }
  439.       }
  440.  
  441.       private void startTask() {
  442.           if(null != task) {
  443.               return;
  444.           }
  445.          
  446.           task = new TimerTask() {
  447.               private boolean firstRun = true;
  448.               public void run() {
  449.                   if (firstRun) {
  450.                     Thread.currentThread().setName("OPENGL");
  451.                     firstRun = false;
  452.                   }
  453.                   if(CustomAnimator.this.shouldRun) {
  454.                      CustomAnimator.this.animThread = Thread.currentThread();
  455.                       // display impl. uses synchronized block on the animator instance
  456.                       display();                
  457.                       synchronized (this) {
  458.                         // done with current frame.
  459.                         shouldRun = false;
  460.                       }                    
  461.                   }
  462.               }
  463.           };
  464.  
  465.           fpsCounter.resetFPSCounter();
  466.           shouldRun = false;
  467.          
  468.           timer.schedule(task, 0, 1);
  469.       }
  470.      
  471.       public synchronized boolean  start() {
  472.           if (timer != null) {
  473.               return false;
  474.           }
  475.           stateSync.lock();
  476.           try {
  477.               timer = new Timer();
  478.               startTask();
  479.           } finally {
  480.               stateSync.unlock();
  481.           }
  482.           return true;
  483.       }
  484.  
  485.       /** Stops this CustomAnimator. */
  486.       public synchronized boolean stop() {
  487.           if (timer == null) {
  488.               return false;
  489.           }
  490.           stateSync.lock();
  491.           try {
  492.               shouldRun = false;
  493.               if(null != task) {
  494.                   task.cancel();
  495.                   task = null;
  496.               }
  497.               if(null != timer) {
  498.                   timer.cancel();
  499.                   timer = null;
  500.               }
  501.               animThread = null;
  502.               try {
  503.                   Thread.sleep(20); // ~ 1/60 hz wait, since we can't ctrl stopped threads
  504.               } catch (InterruptedException e) { }
  505.           } finally {
  506.               stateSync.unlock();
  507.           }
  508.           return true;
  509.       }
  510.      
  511.       public final boolean isPaused() { return false; }
  512.       public synchronized boolean resume() { return false; }
  513.       public synchronized boolean pause() { return false; }    
  514.   }
  515. }
Advertisement
Add Comment
Please, Sign In to add comment