JavaFX z缓冲区问题

RenéSteeman:

我正在用许多小盒子装满一个容器,问题是您可以从某些角度看它们的槽。我已经启用了深度缓冲,但这是行不通的。

处理该部分的代码分为3个。setupUIPreElements设置所有内容,setupUIElements添加框,setupUIPostElements添加容器和一些照相机材质。

public static void setupUIPreElements(Stage stage){
    //Setup grids, groups, scenes, camera and such so that the scene is made from scratch
    topGrid = new GridPane();
    twoDGroup = new Group();
    threeDGroup = new SmartGroup();
    root = new HBox();
    mainScene = new Scene(root, SCREEN_WIDTH, SCREEN_HEIGHT, true, SceneAntialiasing.BALANCED);
    twoD = new SubScene(twoDGroup, SCREEN_WIDTH*.2, SCREEN_HEIGHT);
    threeD = new SubScene(threeDGroup, SCREEN_WIDTH*.8, SCREEN_HEIGHT);
    anchorAngleX = 0;
    anchorAngleY = 0;
    angleX = new SimpleDoubleProperty(0);
    angleY = new SimpleDoubleProperty(0);
    camera = new PerspectiveCamera();
    pins = new ProgressIndicator[1];
    pin = pins[0] = new ProgressIndicator();
    parcels = new ArrayList<UIParcel>();

    //add subscenes to scene
    root.getChildren().addAll(twoD, threeD);
    root.setSpacing(10);
    root.setPadding(new Insets(20, 20, 20, 20));

    /*START Setup top menu*/
    //Setup grid
    topGrid.setHgap(10);
    topGrid.setVgap(10);

    //Setup items
    //Add scoring label
    scoringLabel = new Label("Score: " + Wrapper.score);
    startButton = new Button("Start");

    modeSelection = new ChoiceBox(FXCollections.observableArrayList(
            "Parcels", "Pentominoes"
    ));

    modeSelection.setValue("");

    //Parcel selection UI
    ParcelAAmountLabel = new Label("Amount of parcel A: ");
    ParcelBAmountLabel = new Label("Amount of parcel B: ");
    ParcelCAmountLabel = new Label("Amount of parcel C: ");
    ParcelAAmountTextField = new TextField();
    ParcelBAmountTextField = new TextField();
    ParcelCAmountTextField = new TextField();

    ParcelAValueLabel = new Label("Value of parcel A: ");
    ParcelBValueLabel = new Label("Value of parcel B: ");
    ParcelCValueLabel = new Label("Value of parcel C: ");
    ParcelAValueTextField = new TextField();
    ParcelBValueTextField = new TextField();
    ParcelCValueTextField = new TextField();

    //Pentominoe selection UI
    LPentominoAmountLabel = new Label("Amount of L pentominoes: ");
    PPentominoAmountLabel = new Label("Amount of P pentominoes: ");
    TPentominoAmountLabel = new Label("Amount of T pentominoes: ");
    LPentominoAmountTextField = new TextField();
    PPentominoAmountTextField = new TextField();
    TPentominoAmountTextField = new TextField();

    LPentominoValueLabel = new Label("Value of L pentominoes: ");
    PPentominoValueLabel = new Label("Value of P pentominoes: ");
    TPentominoValueLabel = new Label("Value of T pentominoes: ");
    LPentominoValueTextField = new TextField();
    PPentominoValueTextField = new TextField();
    TPentominoValueTextField = new TextField();

    //-1 will make it display an animated disk, set to 1 to show that it's done
    //pin is the progress indicator
    pin.setProgress(-1);

    topGrid.add(scoringLabel, 0, 0);
    topGrid.add(modeSelection, 0, 1);
    topGrid.add(startButton, 0, 8);
    twoDGroup.getChildren().add(topGrid);
    /*END*/

    //Set materials
    container_material.setDiffuseColor(CONTAINER_COLOR);
    edge_material.setDiffuseColor(EDGE_COLOR);
}

public static void setupUIElements(Stage stage, int[][][] resultBoxesArray){
    //TODO check if I can assume the IDs to be either 1, 2 or 3 if filled in or 0 if not
    int colorStart = 0;
    int colorEnd = 0;

    //give every filled in field a box representation and keep color in mind
    //create all the boxes
    for(int x=0; x<resultBoxesArray.length; x++){
        for(int y=0; y<resultBoxesArray[x].length; y++){
            for(int z=0; z<resultBoxesArray[x][y].length; z++){
                int currentValue = resultBoxesArray[x][y][z];

                //if this field is filled
                if(currentValue!=0){
                    //update color range
                    if(currentValue==1){
                        colorStart = 0;
                        colorEnd = 70;
                    } else if (currentValue==2){
                        colorStart = 85;
                        colorEnd = 155;
                    } else {
                        colorStart = 170;
                        colorEnd = 255;
                    }

                    //50 is used because that is the size that is given for each cell in the array
                    UIParcel cellBox = new UIParcel(x*50, y*50, z*50, 50, 50, 50, colorStart, colorEnd);
                    parcels.add(cellBox);
                }
            }
        }
    }

    //show them
    threeDGroup.getChildren().addAll(parcels);
}

