JMenus вызывал мерцание холста JOGL GLCanvas

При нажатии на параметры 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) {
        }
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
2 750
3

Ответы 3

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

Вау, даже не слышал об этом! К сожалению, мерцанию это не помогло. Есть другие идеи?

user41762 06.01.2009 07:59

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

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

Нет, только мерцает, когда меню выбрано / отменено. Это не зависит от аниматора и имеет значение только тогда, когда вы показываете разные изображения с течением времени.

user41762 09.01.2009 09:25

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

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

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

Если вы не хотите делать это на уровне приложения, возможно, вам удастся избежать очистки области просмотра в коде рисования JOGL.

DJClayworth 17.02.2011 19:00

Другие вопросы по теме