问题
我想将漫反射贴图应用于 MeshView。当我将带有漫反射贴图的材质应用到 MeshView 时,它是不可见的。然而,应用于 Box 的相同材料是可见的。
问题
要将漫反射贴图应用于 MeshView,我需要做什么?
代码
该代码生成带有随机噪声的图像。该图像用作 PhongMaterial 中的漫反射贴图。将显示图像,在其上方是应用了材质的框,在框上方是应用了材质的 MeshView(金字塔)。该材料在金字塔上不可见。您可以使用鼠标拖动进行旋转。
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
public class Test extends Application {
private double mousePosX, mousePosY;
private double mouseOldX, mouseOldY;
private final Rotate rotateX = new Rotate(20, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(-45, Rotate.Y_AXIS);
@Override
public void start(Stage primaryStage) {
// cube
Group group = new Group();
// size of the cube
double size = 400;
group.getTransforms().addAll(rotateX, rotateY);
Image diffuseMap = createImage( size);
// show noise image
ImageView iv = new ImageView( diffuseMap);
iv.setTranslateX(-0.5*size);
iv.setTranslateY(-0.20*size);
iv.setRotate(90);
iv.setRotationAxis(new Point3D(1,0,0));
group.getChildren().add( iv);
// create material out of the noise image
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(diffuseMap);
// create box with noise diffuse map
Box box = new Box( 100,100,100);
box.setMaterial(material);
group.getChildren().add( box);
// create pyramid with diffuse map
float h = 150; // Height
float s = 150; // Side
TriangleMesh pyramidMesh = new TriangleMesh();
pyramidMesh.getTexCoords().addAll(1,1,1,0,0,1,0,0);
pyramidMesh.getPoints().addAll(
0, 0, 0, // Point 0 - Top
0, h, -s/2, // Point 1 - Front
-s/2, h, 0, // Point 2 - Left
s/2, h, 0, // Point 3 - Back
0, h, s/2 // Point 4 - Right
);
pyramidMesh.getFaces().addAll(
0,0, 2,0, 1,0, // Front left face
0,0, 1,0, 3,0, // Front right face
0,0, 3,0, 4,0, // Back right face
0,0, 4,0, 2,0, // Back left face
4,0, 1,0, 2,0, // Bottom rear face
4,0, 3,0, 1,0 // Bottom front face
);
MeshView pyramid = new MeshView(pyramidMesh);
pyramid.setDrawMode(DrawMode.FILL);
pyramid.setTranslateY(-250);
// apply material
// TODO: why is the diffuse map not displayed?
pyramid.setMaterial(material);
group.getChildren().add(pyramid);
// scene
StackPane root = new StackPane();
root.getChildren().add(group);
Scene scene = new Scene(root, 1600, 900, true, SceneAntialiasing.BALANCED);
scene.setCamera(new PerspectiveCamera());
// interaction listeners
scene.setOnMousePressed(me -> {
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
});
scene.setOnMouseDragged(me -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
rotateX.setAngle(rotateX.getAngle()-(mousePosY - mouseOldY));
rotateY.setAngle(rotateY.getAngle()+(mousePosX - mouseOldX));
mouseOldX = mousePosX;
mouseOldY = mousePosY;
});
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Create image with random noise
*/
public Image createImage( double size) {
Random rnd = new Random();
int width = (int) size;
int height = (int) size;
WritableImage wr = new WritableImage(width, height);
PixelWriter pw = wr.getPixelWriter();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color color = Color.rgb(rnd.nextInt( 256), rnd.nextInt( 256), rnd.nextInt( 256));
pw.setColor(x, y, color);
}
}
return wr;
}
public static void main(String[] args) {
launch(args);
}
}
截屏
非常感谢你的帮助!