Login  Register

Re: Multiple GLCanvas/FPSAnimator Hang

Posted by sfriend on Nov 20, 2013; 9:45pm
URL: https://forum.jogamp.org/Multiple-GLCanvas-FPSAnimator-Hang-tp4030581p4030672.html

Below is the attempt to mimic the hang, it opens multiple JFrame/JSplitPane/JPanel/GLCanvas with FPSAnimator. This is exactly what my large app that's failing is doing, the timing is different of course, the window are open by a user. Do you see any problems with the JOGL concept we are using?

Thanks Again





package examples;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;
import examples.OrionAnimator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import jogamp.opengl.GLWorkerThread;

public class JoglTest
{
  private static GLOffscreenAutoDrawable glad = null;

  private static int size = 200;

  public static void main( String[] args )
  {
    GLProfile.initSingleton();
    GLWorkerThread.start();
    /*
     * Create and display the form
     */
    java.awt.EventQueue.invokeLater( new Runnable()
    {
      public void run()
      {
        JoglTest test = new JoglTest();
        test.Run();
      }
    } );

  }

  public JoglTest()
  {
  }

  public void Run()
  {
    Random rand = new Random();
    OrionAnimator.getInstance().init();

    OrionAnimator.getInstance().start();

    PrintStream out;
    try
    {
      out = new PrintStream( new FileOutputStream( "output.txt" ) );
      System.setOut( out );
      System.setErr( out );
    }
    catch( FileNotFoundException ex )
    {
      Logger.getLogger( JoglTest.class.getName() ).log( Level.SEVERE, null, ex );
    }

    for( int i = 0; i < 10; i++ )
    {
      final int x = ( i % 5 ) * size;
      final int y = ( i / 5 ) * size;

      // set up frame and tabs
      JFrame frame = new JFrame();


      JPanel mainPanel = new JPanel();

      mainPanel.setLayout( new BorderLayout() );

      JPanel rightpanel = new JPanel();
      rightpanel.setBorder( BorderFactory.createLineBorder( Color.black ) );

      rightpanel.setSize( size, size );
      JSplitPane splitPaneMap = new javax.swing.JSplitPane();

      rightpanel.setSize( size, size );
      splitPaneMap.setRightComponent( rightpanel );

      mainPanel.add( splitPaneMap, java.awt.BorderLayout.CENTER );
      mainPanel.setSize( size, size );
      splitPaneMap.setDividerLocation( 50 );
      frame.setLayout( new BorderLayout() );
      frame.setContentPane( mainPanel );
      frame.setLocation( x, y );

      GLProfile profile = GLProfile.getDefault();
      GLCapabilities glCaps = new GLCapabilities( profile );
      glCaps.setPBuffer( true );
      if( glad == null )
      {
        glad = GLDrawableFactory.getFactory( profile ).createOffscreenAutoDrawable( GLDrawableFactory.getFactory( profile ).getDefaultDevice(),
                                                                                    glCaps,
                                                                                    new DefaultGLCapabilitiesChooser(),
                                                                                    1,
                                                                                    1 );
        glad.display();
      }

      glCaps = new GLCapabilities( profile );
      GLCanvas canvas = new GLCanvas( glCaps, new DefaultGLCapabilitiesChooser(), null );
      canvas.setSharedContext( glad.getContext() );
      canvas.addGLEventListener( new TestRenderer( new float[]
              {
                1f, 0f, 0f
              } ) );
      FPSAnimator animator = new FPSAnimator( canvas, 40 );


      canvas.setSize( size, size );
      rightpanel.add( canvas );

      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      frame.setSize( size, size );


      if( frame.getExtendedState() == Frame.ICONIFIED )
      {
        frame.setExtendedState( Frame.NORMAL );
      }
      frame.toFront();

      final Frame ff = frame;
      SwingUtilities.invokeLater( new Runnable()
      {
        @Override
        public void run()
        {
          ff.setVisible( true );
        }
      } );

      final FPSAnimator fa = animator;


      frame.addWindowListener( new WindowAdapter()
      {
        @Override
        public void windowOpened( WindowEvent evt )
        {
          fa.start();
        }
      } );
    }
  }

  private static class TestRenderer implements GLEventListener
  {

    private int textureId = -1;

    private float[] color;

    float spin = 0;

    public TestRenderer( float[] color )
    {
      this.color = color;
    }

    @Override
    public void display( GLAutoDrawable drawable )
    {
      GL2 gl = drawable.getGL().getGL2();

      // set custom background color to distinguish tabs
      gl.glClearColor( color[0], color[1], color[2], 1f );
      gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );

      gl.glEnable( GL.GL_TEXTURE_2D );
      gl.glBindTexture( GL.GL_TEXTURE_2D, textureId );

      // make this white so the texture appears correctly
      // if the texture wasn't shared properly, the quad will be all white
      gl.glColor4f( 1f, 1f, 1f, 1f );
      gl.glPushMatrix();
      gl.glRotatef( spin, 0.0f, 0.0f, 1.0f );


      gl.glBegin( GL2.GL_QUADS );
      gl.glVertex3f( -1f, 1f, 0f );
      gl.glTexCoord2f( 0f, 1f );
      gl.glVertex3f( -1f, -1f, 0f );
      gl.glTexCoord2f( 0f, 0f );
      gl.glVertex3f( 1f, -1f, 0f );
      gl.glTexCoord2f( 1f, 0f );
      gl.glVertex3f( 1f, 1f, 0f );
      gl.glTexCoord2f( 1f, 1f );
      gl.glEnd();

      gl.glDisable( GL.GL_TEXTURE_2D );
      gl.glBindTexture( GL.GL_TEXTURE_2D, 0 );
      spin += 1;
      while( spin > 360 )
      {
        spin -= 360;
      }
      gl.glPopMatrix();
    }

    @Override
    public void dispose( GLAutoDrawable drawable )
    {
      // do nothing
    }

    @Override
    public void init( GLAutoDrawable drawable )
    {
      GL2 gl = drawable.getGL().getGL2();
      System.out.println( "Initializing GLCanvas@" + Integer.toHexString( drawable.hashCode() ) );
      if( textureId < 0 )
      {
        int[] id = new int[ 1 ];
        gl.glGenTextures( 1, id, 0 );
        textureId = id[0];

        System.out.println( "Creating texture on GLCanvas@" + Integer.toHexString( drawable.hashCode() ) + " with ID=" + textureId );

        // fill up pixel image with a gradient pattern
        gl.glBindTexture( GL.GL_TEXTURE_2D, textureId );
        int width = 16;
        int height = 16;

        FloatBuffer data = ByteBuffer.allocateDirect( 4 * 3 * width * height ).order( ByteOrder.nativeOrder() ).asFloatBuffer();
        for( int y = 0; y < height; y++ )
        {
          for( int x = 0; x < width; x++ )
          {
            data.put( 3 * ( y * width + x ) + 0, x / (float)width );
            data.put( 3 * ( y * width + x ) + 1, y / (float)height );
            data.put( 3 * ( y * width + x ) + 2, 0f );
          }
        }

        gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, GL.GL_RGB, width, height, 0, GL.GL_RGB, GL.GL_FLOAT, data.rewind() );
        gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST );
        gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST );

        gl.glBindTexture( GL.GL_TEXTURE_2D, 0 );
      }
    }

    @Override
    public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height )
    {
      GL2 gl = drawable.getGL().getGL2();
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
      gl.glOrtho( -2, 2, -2, 2, -1, 1 );

      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
    }
  }
}