public static void setupUIPostElements(Stage stage){
    //Create container (note: Has to be created after adding all the other objects in order to use transparency (I know, javaFX can be crappy))
    Box container = new Box(Wrapper.CONTAINER_WIDTH, Wrapper.CONTAINER_HEIGHT, Wrapper.CONTAINER_DEPTH);
    container.setTranslateX(Wrapper.CONTAINER_WIDTH/2);
    container.setTranslateY(Wrapper.CONTAINER_HEIGHT/2);
    container.setTranslateZ(Wrapper.CONTAINER_DEPTH/2);
    container.setMaterial(container_material);
    threeDGroup.getChildren().add(container);

    //Setup camera (so that you can have the container at the origin and can still see it well
    //The +threeDOffsetLeft comes from the compensation for the 2D subscene on the left
    camera.setTranslateX(-SCREEN_WIDTH/2+Wrapper.CONTAINER_WIDTH/2+threeDOffsetLeft);
    camera.setTranslateY(-SCREEN_HEIGHT/2+Wrapper.CONTAINER_HEIGHT/2);
    camera.setTranslateZ(-Wrapper.CONTAINER_DEPTH/0.5);

    //Setup mouse rotation
    initMouseControl(threeDGroup, mainScene, stage);

    //Set eventListener for mode selection
    modeSelection.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) -> {
        //check what mode was selected and show the corresponding options
        if(newValue.equals("Parcels")){
            //remove other option
            if(oldValue.equals("Pentominoes")){
                topGrid.getChildren().removeAll(LPentominoAmountLabel, PPentominoAmountLabel, TPentominoAmountLabel, LPentominoAmountTextField, PPentominoAmountTextField, TPentominoAmountTextField, LPentominoValueLabel, PPentominoValueLabel, TPentominoValueLabel, LPentominoValueTextField, PPentominoValueTextField, TPentominoValueTextField);
            }

            //add labels
            topGrid.add(ParcelAAmountLabel, 0, 2);
            topGrid.add(ParcelBAmountLabel, 0, 4);
            topGrid.add(ParcelCAmountLabel, 0, 6);

            topGrid.add(ParcelAValueLabel, 0, 3);
            topGrid.add(ParcelBValueLabel, 0, 5);
            topGrid.add(ParcelCValueLabel, 0, 7);

            //add text fields
            topGrid.add(ParcelAAmountTextField, 1, 2);
            topGrid.add(ParcelBAmountTextField, 1, 4);
            topGrid.add(ParcelCAmountTextField, 1, 6);

            topGrid.add(ParcelAValueTextField, 1, 3);
            topGrid.add(ParcelBValueTextField, 1, 5);
            topGrid.add(ParcelCValueTextField, 1, 7);

        } else if (newValue.equals("Pentominoes")){
            //remove other option
            if(oldValue.equals("Parcels")){
                topGrid.getChildren().removeAll(ParcelAAmountLabel, ParcelBAmountLabel, ParcelCAmountLabel, ParcelAAmountTextField, ParcelBAmountTextField, ParcelCAmountTextField, ParcelAValueLabel, ParcelBValueLabel, ParcelCValueLabel, ParcelAValueTextField, ParcelBValueTextField, ParcelCValueTextField);
            }

            //add labels
            topGrid.add(LPentominoAmountLabel, 0, 2);
            topGrid.add(PPentominoAmountLabel, 0, 4);
            topGrid.add(TPentominoAmountLabel, 0, 6);

            topGrid.add(LPentominoValueLabel, 0, 3);
            topGrid.add(PPentominoValueLabel, 0, 5);
            topGrid.add(TPentominoValueLabel, 0, 7);

            //add text fields
            topGrid.add(LPentominoAmountTextField, 1, 2);
            topGrid.add(PPentominoAmountTextField, 1, 4);
            topGrid.add(TPentominoAmountTextField, 1, 6);

            topGrid.add(LPentominoValueTextField, 1, 3);
            topGrid.add(PPentominoValueTextField, 1, 5);
            topGrid.add(TPentominoValueTextField, 1, 7);
        }
    });

    //Set evenListener for start button
    startButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event-> {
        //Show loading circle (that was created at the start)
        topGrid.add(pin, 0, 9);

        //TODO use values from the textFields as input

        //TODO start calculations

        //TODO remove after testing
        test.giveInput();

    });

    threeD.setCamera(camera);
    stage.setTitle("Filling 3D objects");
    threeD.setFill(BACKGROUND_COLOR);
    stage.setScene(mainScene);
    stage.show();
}

从所需的角度看,如下所示: 在此处输入图片说明

从无法正常工作的角度来看,它看起来像这样: 在此处输入图片说明

请注意,盒子是作为UIParcel添加的,这只是一个扩展常规Box的类,带有一些额外的信息,它不会影响任何3D东西。

RenéSteeman:

解决方案是还为包含3D元素的SubScene启用深度缓冲,而不仅仅是遵循mainScene的设置。

threeD = new SubScene(threeDGroup, SCREEN_WIDTH*.8, SCREEN_HEIGHT);

变成

threeD = new SubScene(threeDGroup, SCREEN_WIDTH*.8, SCREEN_HEIGHT, true, SceneAntialiasing.BALANCED);

SubScene构造函数还需要设置SceneAntialiasing。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章