Java 如何正确渲染三维图形

Java 如何正确渲染三维图形,java,javafx-8,javafx-3d,Java,Javafx 8,Javafx 3d,我试图在javafx中制作一个rubiks立方体,结果得到了一个非常糟糕的模型,如本文所示。我给出了这方面的源代码,我使用了RectangleBuilder类来创建矩形并在3d中进行转换。为了修复图形,我还尝试构建了使用TriangleMesh类的矩形,并在添加材质后,在3d中对其进行了转换,最终再次生成同样糟糕的图形。为什么会发生这种情况以及如何消除它 import javafx.scene.transform.Rotate; import javafx.scene.PerspectiveCa

我试图在
javafx
中制作一个rubiks立方体,结果得到了一个非常糟糕的模型,如本文所示。我给出了这方面的源代码,我使用了
RectangleBuilder
类来创建矩形并在3d中进行转换。为了修复图形,我还尝试构建了使用
TriangleMesh
类的矩形,并在添加材质后,在3d中对其进行了转换,最终再次生成同样糟糕的图形。为什么会发生这种情况以及如何消除它

import javafx.scene.transform.Rotate;
import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Translate;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
import javafx.util.Duration;


    public class NewFXMain1 extends Application {


    public class Cube extends Group {
    final Rotate rx = new Rotate(0,Rotate.X_AXIS);
    final Rotate ry = new Rotate(0,Rotate.Y_AXIS);
    final Rotate rz = new Rotate(0,Rotate.Z_AXIS);
    public Cube(double size, Color back,Color bottom,Color right,Color left,Color top,Color front, double shade) {
        getTransforms().addAll(rz, ry, rx);
        getChildren().addAll(
            RectangleBuilder.create() // back face
                .width(size).height(size)
                .fill(back.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // bottom face
                .width(size).height(size)
                .fill(bottom.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(0)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // right face
                .width(size).height(size)
                .fill(right.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
                .translateX(-1*size)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // left face
                .width(size).height(size)
                .fill(left.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))
                .translateX(0)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // top face
                .width(size).height(size)
                .fill(top.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-1*size)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // front face
                .width(size).height(size)
                .fill(front)
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(-0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build()
        );
    }
    }



    PerspectiveCamera camera = new PerspectiveCamera(true);
    @Override public void start(Stage primaryStage) throws Exception {

    Group root = new Group();
    Scene scene=new Scene(root,600,600,true);

    camera.setNearClip(0.00001);
    camera.setFarClip(10000000.0);

    camera.getTransforms().addAll (
            new Rotate(0, Rotate.Y_AXIS),
            new Rotate(0, Rotate.X_AXIS),

            new Translate(0, 0, -1000));
    scene.setCamera(camera);
    Cube c1 = new Cube(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c1.setTranslateX(100);

    Cube c2 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c2.setTranslateX(50);

    Cube c3 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c3.setTranslateX(50);
    c3.setTranslateZ(50);

    Cube c4 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c4.setTranslateX(100);
    c4.setTranslateZ(50);

    Cube c5 = new Cube(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c5.setTranslateX(100);
     c5.setTranslateY(50);

    Cube c6 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c6.setTranslateX(50);
    c6.setTranslateY(50);

    Cube c7 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c7.setTranslateX(50);
    c7.setTranslateZ(50);
    c7.setTranslateY(50);

    Cube c8 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c8.setTranslateX(100);
    c8.setTranslateZ(50);
    c8.setTranslateY(50);
    handleMouse(scene,root);
    Group k=new Group(c1,c2,c3,c4,c5,c6,c7,c8);
    k.setTranslateZ(70);
    root.getChildren().addAll(k);
    primaryStage.setScene(scene);
    primaryStage.show();
    }
    public static void main(String[] args) { launch(args); }
    private static final double CONTROL_MULTIPLIER = 0.1;   
    private static final double SHIFT_MULTIPLIER = 10.0;   
    private static final double MOUSE_SPEED = 0.1;    
  private static final double ROTATION_SPEED = 2.0; 
  double mousePosX,mousePosY,mouseOldX,mouseOldY,mouseDeltaX,mouseDeltaY;
  private void handleMouse(Scene scene, final Node root) {


    scene.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
             mousePosX = me.getSceneX();
             mousePosY = me.getSceneY();
             mouseOldX = me.getSceneX();
             mouseOldY = me.getSceneY();
        }
    });
    scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            mouseDeltaX = (mousePosX - mouseOldX); 
            mouseDeltaY = (mousePosY - mouseOldY);

           double modifier = 1.0;

           if (me.isControlDown()) {
                modifier = CONTROL_MULTIPLIER;
            } 
            if (me.isShiftDown()) {
                modifier = SHIFT_MULTIPLIER;
            }     
            if (me.isPrimaryButtonDown()) {
                camera.setRotationAxis(Rotate.Y_AXIS);camera.setRotate(camera.getRotate() -
                   mouseDeltaX*modifier*ROTATION_SPEED);  // 
               camera.setRotationAxis(Rotate.X_AXIS);camera.setRotate(camera.getRotate() +
                   mouseDeltaY*modifier*ROTATION_SPEED);  // -

            }
            else if (me.isSecondaryButtonDown()) {
                double z = camera.getTranslateZ();
                double newZ = z + mouseDeltaX*MOUSE_SPEED*modifier;
                camera.setTranslateZ(newZ);
            }

       }
   }); // setOnMouseDragged
 } //handleMouse
}
导入javafx.scene.transform.Rotate;
导入javafx.scene.PerspectiveCamera;
导入javafx.scene.transform.Translate;
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.stage.stage;
导入javafx.animation.animation;
导入javafx.animation.KeyFrame;
导入javafx.animation.KeyValue;
导入javafx.animation.Timeline;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.Node;
导入javafx.scene.sceneatialiasing;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.RectangleBuilder;
导入javafx.scene.transform.Rotate;
导入javafx.util.Duration;
公共类NewFXMain1扩展了应用程序{
公共类多维数据集扩展组{
最终旋转rx=新旋转(0,旋转X_轴);
最终旋转ry=新旋转(0,旋转Y_轴);
最终旋转rz=新旋转(0,旋转Z_轴);
公共立方体(双尺寸、彩色背面、彩色底部、彩色右侧、彩色左侧、彩色顶部、彩色前部、双阴影){
getTransforms().addAll(rz、ry、rx);
getChildren().addAll(
RectangleBuilder.create()//背面
.宽度(尺寸).高度(尺寸)
.填充(背衬颜色(0.0,1.0,(1-0.5*阴影),1.0))
.translateX(-0.5*尺寸)
.translateY(-0.5*尺寸)
.translateZ(0.5*尺寸)
.平滑(真实)
.笔划(颜色.黑色)
.build(),
RectangleBuilder.create()//底面
.宽度(尺寸).高度(尺寸)
.填充(底部衍生颜色(0.0,1.0,(1-0.4*阴影),1.0))
.translateX(-0.5*尺寸)
.translateY(0)
.旋转轴(旋转X_轴)
.旋转(90)
.平滑(真实)
.笔划(颜色.黑色)
.build(),
RectangleBuilder.create()//右面
.宽度(尺寸).高度(尺寸)
.填充(右侧的衍生色(0.0,1.0,(1-0.3*阴影),1.0))
.translateX(-1*尺寸)
.translateY(-0.5*尺寸)
.旋转轴(旋转Y_轴)
.旋转(90)
.平滑(真实)
.笔划(颜色.黑色)
.build(),
RectangleBuilder.create()//左侧面
.宽度(尺寸).高度(尺寸)
.填充(左德里维科颜色(0.0,1.0,(1-0.2*阴影),1.0))
.translateX(0)
.translateY(-0.5*尺寸)
.旋转轴(旋转Y_轴)
.旋转(90)
.平滑(真实)
.笔划(颜色.黑色)
.build(),
RectangleBuilder.create()//顶面
.宽度(尺寸).高度(尺寸)
填充(顶部衍生颜色(0.0,1.0,(1-0.1*阴影),1.0))
.translateX(-0.5*尺寸)
.translateY(-1*大小)
.旋转轴(旋转X_轴)
.旋转(90)
.平滑(真实)
.笔划(颜色.黑色)
.build(),
RectangleBuilder.create()//正面
.宽度(尺寸).高度(尺寸)
.加油(前)
.translateX(-0.5*尺寸)
.translateY(-0.5*尺寸)
.translateZ(-0.5*尺寸)
.平滑(真实)
.笔划(颜色.黑色)
.build()
);
}
}
透视摄影机=新透视摄影机(真);
@覆盖公共无效开始(阶段primaryStage)引发异常{
组根=新组();
场景场景=新场景(根,600600,真);
摄像头。setNearClip(0.00001);
摄像机.setFarClip(10000000.0);
camera.getTransforms().addAll(
新旋转(0,旋转Y_轴),
新旋转(0,旋转X_轴),
新翻译(0,0,-1000));
场景。设置摄像机(摄像机);
立方体c1=新立方体(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c1.setTranslateX(100);
立方体c2=新立方体(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c2.setTranslateX(50);
立方体c3=新立方体(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c3.setTranslateX(50);
c3.setTranslateZ(50);
立方体c4=新立方体(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c4.setTranslateX(100);
c4.setTranslateZ(50);
立方体c5=新立方体(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c5.setTranslateX(100);
c5.setTranslateY(50);
立方体c6=新立方体(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c6.setTranslateX(50);
c6.setTranslateY(50);
立方体c7=新立方体(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c7.setTranslateX(50);
c7.setTranslateZ(50);
c7.setTranslateY(50);
立方体c8=新立方体(50,Color.CYAN.brighter(),Color.GREEN)。
camera.setNearClip(0.00001);
camera.setFarClip(10000000.0);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
Box cube = new Box();
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResource("cubeNet.png").toExternalForm()));
cube.setMaterial(material);
CuboidMesh cube = new CuboidMesh();
cube.setTextureModeImage(getClass().getResource("cubeNet.png").toExternalForm());
public static final int RED     = 0;
public static final int GREEN   = 1;
public static final int BLUE    = 2;
public static final int YELLOW  = 3;
public static final int ORANGE  = 4;
public static final int WHITE   = 5;
public static final int GRAY    = 6;
public static final float X_RED     = 0.5f / 7f;
public static final float X_GREEN   = 1.5f / 7f;
public static final float X_BLUE    = 2.5f / 7f;
public static final float X_YELLOW  = 3.5f / 7f;
public static final float X_ORANGE  = 4.5f / 7f;
public static final float X_WHITE   = 5.5f / 7f;
public static final float X_GRAY    = 6.5f / 7f;
private TriangleMesh createCube(int[] face) {
    TriangleMesh m = new TriangleMesh();
    m.getPoints().addAll(
     0.5f,  0.5f,  0.5f,
     0.5f, -0.5f,  0.5f,
     0.5f,  0.5f, -0.5f,
     0.5f, -0.5f, -0.5f,
    -0.5f,  0.5f,  0.5f,
    -0.5f, -0.5f,  0.5f,
    -0.5f,  0.5f, -0.5f,
    -0.5f, -0.5f, -0.5f
    );
    m.getTexCoords().addAll(
     X_RED, 0.5f, 
     X_GREEN, 0.5f,
     X_BLUE, 0.5f, 
     X_YELLOW, 0.5f, 
     X_ORANGE, 0.5f,  
     X_WHITE, 0.5f,
     X_GRAY, 0.5f
    );
    m.getFaces().addAll(
     2, face[0], 3, face[0], 6, face[0],      // F      
     3, face[0], 7, face[0], 6, face[0],  

     0, face[1], 1, face[1], 2, face[1],      // R     
     2, face[1], 1, face[1], 3, face[1],         

     1, face[2], 5, face[2], 3, face[2],      // U   
     5, face[2], 7, face[2], 3, face[2],

     0, face[3], 4, face[3], 1, face[3],      // B      
     4, face[3], 5, face[3], 1, face[3],       

     4, face[4], 6, face[4], 5, face[4],      // L      
     6, face[4], 7, face[4], 5, face[4],    

     0, face[5], 2, face[5], 4, face[5],      // D      
     2, face[5], 6, face[5], 4, face[5]         
    );
    return m;
}
int[] p = new int[]{BLUE, GRAY, GRAY, GRAY, ORANGE, WHITE};
MeshView meshP = new MeshView();
meshP.setMesh(createCube(p));
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(new Image(getClass().getResourceAsStream("palette.png")));
meshP.setMaterial(mat);