4

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

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

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

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

我已经尝试了各种方法,例如使用 JFrame 和画布的双缓冲选项,但没有让画布不闪烁的运气。

当查看菜单选项时,任何人都可以让它不闪烁吗?

谢谢!

-担

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) {
        }
    }
}
4

3 回答 3

2

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

于 2009-01-06T00:26:58.700 回答
2

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

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

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

于 2009-02-06T10:18:05.773 回答
0

您可能想要添加一个animator。画布可能会闪烁,因为 JFrame 刷新的速度不够快。

FPSAnimator = new FPSAnimator(GLCanvas,int TARGET_FPS, boolean);
于 2009-01-07T15:14:07.943 回答