5 Replies Latest reply: Oct 24, 2012 5:49 AM by 968630 RSS

    JavaFX2 depth buffer issues

    968630
      Hi all!

      Here at the company we had some 3d animations done in java 3D.. Which were heavy and not very portable so, when Javafx2 came out we immediately switched to it and tried to implement similar animations.
      It was a bother since Javafx does not have any 3d primitives, and we had to build some of our own. All good until now.. so here is the issue:

      with depth buffering enabled, and perspective camera the scene flickers, hides part of the stuff.. sometimes does not render at all etc
      Without depth buffering all renders ok, but obviouly the objects in the scene overlap etc

      From the tests i made, it looks like the scene struggles with node resizing. If the objects are inside a container and that container is big enough to contain the scene in perspective, normally all looks ok. But when (due to layout resizing, and fitting) the scene is not big enough
      it starts the rendering issues above.

      Keep in mind that i could not find a pattern for this.. but seems the depth buffering is somewhat broken.

      Has anyone stumbled on this?

      Thanks in advance
      Best regards
      Pedro Quelhas
        • 1. Re: JavaFX2 depth buffer issues
          892978
          Have you set a perspective camera? For example:

          scene.setCamera(new PerspectiveCamera());

          There are known issues with 3D rendering when using the default parallel camera. For example: http://javafx-jira.kenai.com/browse/RT-13847

          Also, you may be interested to know that we are adding 3D primitives and attributes to FX 8.
          • 2. Re: JavaFX2 depth buffer issues
            892978
            I guess I should read more carefully. I see that you are using a perspective camera. There are a couple possible causes:

            1) Your objects are too close together to be distinguished from each other by the depth buffer

            2) You have transparency on some of the objects (depth buffer is insufficient to correct render transparent objects unless they are presorted).

            If you like, you can file a JIRA and attach a reproducible test case and screen-shot: http://javafx-jira.kenai.com/secure/Dashboard.jspa
            • 3. Re: JavaFX2 depth buffer issues
              968630
              Hi kcr, thank you for the answers!

              Nice to know we will have primitives in the near future!

              I will debug a bit more my program, and see if i have transparency issues on the scene. I will also look for overlapping objects (i think this happens when the layout is resized..)

              regards!
              • 4. Re: JavaFX2 depth buffer issues
                968630
                Hi again.

                During the day, did more extensive tests to my program trying to understand the issue. I did reach a conclusion.. so im still stuck. However, i found a diferent issue, and im starting to think that part of the problem is also related with JFXPanel integration.

                I tried to use your jira, but i dont know the login.. i tried with one from here but it did nor work.

                anyway i will post here some Junk code (its bad i know, but its only to trigger the issues).

                On issue one, multiple Scenes on the same JFXPanel, dont render correctly.

                On issue two, the problem i have in my program appears.. without depth buffering all works, with depthbuffering all hell breaks loose.

                The JFrame opening without size is intentional to make the scene render itself on resize.

                Issue 1
                import javafx.animation.KeyFrame;
                import javafx.animation.KeyValue;
                import javafx.animation.Timeline;
                import javafx.application.Platform;
                import javafx.embed.swing.JFXPanel;
                import javafx.scene.PerspectiveCamera;
                import javafx.scene.Scene;
                import javafx.scene.layout.Pane;
                import javafx.scene.shape.Rectangle;
                import javafx.scene.transform.Rotate;
                import javafx.util.Duration;
                import javax.swing.GroupLayout;
                import javax.swing.JFrame;
                import javax.swing.JPanel;
                import javax.swing.SwingUtilities;
                
                /**
                 *
                 * @author omega
                 */
                public class Issue1 {
                    
                    public static void main(String[] args) {
                        //  Application.launch(WS_FXChart_API.class, args);
                
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                JFrame a = new JFrame();
                
                                a.add(getTestPanel());
                
                                a.setVisible(true);
                
                                a.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                
                            }
                        });
                    }
                 private static JPanel getTestPanel() {
                       
                        JFXPanel tmp = createTestPanel();
                        JFXPanel tmp2 = createTestPanel();
                        JFXPanel tmp3 = createTestPanel();
                
                        final JPanel panel = new JPanel();
                        GroupLayout layout = new GroupLayout(panel);
                        panel.setLayout(layout);
                
                        layout.setHorizontalGroup(layout.createParallelGroup()
                                .addGroup(layout.createSequentialGroup()
                                .addComponent(tmp,300,300,300)
                                .addComponent(tmp2,300,300,300)
                                .addComponent(tmp3,300,300,300))
                                );
                
                        layout.setVerticalGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup()
                                .addComponent(tmp,300,300,300)
                                .addComponent(tmp2,300,300,300)
                                .addComponent(tmp3,300,300,300)
                                )
                                );
                
                
                        return panel;
                    }
                 
                 
                    private static JFXPanel createTestPanel() {
                        final JFXPanel tmp = new JFXPanel();
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                Pane pane = new Pane();
                                pane.setPrefSize(300, 300);
                                Rectangle rec = new Rectangle(200, 200);
                                pane.getChildren().add(rec);
                
                                Scene scene = new Scene(pane, 1000, 1000, true);
                                scene.setCamera(new PerspectiveCamera());
                
                                tmp.setScene(scene);
                
                                final Timeline timeline = new Timeline();
                                timeline.setAutoReverse(true);
                                timeline.setCycleCount(Timeline.INDEFINITE);
                                pane.setRotationAxis(Rotate.X_AXIS);
                                final KeyValue rotate = new KeyValue(pane.rotateProperty(), -65);
                
                                final KeyFrame rotateXKey = new KeyFrame(Duration.millis(500), rotate);
                
                                timeline.getKeyFrames().addAll(rotateXKey);
                                timeline.play();
                            }
                        });
                
                        return tmp;
                
                
                    }
                }
                Issue 2
                import javafx.animation.KeyFrame;
                import javafx.animation.KeyValue;
                import javafx.animation.Timeline;
                import javafx.application.Platform;
                import javafx.embed.swing.JFXPanel;
                import javafx.geometry.Pos;
                import javafx.scene.PerspectiveCamera;
                import javafx.scene.Scene;
                import javafx.scene.layout.HBox;
                import javafx.scene.layout.Pane;
                import javafx.scene.layout.Priority;
                import javafx.scene.layout.VBox;
                import javafx.scene.shape.Rectangle;
                import javafx.scene.transform.Rotate;
                import javafx.util.Duration;
                import javax.swing.GroupLayout;
                import javax.swing.JFrame;
                import javax.swing.JPanel;
                import javax.swing.SwingUtilities;
                
                /**
                 *
                 * @author omega
                 */
                public class Issue2 {
                
                    public static void main(String[] args) {
                
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                JFrame a = new JFrame();
                
                                a.add(getTestPanel());
                
                                a.setVisible(true);
                
                                a.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                
                            }
                        });
                    }
                
                    private static JPanel getTestPanel() {
                
                        final JFXPanel tmp = new JFXPanel();
                        Platform.runLater(new Runnable() {
                
                            @Override
                            public void run() {
                    
                        Pane p = createTestPane();
                        Pane p2 = createTestPane();
                        
                        Rectangle rec = new Rectangle(200,200);
                        Rectangle rec2= new Rectangle(200,200);
                        
                        VBox middle = new VBox();
                        middle.setAlignment(Pos.CENTER);
                        middle.getChildren().addAll(rec,rec2);
                        VBox.setVgrow(rec, Priority.ALWAYS);
                        VBox.setVgrow(rec2, Priority.NEVER);
                        
                        HBox footPane = new HBox();
                        HBox.setHgrow(p, Priority.ALWAYS);
                        HBox.setHgrow(p2, Priority.ALWAYS);
                        HBox.setHgrow(middle, Priority.NEVER);
                        middle.setPrefWidth(40);
                        middle.setMinWidth(40);
                         footPane.getChildren().addAll(p,middle,p2);
                        
                        Scene scene = new Scene(footPane,1000,1000,true);
                        scene.setCamera(new PerspectiveCamera());
                        
                        tmp.setScene(scene);
                                }
                        });
                        
                        final JPanel panel = new JPanel();
                        GroupLayout layout = new GroupLayout(panel);
                        panel.setLayout(layout);
                
                        layout.setHorizontalGroup(layout.createParallelGroup()
                                .addGroup(layout.createSequentialGroup()
                                .addComponent(tmp)));
                
                        layout.setVerticalGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup()
                                .addComponent(tmp)));
                
                
                        return panel;
                    }
                
                    private static Pane createTestPane() {
                        Pane pane = new Pane();
                        pane.setPrefSize(300, 300);
                        Rectangle rec = new Rectangle(200, 200);
                        pane.getChildren().add(rec);
                
                        final Timeline timeline = new Timeline();
                        timeline.setAutoReverse(true);
                        timeline.setCycleCount(Timeline.INDEFINITE);
                        pane.setRotationAxis(Rotate.X_AXIS);
                        final KeyValue rotate = new KeyValue(pane.rotateProperty(), -65);
                
                        final KeyFrame rotateXKey = new KeyFrame(Duration.millis(500), rotate);
                
                        timeline.getKeyFrames().addAll(rotateXKey);
                        timeline.play();
                
                        return pane;
                    }
                }
                Hope you guys can help.

                regards!
                Pedro
                • 5. Re: JavaFX2 depth buffer issues
                  968630
                  FYI I filled a jira issue. Wainting for feedback...