FAQ JavaFXConsultez toutes les FAQ
Nombre d'auteurs : 4, nombre de questions : 507, dernière mise à jour : 2 novembre 2016 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum JavaFX de http://java.developpez.com ainsi que l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Comment tester si la 3D est supportée sur ma plateforme ?
- Comment puis-je afficher de la 3D ?
- Comment activer la 3D sur la scène ?
- Quels types de nœuds puis-je placer dans une scène 3D ?
- Quelles sont les primitives 3D ?
- Comment importer un modèle 3D créé dans un logiciel externe ?
- Quelles sont les sources d'éclairage 3D ?
- Comment changer la couleur d'une source d'éclairage 3D ?
- Comment éteindre une source d'éclairage 3D ?
- Comment afficher un cube ?
- Comment afficher un rendu de type fil de fer ?
- Comment spécifier le mode d'occultation des faces ?
- Qu'est-ce qu'un matériau ?
- Comment changer la couleur d'un objet ?
- Comment appliquer une texture sur un objet ?
- Comment spécifier la couleur spéculaire de l'objet ?
Pour tester si la 3D est supportée par votre plateforme, vous pouvez invoquer la méthode isSupported() de la classe javafx.application.Platform en lui passant en paramètre la valeur javafx.application.ConditionalFeature.SCENE3D :
Code Java : | Sélectionner tout |
Platform.isSupported(ConditionalFeature.SCENE3D);
À l'heure actuelle (JDK8_u20), la 3D n'est pas disponible sur la version ARM du JDK destinée aux plateformes embarquées (ex. : Raspberry Pi, etc.).
Vous pouvez afficher de la 3D de deux manières :
- dans la scène : dans ce cas l’intégralité de votre affichage sera en 3D ;
- dans une sous-scène : un nœud graphique de type javafx.scene.SubScene. Utiliser un tel objet permet par exemple d'avoir une IU 2D classique avec une vue 3D dans une partie de l'affichage.
Le fonctionnement de la 3D est identique, quel que soit le mode d'affichage choisi.
La scène supporte de base le positionnement dans l'espace 3D, ce qui veut dire que vous pouvez d'ores et déjà commencer à disposer vos nœuds graphiques dans l'espace. Cependant, par défaut, la scène utilise une caméra parallèle (javafx.scene.ParallelCamera), c'est-à-dire une caméra qui ne permet pas de voir l'effet de profondeur, car l'axe Z est perpendiculaire à la surface de l’écran (le plan XY) en tout point de cette surface.
Pour activer l'effet de profondeur, il faut placer sur la scène une caméra de perspective en créant une instance de la classe javafx.scene.PerspectiveCamera :
Code Java : | Sélectionner tout |
scene.setCamera(new PerspectiveCamera());
Désormais, les tangentes des axes Z convergent vers un seul et même point qui se trouve derrière l’écran. L'effet de perspective fait que l’œil voit la profondeur des objets.
Note : une caméra est un nœud graphique, elle peut donc être placée dans la scène ou un noeud parent et déplacée ou transformée ce qui permet de changer le point de vue sur les objets rendus dans la scène 3D (par exemple pour faire des flyby).
Vous pouvez placer n'importe quel type de nœud dans une scène 3D : formes géométriques 2D, contrôles, groupes et gestionnaires de mise en page, graphiques de données statistiques, vues sur image, médias ou web, et bien sûr des primitives 3D ou des sources d’éclairage 3D.
Cependant, certaines fonctionnalités propres à la 3d, telles que l'ombrage ou la coloration dues aux sources d’éclairage ne seront pas opérantes sur les formes 2D ou les contrôles.
Les primitives 3D sont des classes qui héritent toutes de la classe abstraite javafx.scene.shape.Shape3D. Ces objets sont des nœuds graphiques, il est donc possible de les positionner et de les manipuler, de leur faire subir des effets ou transformations comme n'importe quel autre nœud de SceneGraph.
Il actuellement existe quatre types de primitives 3D :
- Box - une brique ou une boite définie par ses dimensions width sur l'axe X, height sur l'axe Y et depth sur l'axe Z. Peut servir à créer des cubes si les trois valeurs sont identiques. Le centre de la boite réside en (0, 0, 0) ;
- Sphere - une sphère définie par son rayon radius. Le centre de la sphère réside en (0, 0, 0) ;
- Cylinder - un cylindre défini par son rayon radius dans le plan Z ainsi que sa hauteur height suivant l'axe Y et le nombre de facettes divisions. Le nombre de facettes n'est pas modifiable après création et sa valeur minimale est de 3, sa valeur par défaut de 15. Le centre du cylindre réside en (0, 0, 0) ;
- MeshView - une vue sur un objet de type Mesh qui représente une surface 3D crée à partir d'un nuage de points et de coordonnées de texture.
Des exemples de filtres d'importation de modèles 3D aux formats Obj, Maya, 3D Studio Max et Collada sont fournis dans les exemples et démos de JavaFX disponibles, tout comme les exemples du JDK, en tant que téléchargements annexes du JDK chez Oracle.
Des filtres d'importation de modèles 3D en Mesh sont disponibles gratuitement pour une utilisation éducative, commerciale ou personnelle sur le site InteractiveMesh.org d'Impressum.
Il est possible de positionner des sources d’éclairage dans la scène. Ces objets héritent de la classe abstraite javafx.scene.LightBase. Ces objets sont des nœuds graphiques, il est donc possible de les positionner et de les manipuler, de leur faire subir des effets ou transformations comme n'importe quel autre nœud de SceneGraph.
Il existe deux types de sources de lumière :
- AmbientLight - une lumière ambiante qui baigne toute la scène d'une lumière provenant de toutes les directions à la fois éclairant toutes les faces de tous les objets ;
- PointLight - une source d'éclairage ponctuelle qui émet des rayons de lumière dans toutes les directions à partir de cette position. Les faces qui ne sont pas exposées à cette source de lumière ne sont pas éclairées.
Par défaut, une source de lumière impacte automatiquement tous les nœuds 3D qui sont dans la même arborescence du SceneGraph qu'elle (tous les nœuds 3D qui sont des sous-nœuds du nœud parent de la source de lumière). Cependant, une source d’éclairage dispose d'une liste observable scope qui peut contenir la liste de tous les nœuds graphiques impactés par cette source de lumière. Si cette liste scope d'une source de lumière n'est pas vide, les nœuds qui ne sont pas dans la liste ne sont pas éclairés par cette source.
Note : actuellement (JDK8_25), pour des raisons de performances, un nœud 3D ne peut pas être impacté par plus de trois sources de lumière différentes. Les sources de lumière additionnelles seront ignorées.
Lorsqu'une scène ou une sous-scène contient des objets 3D, mais qu'on n'y a pas positionné de source de lumière, elle dispose d'une source d’éclairage par défaut : une lumière ponctuelle blanche est placée sur la position de la caméra et qui éclaire tous les objets de la scène.
Il est possible de changer la couleur d'une source de lumière en changeant la valeur de sa propriété color.
Par exemple :
Code Java : | Sélectionner tout |
light1.setColor(Color.BLUE);
Cette instruction fait que notre source de lumière light1 émet désormais de la lumière bleue sur les objets contenus dans sa liste observable scope.
Il est possible d'activer ou de désactiver une source de lumière en changeant la valeur de sa propriété lightOn.
Par exemple :
Code Java : | Sélectionner tout |
light1.setLightOn(false);
Cette instruction éteint la source de lumière light1 : celle-ci cesse désormais d’éclairer les objets contenus dans sa liste observable scope.
Le code suivant crée un cube et le positionne dans la scène :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class Main extends Application { @Override public void start(Stage primaryStage) { // Création du cube. final int size = 75; final Box cube = new Box(size, size, size); cube.setTranslateX(175); cube.setTranslateY(150); // Configuration du nœuds racine. final Pane root = new Pane(); root.setStyle("-fx-background-color: black;"); root.getChildren().setAll(cube); // Configuration de la scène. final Scene scene = new Scene(root, 350, 300, false, SceneAntialiasing.BALANCED); scene.setCamera(new PerspectiveCamera()); // Configuration de la fenêtre. primaryStage.setTitle("Test d'affichage 3D"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } |
Ce qui nous donne :
Évidemment, notre cube étant positionné au centre de la scène, nous ne voyons que la face avant et donc il ressemble à un simple rectangle gris.
Nous allons rajouter des animations pour mieux apercevoir les autres facettes du cube :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | final TranslateTransition translateTransition = new TranslateTransition(Duration.seconds(10), cube); translateTransition.setInterpolator(Interpolator.LINEAR); translateTransition.setAutoReverse(true); translateTransition.setCycleCount(TranslateTransition.INDEFINITE); translateTransition.setFromY(0); translateTransition.setToY(300); final RotateTransition rotateTransition = new RotateTransition(Duration.seconds(5), cube); rotateTransition.setInterpolator(Interpolator.LINEAR); rotateTransition.setCycleCount(TranslateTransition.INDEFINITE); rotateTransition.setByAngle(360); rotateTransition.setAxis(Rotate.Y_AXIS); final ParallelTransition animation = new ParallelTransition(translateTransition, rotateTransition); animation.jumpTo(Duration.seconds(5)); animation.play(); |
Ce qui nous donne :
Ici, une animation de translation va déplacer le cube suivant l'axe Y ce qui permettra d'apercevoir les faces du dessus et du dessous grâce à la perspective tandis que l'animation de rotation va nous permettre de voir les faces initialement cachées sur les côtés et à l’arrière du cube. Nous avons bien un affichage en 3D !
Modifions maintenant l’éclairage pour ajouter une source de lumière ambiante :
Code Java : | Sélectionner tout |
1 2 3 | final AmbientLight ambientLight = new AmbientLight(Color.WHITE.deriveColor(0, 0, 0.25, 0)); ambientLight.getScope().add(cube); root.getChildren().add(ambientLight); |
Ce qui nous donne :
Puisque nous avons ajouté une source d’éclairage dans la scène, la source de lumière par défaut n'est plus active. La seule lumière provient donc de l’éclairage ambiant que nous venons d’insérer et qui éclaire toutes les faces de la même manière. On n'arrive plus à distinguer les faces les unes des autres.
Corrigeons cela en ajoutant une nouvelle source de lumière, ponctuelle cette fois :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 | final PointLight pointLight = new PointLight(Color.ORANGE); pointLight.setTranslateX(300); pointLight.setTranslateY(300); pointLight.setTranslateZ(-300); pointLight.getScope().add(cube); root.getChildren().addAll(pointLight); |
Ce qui nous donne :
Notre cube est désormais éclairé par une source de lumière ponctuelle de couleur orange qui se trouve sur le côté inférieur droit de la scène et hors de l’écran. Les faces orientées vers la droite, le haut ou l’arrière par rapport à ce point ne sont donc pas baignées de lumière orange.
Il est possible d'activer le mode rendu fil de fer (wireframe) sur un nœud 3D en modifiant la valeur de sa propriété drawMode.
Par exemple :
Code Java : | Sélectionner tout |
cube.setDrawMode(DrawMode.LINE);
Ce qui nous donne :
Ici, nous avons activé le rendu fil de fer sur notre cube, nous voyons donc que chaque face du cube est en fait constituée de deux triangles mis côte à côte dans le même plan.
Par défaut, la propriété drawMode est à la valeur DrawMode.FILL qui fait que les faces sont complètement remplies par le matériau placé sur le cube.
Il est possible de modifier le mode d'occultation des faces d'un nœud 3D en modifiant la valeur de sa propriété cullFace.
Par exemple :
Code Java : | Sélectionner tout |
cube.setCullFace(CullFace.FRONT);
Ce qui nous donne :
Ici, les faces du cube dirigées vers l'utilisateur sont occultées et on aperçoit l’intérieur du cube.
Les valeurs possibles sont :
- CullFace.BACK - la valeur par défaut. Les faces qui ne sont pas dirigées vers l'utilisateur ne sont pas visibles ;
- CullFace.FRONT - les faces du cube dirigées vers l'utilisateur sont occultées ; on voit l’intérieur des objets ;
- CullFace.NONE - aucune occultation ; on voit un peu un mélange de toutes les faces.
Un matériau est un objet de type javafx.scene.paint.Material qui permet d'appliquer des propriétés visuelles sur les faces d'un nœud 3D, par exemple sa couleur diffuse (sa couleur de base), sa texture, son taux spéculaire (combien il réfléchit de lumière reçue), etc. À l'heure actuelle, la seule implémentation présente dans l'API est la classe javafx.scene.paint.PhongMaterial.
Il est possible de spécifier le matériau d'un nœud 3D en changeant la valeur de sa propriété material.
Pour spécifier une couleur unie sur un objet (sa couleur diffuse), il suffit de créer une instance de type PhongMaterial avec la couleur donnée et de l'appliquer à la propriété material de notre nœud 3D.
Par exemple :
Code Java : | Sélectionner tout |
1 2 | final PhongMaterial material = new PhongMaterial(Color.CYAN); cube.setMaterial(material); |
Ce qui nous donne :
Désormais, les faces de notre rectangle sont de couleur cyan au lieu d’être simplement grises.
Il est également possible de modifier la valeur de la propriété diffuseColor de l'objet de type PhongMaterial.
Pour spécifier une texture sur un objet (sa diffuse map), il suffit de créer une instance de type PhongMaterial avec une Image contenant la texture choisie et de l'appliquer à la propriété material de notre nœud 3D.
Par exemple :
Code Java : | Sélectionner tout |
1 2 3 | final Image diffuseMap = new Image(getClass().getResource("1-Marble-Texture-1.jpg").toExternalForm()); final PhongMaterial material = new PhongMaterial(Color.WHITE, diffuseMap, null, null, null); cube.setMaterial(material); |
Ce qui nous donne :
L'image utilisée pour la texture provient du site Naldz Graphic
Désormais, les faces de notre rectangle sont texturées avec l'image que nous avons utilisée. Ici la couleur diffuse s'applique sur la texture, si la couleur diffuse avait été Color.CYAN par exemple, la texture serait apparue bleutée.
Il est également possible de modifier la valeur de la propriété diffuseMap de l'objet de type PhongMaterial.
Pour spécifier la couleur spéculaire d'un objet (la couleur qui est émise par la lumière qui se réfléchit sur la surface de l'objet comme sur une couche de vernis), il suffit de créer une instance de type PhongMaterial et de modifier sa propriété specularColor en lui donnant comme valeur la couleur désirée.
Par exemple :
Code Java : | Sélectionner tout |
material.setSpecularColor(Color.RED);
Ce qui nous donne :
Désormais, notre cube réfléchira la lumière en émettant de la couleur rouge.
Il est également possible de modifier la valeur de la propriété specularPower de l'objet de type PhongMaterial pour modifier l’intensité de la réflexion.
Par exemple :
Code Java : | Sélectionner tout |
material.setSpecularPower(50);
La valeur par défaut de la propriété specularPower est 32.
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.