JOGL: моя скорость вращения куба не постоянна - PullRequest
0 голосов
/ 12 октября 2011

Я только что написал простую анимацию в JOGL: 6-цветный куб вращается вокруг оси Y. Но, похоже, у моей анимации есть небольшой обходной путь: иногда он ускоряется, а иногда замедляется, хотя я просто вызываю glRotate () с переменной float, которую я увеличиваю при каждом вызове дисплея (мой код ниже).

  • Мой процессор - двухъядерный процессор Pentium T3400
  • Моя операционная система - Xubuntu 11.04 32 бита
  • Моя графическая карта ATI Radeon HD4330, и я установил последний проприетарный драйвер: 11.6 (загружается на сайте AMD, а не в диспетчере программного обеспечения Ubuntu)

В Eclipse EDI (я использую Indigo 3.7.0), вот как я настроил свою пользовательскую библиотеку:

  • Я скачал JOGL 2.0 beta 23 (с 2011 года, 3 марта) для i586 linux
  • В пользовательской библиотеке я импортировал следующие jar-файлы: newt.all.jar, nativewindow.all.jar, jogl.all.jar, gluegen-rt.jar
  • Все импортированные файлы jar ссылаются на подпапку lib несжатого архива jogl: где находятся все файлы * .so

Вот мои три класса.

ArcballExperiment.java

package com.gmail.bernabe.laurent.jogl.arcball_experiment;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

import com.jogamp.opengl.util.Animator;

public class ArcBallExperiment extends JFrame {

    public ArcBallExperiment(){
        setTitle("ArcBall Experimentation");
        setSize(500, 500);
        setLocationRelativeTo(null);

        GLCanvas glCanvas = new GLCanvas();
        TheGLEventListener glEventListener = new TheGLEventListener();
        glCanvas.addGLEventListener(glEventListener);
        add(glCanvas);

        final Animator animator = new Animator(glCanvas);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                animator.stop();
                System.exit(0);
            }


        });

        animator.start();
    }

    public static void main(String[] args) {
        new ArcBallExperiment().setVisible(true);
    }

    private static final long serialVersionUID = 1L;

}

Cube.java:

package com.gmail.bernabe.laurent.jogl.arcball_experiment;

import javax.media.opengl.GL2;

public class Cube {

    /**
     * Draws a cube in a GL2 context
     * @param gl - GL2 - GL2 context
     */
    public static void draw(GL2 gl){
        gl.glBegin(GL2.GL_QUADS);

            // front : blue
            gl.glColor3f(0.0f, 0.0f, 1.0f);
            gl.glVertex3f(-0.5f, +0.5f, +0.5f);
            gl.glVertex3f(-0.5f, -0.5f, +0.5f);
            gl.glVertex3f(+0.5f, -0.5f, +0.5f);
            gl.glVertex3f(+0.5f, +0.5f, +0.5f);

            // back : green
            gl.glColor3f(0.0f, 1.0f, 0.0f);
            gl.glVertex3f(+0.5f, -0.5f, -0.5f);
            gl.glVertex3f(+0.5f, +0.5f, -0.5f);
            gl.glVertex3f(-0.5f, +0.5f, -0.5f);
            gl.glVertex3f(-0.5f, -0.5f, -0.5f);

            // left : red
            gl.glColor3f(1.0f, 0.0f, 0.0f);
            gl.glVertex3f(-0.5f, +0.5f, +0.5f);
            gl.glVertex3f(-0.5f, +0.5f, -0.5f);
            gl.glVertex3f(-0.5f, -0.5f, -0.5f);
            gl.glVertex3f(-0.5f, -0.5f, +0.5f);

            // right : orange
            gl.glColor3f(1.0f, 0.4f, 0.0f);
            gl.glVertex3f(+0.5f, +0.5f, -0.5f);
            gl.glVertex3f(+0.5f, +0.5f, +0.5f);
            gl.glVertex3f(+0.5f, -0.5f, +0.5f);
            gl.glVertex3f(+0.5f, -0.5f, -0.5f);

            // top : white
            gl.glColor3f(1.0f, 1.0f, 1.0f);
            gl.glVertex3f(+0.5f, +0.5f, +0.5f);
            gl.glVertex3f(-0.5f, +0.5f, +0.5f);
            gl.glVertex3f(-0.5f, +0.5f, -0.5f);
            gl.glVertex3f(+0.5f, +0.5f, -0.5f);

            // bottom : yellow
            gl.glColor3f(1.0f, 1.0f, 0.0f);
            gl.glVertex3f(+0.5f, -0.5f, +0.5f);
            gl.glVertex3f(+0.5f, -0.5f, -0.5f);
            gl.glVertex3f(-0.5f, -0.5f, -0.5f);
            gl.glVertex3f(-0.5f, -0.5f, +0.5f);

        gl.glEnd();
    }

}

TheGLEventListener.java:

package com.gmail.bernabe.laurent.jogl.arcball_experiment;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.gl2.GLUgl2;

public class TheGLEventListener implements GLEventListener {

    @Override
    public void display(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();

        glu.gluLookAt(
                0f, 0f, 3f,
                0f, 0f, 0f,
                0f, 1f, 0f
        );

        gl.glRotatef(rotationAngle, 0f, 1f, 0f);
        Cube.draw(gl);

        rotationAngle += 0.3f;
        if (rotationAngle >= 360f)
            rotationAngle %= 360f;
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
        // TODO Auto-generated method stub

    }

    @Override
    public void init(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glEnable(GL2.GL_DEPTH_TEST);
        gl.glDepthFunc(GL2.GL_LEQUAL);
        gl.glClearDepthf(1.0f);
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width,
            int height) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glViewport(x, y, width, height);

        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(60.0f, (float) width/height, 1f, 10f);

        gl.glMatrixMode(GL2.GL_MODELVIEW);
    }

    private GLUgl2 glu = new GLUgl2();
    private float rotationAngle = 0f;

}

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

Заранее спасибо

(Эксперимент по названию ArcBall кажется неподходящим, и это правильно: вращение куба - это фаза для меня, чтобы снова вспомнить программирование JOGL перед тем, как перейти к реализации arcball.)

1 Ответ

3 голосов
/ 23 мая 2012

Наконец я решил проблему :) Я изменил экземпляр аниматора на FPSAnimator вместо Animator, чтобы сохранить постоянный FPS.Существует только один класс для обновления: ArcBallExperiment.java

package com.gmail.bernabe.laurent.jogl.arcball_experiment;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;

public class ArcBallExperiment extends JFrame {

    public ArcBallExperiment(){
        setTitle("ArcBall Experimentation");
        setSize(500, 500);
        setLocationRelativeTo(null);

        GLCanvas glCanvas = new GLCanvas();
        TheGLEventListener glEventListener = new TheGLEventListener();
        glCanvas.addGLEventListener(glEventListener);
        add(glCanvas);

        /*
         *  Here I limit the FPS to a quite lower value than default,
         *  thanks to the FPSAnimator class : 180 FPS here.
         *  That way, cube rotation speed will really be constant
         */
        final FPSAnimator animator = new FPSAnimator(glCanvas, 180);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                animator.stop();
                System.exit(0);
            }


        });

        animator.start();
    }

    public static void main(String[] args) {
        new ArcBallExperiment().setVisible(true);
    }

    private static final long serialVersionUID = 1L;

}
...