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();
}
}
}