3D-приложение JavaFX, работающее со скоростью 30 кадров в секунду - PullRequest
0 голосов
/ 23 февраля 2019

Я разрабатываю приложение в Gluon.На данный момент это простой куб.

Я использую AnimationTimer для обработки игрового цикла.Когда таймер анимации работает, я сравниваю наносекунды системы, чтобы вычислить время дельты кадров.Я отображаю fps через: 1 / DeltaTime.

На рабочем столе fpsLabel постоянно отображает 60 fps.На мобильный, однако, я получаю только 30 кадров в секунду.Я заметил, что консоль иногда пишет setSwapInterval (1), который, как я знаю, является настройкой VSYNC в OpenGL.Действительно ли мой телефон не достигает цели 60 кадров в секунду и не подавляется?Может быть полезно иметь более прямую поддержку OpenGLES с Gluon.

// Content pane
StackPane content = new StackPane();
content.setAlignment(Pos.TOP_LEFT);
content.setPadding(new Insets(8));
content.setPrefSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
this.setCenter(content);

// Holds 3d objects
Group root3D = new Group();

// Scene to view the 3d objects
SubScene subScene = new SubScene(root3D, MobileApplication.getInstance().getScreenWidth(), MobileApplication.getInstance().getScreenHeight(), true, SceneAntialiasing.DISABLED);
content.getChildren().add(subScene);

// Create camera
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setNearClip(0.1);
camera.setFarClip(1000.0);
camera.setTranslateZ(-64);
root3D.getChildren().add(camera);

// Put camera in scene
Platform.runLater(()->{
    subScene.setCamera(camera);
    subScene.widthProperty().bind(MobileApplication.getInstance().getView().widthProperty());
    subScene.heightProperty().bind(MobileApplication.getInstance().getView().heightProperty());
});

// Put box in scene
Box box = new Box(8, 8, 8);
Rotate rxBox = new Rotate(0, 0, 0, 0, Rotate.X_AXIS);
boxRot = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
rxBox.setAngle(30);
boxRot.setAngle(50);
box.getTransforms().addAll(rxBox, boxRot);
root3D.getChildren().add(box);

// FPS Label
fpsLabel = new Label("Fps 60");
content.getChildren().add(fpsLabel);

1 Ответ

0 голосов
/ 24 февраля 2019

В iOS CADisplayLink - это эквивалент AnimationTimer :

Объект таймера, который позволяет вашему приложению синхронизировать рисунок с частотой обновления экрана

Если вы проверите исходный код в JDK 1.8, вы найдете в графическом модуле под native-glass для iOS реализацию этого таймера:

displayLink = [[UIScreen mainScreen] displayLinkWithTarget:[GlassTimer getDelegate]
                                                                  selector:@selector(displayLinkUpdate:)];
// 1 is 60hz, 2 is 30 Hz, 3 is 20 Hz ...
[displayLink setFrameInterval:2];

Как вы можете видеть, FPS, который вы можете получить, ограничен по дизайну .

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

Я изменил кадрс интервалом до 1 (60 Гц), собрал SDK для iOS и успешно протестировал его на моем iPhone:

image

Однако, конечно, это не то, как его нужно изменять,Этот параметр должен быть как-то открыт для разработчика, и какой-то API-интерфейс будет желательным.

Поскольку этот предел применяется также к OpenJFX JavaFX 11 кодовая база , я бы предложил подать заявку выпуск , поэтому его можно правильно изменить.

...