本文介紹了JavaFX 8 Z緩沖區問題的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我的問題是JavaFX 3D中的Z-Buffer,它似乎不能在我的機器上按預期工作。
我了解以下問題:
Overlapping shapes
和
…Z Order…
但是,我確實啟用了Z緩沖區,并且節點仍然按照它們添加到場景圖的順序進行渲染。
可能我缺少某些依賴項或其他什么?
我正在發布代碼,希望有人能幫助我。我正在創建一個在橢圓路徑上圍繞另一個節點移動節點的過渡。
提前感謝您!
public class OrbitExp extends Application {
Group root = new Group();
Scene scene = new Scene(root, 800, 600, true, SceneAntialiasing.BALANCED);
PerspectiveCamera camera = new PerspectiveCamera();
@Override
public void start(Stage primaryStage) {
root.setDepthTest(DepthTest.ENABLE);
//Tried to set Depthtest explicitly. Assumed maybe it did not inherit:S
System.out.println(
"3D supported? " +
Platform.isSupported(ConditionalFeature.SCENE3D)
); // returns true
System.out.println("root z-buffer: " + root.getDepthTest());
initCamera();
Box
box1 = new Box(50,50,50),
box2 = new Box(10,10,10);
root.setTranslateX(scene.getWidth()/2);
root.setTranslateY(scene.getHeight()/2);
PhongMaterial
pmat = new PhongMaterial(Color.BLUE),
pmat2 = new PhongMaterial(Color.RED);
box1.setMaterial(pmat);
box2.setMaterial(pmat2);
scene.setFill(Color.LIGHTGREEN);
root.getChildren().addAll(box1,box2);
SequentialTransition sqt = orbit(box1, box2, 40, 40, Duration.seconds(3), 360);
sqt.play();
scene.setOnMouseClicked(click->{
Node node = (Node)(click.getPickResult().getIntersectedNode());
System.out.println("Tx: "+node.getTranslateX());
System.out.println("Ty: "+node.getTranslateY());
System.out.println("Tz: "+node.getTranslateZ());
});
// just for debugging, but coords does seem to be alright
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void initCamera() {
camera.setTranslateZ(-50);
camera.setTranslateY(20);
camera.setFarClip(5000);
camera.setNearClip(0);
scene.setCamera(camera);
}
SequentialTransition orbit(Node node1, Node node2,double a, double b, Duration totalDuration, int N) {
SequentialTransition sqt = new SequentialTransition();
Duration dur = new Duration(totalDuration.toMillis()*(1.0d/N));
node2.setTranslateX(a+node1.getTranslateX());
node2.setTranslateZ(node1.getTranslateZ());
for (int i = 1; i < N; i++) {
TranslateTransition tt = new TranslateTransition(dur, node2);
double
angle = i*(360.0d/N),
toX = (Math.cos(Math.toRadians(angle))*a)+node1.getTranslateX(),
toZ = (Math.sin(Math.toRadians(angle))*b)+node1.getTranslateZ();
tt.setToX(toX);
tt.setToZ(toZ);
tt.setInterpolator(Interpolator.LINEAR);
sqt.getChildren().add(tt);
System.out.println("angle = " + angle + "
angle in rads: " + Math.toRadians(angle) + "
toX = " + toX + "
toZ = " + toZ);
}
sqt.setCycleCount(Timeline.INDEFINITE);
return sqt;
}
}
順便說一下,這是我的第一篇帖子:)
推薦答案
如果使用矩形檢查您提供的link上的代碼,則深度緩沖區工作正常。
將矩形更改為使用3D框也有效。
問題是如何定義其中一個框與另一個框相關的旋轉,因此,我沒有像您那樣使用RotateTransition
或SequentialTransition
的SequentialTransition
,而是對紅色框應用了Rotate
變換,并在藍色框的中心設置了軸,并使用AnimationTimer
修改了旋轉角度以創建”環繞”效果。
您甚至可以在大盒子(從8u60開始)上使用透明度來查看其下面的小盒子。
private final Group shapes = new Group();
private long lastTimerCall;
private AnimationTimer timeline;
@Override
public void start(Stage stage) throws Exception {
Scene scene = new Scene(createRotatingShapes(), 400, 300,
true, SceneAntialiasing.BALANCED);
scene.setFill(Color.LIGHTGREEN);
final PerspectiveCamera camera = new PerspectiveCamera();
camera.setRotationAxis(Rotate.X_AXIS);
camera.setRotate(10);
camera.setTranslateZ(200);
scene.setCamera(camera);
stage.setScene(scene);
stage.show();
}
private Group createRotatingShapes() {
final Box box1 = new Box(50, 50, 50);
// Transparency in box1: last node of the group
box1.setMaterial(new PhongMaterial(Color.web("#0000FF80")));
box1.setTranslateZ(50);
final Box box2 = new Box(10, 10, 10);
box2.setMaterial(new PhongMaterial(Color.RED));
box2.setTranslateZ(-50);
shapes.getChildren().addAll(box2, box1);
shapes.setTranslateX(200);
shapes.setTranslateY(150);
rotateAroundYAxis(box2);
return shapes;
}
private int count = 0;
private void rotateAroundYAxis(Node node) {
Rotate r = new Rotate(0, 0, 0, 100, Rotate.Y_AXIS);
node.getTransforms().add(r);
lastTimerCall = System.nanoTime();
timeline = new AnimationTimer() {
@Override public void handle(long now) {
if (now > lastTimerCall + 100_000_000l) {
r.setAngle((count++)%360);
}
}
};
timeline.start();
}
@Override
public void stop() {
timeline.stop();
}
盒子前面:
藍框后面:
編輯
如果您查看nearClip
的Camera JavaDoc:
指定到的近剪裁平面的眼睛的距離
這個相機在眼睛的坐標空間。
不會繪制比Near Clip更靠近眼睛的對象。
Near Clip被指定為大于零的值。價值小于
大于或等于零被視為非常小的正數。
(粗體是我的)。
所以您的代碼的問題在于該行:
camera.setNearClip(0);
只需更改為:
camera.setNearClip(0.01);
它將按您的預期工作。
這篇關于JavaFX 8 Z緩沖區問題的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,