Bug 155

Summary: resizing jsplitpane leaves dirty zone on linux using animator
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: VERIFIED FIXED    
Severity: normal    
Priority: P3    
Version: 1   
Hardware: All   
OS: linux   
Type: DEFECT SCM Refs:
Workaround: ---

Description Sven Gothel 2010-03-24 07:47:44 CET


---- Reported by c_lilian 2005-04-08 09:23:46 ----

When using nested JSplitPanes on linux, with a GLCanvas, repaint problems appear
when dragging the splits resizers.

Problem desapears is jogl.1thread=false or if I insert a Thread.yield into the
display loop of the animator class.

Here is a test case : try resizing the vertical dividers around the canvas,
dirty (gray) regions should appears between old and new divider position.

-------------------------- source code here

package test;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import net.java.games.jogl.Animator;
import net.java.games.jogl.GL;
import net.java.games.jogl.GLCanvas;
import net.java.games.jogl.GLCapabilities;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLDrawableFactory;
import net.java.games.jogl.GLEventListener;
import net.java.games.jogl.GLU;

/** Illustrates the repaint problem on linux.
 *
 * @author Lilian
 */
public class JOGLTestCase extends JFrame implements GLEventListener {
    
    JSplitPane splitH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    JSplitPane splitH2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    JSplitPane splitV = new JSplitPane(JSplitPane.VERTICAL_SPLIT);

    private float	xrot;
    private float	yrot;
    private float	zrot;
    
    public JOGLTestCase() {
        // run in EDT (see main())
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        getContentPane().add(splitH);
        splitH.setLeftComponent(splitV);
        splitH2.setRightComponent(new JButton("left"));
    
        splitV.setTopComponent(new JButton("top"));
        splitV.setBottomComponent(new JButton("bottom"));
        final GLCanvas canvas =
GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
        final Animator animator = new Animator(canvas);
        
        JPanel canvasPanel = new JPanel(new BorderLayout()); // workaround
resize in split pane
        canvasPanel.add(canvas, BorderLayout.CENTER);
        canvasPanel.setMinimumSize(new Dimension(10,10));
        
        splitH.setRightComponent(splitH2);
        splitH2.setLeftComponent(canvasPanel);
        canvas.addGLEventListener(this);
        setSize(800,600);
        validate();
        setVisible(true);                
    
        addWindowListener(new WindowAdapter(){
           public void windowOpened(WindowEvent e){
               splitH.setDividerLocation(300);
               splitH2.setDividerLocation(300);
               splitV.setDividerLocation(200);
               canvas.validate();
               animator.start();
           }
           public void windowClosing(WindowEvent e){
               animator.stop();
               System.exit(0);
           }
        });
        
    }


    public void init(GLDrawable drawable) {
        final GL gl = drawable.getGL();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        gl.glEnable(GL.GL_DEPTH_TEST);
    }

    public void display(GLDrawable drawable) {
        // a basic rotating cube
        final GL gl = drawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity(); // Reset The View
        gl.glTranslatef(0.0f, 0.0f, -5.0f);
        
        gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
        
        gl.glBegin(GL.GL_QUADS);
        // Front Face
        gl.glColor3f(0.5f, 0,0);
        gl.glVertex3f( -1.0f, -1.0f, 1.0f);
        gl.glColor3f(1, 0,0);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glColor3f(1, 1,0);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glColor3f(1, 0,1);
        gl.glVertex3f( -1.0f, 1.0f, 1.0f);
        // Back Face
        gl.glColor3f(0, 1,0);
        gl.glVertex3f( -1.0f, -1.0f, -1.0f);
        gl.glColor3f(0, 1,1);
        gl.glVertex3f( -1.0f, 1.0f, -1.0f);
        gl.glColor3f(0, 0,1);
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glColor3f(1, 0,1);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        // Top Face
        gl.glVertex3f( -1.0f, 1.0f, -1.0f);
        gl.glVertex3f( -1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        // Bottom Face
        gl.glVertex3f( -1.0f, -1.0f, -1.0f);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glVertex3f( -1.0f, -1.0f, 1.0f);
        // Right face
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        // Left Face
        gl.glVertex3f( -1.0f, -1.0f, -1.0f);
        gl.glVertex3f( -1.0f, -1.0f, 1.0f);
        gl.glVertex3f( -1.0f, 1.0f, 1.0f);
        gl.glVertex3f( -1.0f, 1.0f, -1.0f);
        gl.glEnd();
        
        xrot += 0.3f;
        yrot += 0.2f;
        zrot += 0.4f;
    }

    public void reshape(GLDrawable drawable, int x, int y, int width, int height) {
        final GL gl = drawable.getGL();
        final GLU glu = drawable.getGLU();
        
        if (height <= 0) // avoid a divide by zero error!
            height = 1;
        final float h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
    
    public void displayChanged(GLDrawable drawable, boolean modeChanged,
            boolean deviceChanged) {
    }
    
    public static void main(String [] args){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                new JOGLTestCase(); // in EDT
            }
        });
        
    }
}



---- Additional Comments From kbr 2005-05-06 17:52:14 ----

This is happening because the Animator is swamping the CPU and preventing the
AWT components from rendering. A future version of the Animator will have an
option for throttling its CPU usage. As a workaround, as indicated in the
description, put a Thread.yield(), Thread.sleep(), or Object.wait() call in your
GLEventListener.display() method.




---- Additional Comments From kbr 2006-01-11 00:26:01 ----

The current Animator in com.sun.opengl.utils contains a yield() in the animation
loop by default, preventing this problem. There is a way to override this to
revert back to the previous behavior. There is also a new FPSAnimator in the
com.sun.opengl.utils which attempts to provide better control over the frame
rate. Closing this bug as fixed.




--- Bug imported by sgothel@jausoft.com 2010-03-24 07:47 EDT  ---

This bug was previously known as _bug_ 155 at https://jogl.dev.java.net/bugs/show_bug.cgi?id=155