JMenus вызвал мерцание холста JOGL GLCanvas - PullRequest
4 голосов
/ 06 января 2009

Нажатие на опции JMenu вызывает мерцание моего JOGL GLCanvas.

В JMenu для setDefaultLightWeightPopupEnabled установлено значение false. Я не хочу использовать JGLPanel, потому что он работает медленнее (приложение должно работать в полноэкранном режиме).

Интересно, мерцание прекращается, если я установил sun.java2d.opengl = true в командной строке. Однако тот факт, что Sun не включает это по умолчанию, заставляет меня беспокоиться, что я бы рискнул, если у моих пользователей возникнут проблемы с несовместимостью оборудования.

Видят ли другие люди мерцание с кодом ниже при нажатии на меню?

Я пробовал все виды вещей, например, игру с опциями двойной буферизации для JFrame и для canvas, но безуспешно заставлял холст не мерцать.

Кто-нибудь может заставить это не мерцать при просмотре пунктов меню?

Спасибо!

* 1015 Дан *

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 ]

2 голосов
/ 06 февраля 2009

Это вызвано тем, что AWT стирает GLCanvas каждый раз перед тем, как JOGL перерисовывает его, и его можно обойти, вставив следующую строку в метод main ():

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

Хотя это решает данную проблему, побочные эффекты возможны в других областях приложения, таких как видимые артефакты при изменении размера окна. Я использую это во всех моих приложениях JOGL, хотя без проблем.

2 голосов
/ 06 января 2009

Попробуйте вызвать createBufferStrategy(2); в конструкторе JFrame. Это должно включить двойную буферизацию в JFrame.

0 голосов
/ 07 января 2009

Возможно, вы захотите добавить аниматор . Холст может мерцать, потому что JFrame обновляет его недостаточно быстро.

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