35 votes

java et libGDX / LWJGL taille du plein écran d'un jeu incorrecte pour plusieurs moniteurs sur Ubuntu

Je travaille sur un projet de jeu libGDX (bibliothèque au-dessus de LWJGL) et j'utilise l'IDE Intellij IDEA depuis plusieurs postes de travail différents :

  • Ordinateur portable Windows 7 x64 avec deux écrans (1920x1080 et 1600x1200), nVidia GT540M.
  • Ubuntu 12.04 LTS sur un ordinateur portable avec un seul écran (1366x768), graphique intégré Intel.
  • Ubuntu 12.04 LTS sur un bureau avec deux écrans (1920x1080 et 1280x1024), nVidia GTS 450.

J'utilise l'OpenJDK pour Java 6 sur les boîtes Ubuntu, et Sun/Oracle Java 6 sur la boîte Windows (j'ai entendu dire que Java 6 était celui à utiliser pour la compatibilité avec Android).

Lors du fonctionnement en plein écran :

  • Ordinateur portable Windows 7 : fonctionne bien.
  • Ordinateur portable Ubuntu : fonctionne bien.
  • Bureau Ubuntu : l'image d'arrière-plan est affichée en grand, et seule une partie tient sur l'écran. +

En y regardant de plus près, je vois que les appels à Gdx.graphics.getHeight() et Gdx.graphics. getWidth() renvoient la taille du rectangle nécessaire pour couvrir les deux écrans, dans mon cas 3200x1080, mais quand je dis à mon jeu de fonctionner en plein écran, il n'utilise qu'un seul des écrans, donc les caméras sont réglées sur 1920x1080, mais le mouvement de la caméra et le panoramique de la carte en mosaïque pensent qu'ils ont 3200x1080 pour travailler, ce qui rend les choses déformées et inutilisables (puisque le personnage peut sortir de l'écran vers la droite).

Je suppose que mon problème vient en fait des tailles renvoyées par l'appel getScreenSize() de awt.Toolkit, mais je ne sais pas comment l'interroger plus en profondeur pour obtenir la taille de l'écran qu'il utilisera réellement lorsque je passerai en plein écran.

Mon DesktopStarter obtient la taille de l'écran et définit le mode plein écran comme suit :

    LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
    Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
    cfg.width = screenDimension.width;
    cfg.height = screenDimension.height;
    cfg.fullscreen = true;
    new LwjglApplication(new Game1(), cfg);

Existe-t-il une solution pour obtenir la hauteur/largeur de l'affichage dans lequel le "plein écran" sera effectivement lancé ?

Le problème que je rencontre, c'est qu'en exécutant le fichier game.jar, en quittant le jeu, puis en l'exécutant à nouveau, de manière répétée, différents modes d'affichage apparaissent dans la liste des modes renvoyés par Gdx.graphics.getDisplayModes() -- comme P.T. l'a fait remarquer ci-dessous, il s'agit d'une enveloppe fine autour de la fonction LWJGL Display.getAvailableDisplayModes() . Pourquoi cela se produit-il ? Pourquoi un ensemble différent de modes serait-il présenté lors des exécutions suivantes sur Ubuntu ?

edit : selon la suggestion de P.T., mettre les références LWJGL en question, puisque cela semble être LWJGL qui fournit la liste des modes d'affichage.

Merci !

1voto

johnny Points 35
GraphicsDevice monitors[]=GraphicsEnvironment.getScreenDevices(); 

Dimension screen_resolution[monitors.length];

for (int monitorID = 0; monitorID < monitors.length; monitorID++)
{
    screen_resolution[monitorID] = new Dimension(monitors[monitorID].getDisplyMode().getWidth(),monitors[monitorID].getDisplyMode().getHeight());
}

1voto

cfstras Points 170

Je m'abstiendrais d'utiliser Toolkit.getDefaultToolkit() et utiliser uniquement lwjgl.util.Display.getAvailableDisplayModes() ou la méthode décrite par libgdx .

Une fois que vous avez configuré une fenêtre plein écran, récupérez sa taille (si votre méthode de configuration ne la connaît pas déjà) et n'utilisez que cette information à partir de là.

Si Display.getAvailableDisplayModes() change son ordre de tri sur différentes exécutions, il suffit de les retrier et d'utiliser le plus grand disponible ou d'utiliser un standard et de fournir des paramètres en jeu pour les changer.

0voto

Cristian Zaloj Points 27

Je m'abstiendrais complètement d'utiliser lwjgl. Cela peut sembler assez simple à première vue, mais si vous essayez d'ajouter des fonctionnalités plus avancées, vous réaliserez qu'un wrapper sur OpenGL ne vous donnera pas cette fonctionnalité, ou rendra le programme 3x plus lent. Je suggère de passer à c++ et OpenGL (si c'est une option). Vous serez surpris de sa simplicité. Sinon, les bibliothèques multiplateformes ont généralement ce genre de problèmes. Pour résoudre votre problème, vous devez arrêter de compter sur la bibliothèque pour déterminer les résolutions de vos fenêtres d'affichage. Au lieu de cela, faites l'énumération de tous les modes d'affichage possibles et choisissez le meilleur selon vous. Le résultat sera un comportement beaucoup plus défini et plus facile à déboguer que l'utilisation d'une configuration par défaut qui apparaît comme par magie. En général, vous voulez toujours être sûr de savoir quelles données vous utilisez. Pire encore, je viens de remarquer que vous utilisez un wrapper sur un wrapper. Cela complique à l'excès et ralentit le rendu bien plus que vous ne pouvez l'imaginer (20x en moyenne).

0voto

Bill Horvath II Points 366

Vous pourriez utiliser javafx.stage.screen pour contourner ce problème, mais vous devrez soit ajouter JavaFX si vous utilisez Java 6, soit passer à Java 7 (il est inclus dans le SDK Java 7).

Dans la documentation :

" Décrit les caractéristiques d'une destination graphique telle que le écran. Dans un environnement multi-écrans à dispositif virtuel dans lequel la dans lequel la zone du bureau peut s'étendre sur plusieurs écrans physiques, les limites des objets Screen sont relatives à l'objet Screen.primary.

Par exemple :

Rectangle2D primaryScreenBounds = (en anglais) Screen.getPrimary().getVisualBounds() ;

//définir les limites de la scène aux limites visibles de l'écran principal stage.setX(primaryScreenBounds.getMinX()) ; stage.setY(primaryScreenBounds.getMinY()) ; stage.setWidth(primaryScreenBounds.getWidth()) ; stage.setHeight(primaryScreenBounds.getHeight()) ;

stage.show() ;"

Il existe une variété d'autres méthodes ( getBounds(), getDpi(), getScreens() etc.) qui pourraient également vous être très utiles.

0voto

6a6179 Points 76

Vous pouvez peut-être obtenir les dimensions de l'écran que vous utilisez actuellement, afin d'obtenir les dimensions des écrans de tailles différentes. Il se peut que vous deviez faire les choses différemment pour des moniteurs de tailles différentes.

Peut-être que l'image d'arrière-plan est agrandie parce qu'elle pense qu'elle fonctionne toujours sur les autres écrans.

J'espère que cela vous aidera, si ce n'est pas le cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X