JMenus导致JOGL GLCanvas画布闪烁

时间:2009-01-05 23:32:45

标签: java opengl jogl

单击JMenu选项会导致我的JOGL GLCanvas闪烁。

JMenu将setDefaultLightWeightPopupEnabled设置为false。我不想使用JGLPanel,因为它运行速度较慢(应用程序需要以全屏模式运行)。

有趣的是,如果我在命令行上设置sun.java2d.opengl = true,闪烁就会停止。但是,sun默认情况下不启用此功能这一事实让我担心我的用户会遇到硬件兼容性问题的风险。

点击菜单时,其他人是否会看到闪烁的代码?

我尝试了各种各样的东西,比如玩JFrame和画布的双缓冲选项,但没有运气让画布不闪烁。

当看到菜单选项时,是否有人可以避免闪烁?

谢谢!

-Dan

import javax.media.opengl.*;
import javax.swing.*;

public class FlickerTest extends JFrame {
    private GLCapabilities m_caps = new GLCapabilities();

    public FlickerTest() {
        super("FlickerTest");

        GLCanvas canvas = new GLCanvas(m_caps);
        add( canvas );
        canvas.addGLEventListener( new MyGLEventListener() );

        setSize( 640, 480 );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        // false lets the JMenuBar appear on top of the remote image openGL canvas
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);

        setJMenuBar( getMyMenuBar() );
        setVisible( true );
    }

    public static void main(String[] args) {
        new FlickerTest();
    }

    private static JMenuBar getMyMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        JMenuItem quitMenuItem = new JMenuItem( "Quit" );
        JMenuItem doSomething = new JMenuItem("Do Something");
        fileMenu.add( quitMenuItem );
        fileMenu.add( doSomething );

        menuBar.add( fileMenu );
        return menuBar;
    }

    private class MyGLEventListener implements GLEventListener {
        private MyGLEventListener() {
        }

        public void init(GLAutoDrawable drawable) {
            GL gl = drawable.getGL();
            gl.glClearColor(1,1,0,0);
            gl.glBlendFunc(GL.GL_ONE,GL.GL_ONE);
            gl.glEnable(GL.GL_BLEND);
        }

        public synchronized void display( GLAutoDrawable p_glAutoDrawable ) {
            GL gl = p_glAutoDrawable.getGL();

            gl.glClear(GL.GL_COLOR_BUFFER_BIT);

            gl.glColor3f(0,0,1);
            gl.glRectf(-.5f,-.5f,.5f,.5f);
            gl.glFlush();
        }

        public void reshape(GLAutoDrawable p_drawable, int x, int y, int w, int h) {
        }

        public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
        }
    }
}

3 个答案:

答案 0 :(得分:2)

尝试在JFrame构造函数中调用createBufferStrategy(2);。这应该在JFrame中启用双缓冲。

答案 1 :(得分:2)

这是由于每次JOGL重新绘制之前AWT擦除GLCanvas引起的,并且可以通过在main()方法中插入以下行来解决这个问题:

System.setProperty("sun.awt.noerasebackground", "true");

虽然这解决了给定的问题,但是在应用程序的其他区域中可能出现副作用,例如在调整窗口大小时可见的伪像。我在所有JOGL应用程序中都使用它,但没有任何问题。

答案 2 :(得分:0)

您可能想要添加animator。画布可能会闪烁,因为JFrame没有足够快地刷新它。

FPSAnimator = new FPSAnimator(GLCanvas,int TARGET_FPS, boolean);