#java #jogl
#java #jogl
Вопрос:
Я только что написал простую анимацию на JOGL: 6-цветной куб вращается вокруг оси y. Но, похоже, у моей анимации есть небольшое решение для ускорения: иногда она ускоряется, а иногда замедляется, хотя я просто вызываю glRotate() с переменной с плавающей запятой, которую я увеличиваю при каждом вызове дисплея (мой код ниже).
- Мой процессор — pentium dual core t3400
- Моя операционная система — Xubuntu 11.04 32 бит
- Моя графическая карта — ATI Radeon HD4330, и я установил недавний проприетарный драйвер: 11.6 (загруженный на веб-сайте AMD, а не в ubuntu Software manager)
В Eclipse EDI (я использую Indigo 3.7.0), вот как я настроил свою пользовательскую библиотеку :
- Я загрузил бета-версию JOGL 2.0 23 (с 2011 года, 03 марта) для i586 linux
- В пользовательской библиотеке я импортировал следующие банки: 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;
}
Я думаю, это может быть связано с тем, что я импортировал несовместимые банки в пользовательскую библиотеку, созданную для моих проектов JOGL eclipse, но я не уверен.
Заранее спасибо
(Название ArcBall experiment кажется неуместным, и это правильно: это вращение куба — просто этап для меня, чтобы снова вспомнить программирование JOGL, прежде чем переходить к реализации arcball.)
Комментарии:
1. Наконец, кажется, что проблему можно решить, введя значение FPS: я заменил Animator на FPSAnimator => Вращение куба больше не было «глючным».
2. Хорошая работа, Лоран БЕРНАБЕ. Не могли бы вы сами опубликовать ответ на вопрос, а затем принять этот ответ, чтобы мы могли закрыть этот вопрос? Кроме того, вам необходимо принять ответы на предыдущие вопросы, если они решают вашу проблему.
Ответ №1:
Наконец-то я решил проблему Я изменил экземпляр animator на 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;
}