'Is it possible to create 3d model in JavaFX 8 without texture?
I'd like to create a model in JavaFX 8 application which will have ~400000 polygons. And I don't need any texture, only simple color. Commonly it's necessary to have something like this:
float[] points = {
-5, 5, 0,
-5, -5, 0,
5, 5, 0,
5, -5, 0
};
float[] texCoords = {
1, 1,
1, 0,
0, 1,
0, 0
};
int[] faces = {
2, 2, 1, 1, 0, 0,
2, 2, 3, 3, 1, 1
};
TriangleMesh mesh = new TriangleMesh();
mesh.getPoints().setAll(points);
mesh.getTexCoords().setAll(texCoords);
mesh.getFaces().setAll(faces);
And if I use this code without texCoords
and faces
arrays, it, surely, doesn't work. So is it possible to create 3d model without texture?
Solution 1:[1]
Short Answer
You must define all of points, faces and texture co-ordinates for a TriangleMesh for the mesh to be valid for rendering in Java 8.
Some Explanation
You are using a TriangleMesh for your model. The faces describe the triangles to be used to draw the mesh. If you don't provide faces, then the system cannot know what the triangles are that comprise the polygons to be rendered.
It's just an implementation detail (which is documented in the TriangleMesh javadoc), that you must supply texture co-ordinate values, for your mesh, even though in your case as you will be rendering with a single diffuse color, it doesn't matter what the values are.
Java 8 defines only a single material to be used in rendering 3D shapes such as meshes. That material is a PhongMaterial. With a PhongMaterial, you don't need to provide an image texture for rendering the material, you can use a basic color for the material (for example blue) by calling material.setDiffuseColor(Color.BLUE). Each of the polygons will be shaded according to a phong shading algorithm, taking into account other items in the scene graph such as point lights, ambient lights, transparent areas, occluded areas, specular highlights etc. This allows you to realistically view your model (if everything polygon was just painted blue, it would just show up as a blue blob and you would be unable to discern the internal details of the model).
There are other shading techniques which could be used such as flat shading or gouraud shading or custom shading algorithms, but materials using those shading techniques are not supported in Java 8 - you must use a PhongMaterial.
Now, if you set the diffuse color of your PhongMaterial to a solid color and don't set any other values for your PhongMaterial, the values of the texture co-ordinates provided to the TriangleMesh aren't going to matter. The texture co-ordinates are provided so that the shader can lookup pixel colors from the material for rendering polygons. As the material has a single uniform color, you can specify any valid texture co-ordinate (e.g. any value between 0 and 1) and it will return the same color. So, in your case, you don't need to calculate texture co-ordinates for your model if you don't want to, you could set all of the texture co-ordinate values to 0 or 1 and you will get the same rendered output.
Solution 2:[2]
Point all uv coordinates to the same coordinate (0 u ,0 v)
If you don't need to apply raster image textures on your meshview just point all textcoordinates indexes in faces[]
to the same uv point ( 0,0 ) . This is a single class javafx app with same points[]
but just one uv point in textCoords[]
(0 u , 0 v ) and , where faces[]
needs a uv point I replace all to index 0 .
public class App extends Application {
@Override
public void start(Stage stage) {
PerspectiveCamera perspectiveCamera = new PerspectiveCamera(true);
perspectiveCamera.setTranslateZ(-30);
float[] points = {
-5, 5, 0,
-5, -5, 0,
5, 5, 0,
5, -5, 0
};
float[] texCoords = {
0, 0
};
int[] faces = {
2, 0, 1, 0, 0, 0,
2, 0, 3, 0, 1, 0
};
TriangleMesh mesh = new TriangleMesh();
mesh.getPoints().setAll(points);
mesh.getTexCoords().setAll(texCoords);
mesh.getFaces().setAll(faces);
PhongMaterial material = new PhongMaterial(Color.CORAL);
MeshView meshView = new MeshView(mesh);
meshView.setMaterial(material);
Group group = new Group(meshView, perspectiveCamera);
AnchorPane anchorPane = new AnchorPane(group);
Scene scene = new Scene(anchorPane, 640, 480, false, SceneAntialiasing.BALANCED);
scene.setCamera(perspectiveCamera);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
of course , you can set an image in difuse map , but it will be useless 'cause al uvs are pointing to 0,0
result :
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | jewelsea |
Solution 2 | Giovanni Contreras |