IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

2D Java Discussion :

Problème d'affichage avec la nouvelle version Java


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de anadoncamille
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 395
    Billets dans le blog
    1
    Par défaut Problème d'affichage avec la nouvelle version Java
    Bonjour,

    je développe un jeu vidéo dans lequel l'affichage des personnages se fait par superposition de couches de peau ou de vêtements colorées.

    Depuis l'installation de la nouvelle version de Java, j'ai ce genre affichage , dont les couleurs sont affreuses et surtout mal affichées :



    A quoi est-ce dû, avez vous déjà vu ce genre de bug ?

    Le principe d'affichage que j'utilise est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Pour chaque couche à afficher (du corps aux vêtements les plus extérieurs) {
     
    dessinerVersionNoirEtBlanc();
    ajouterMasqueCouleur();
     
    FinPour}
    Donc pour chaque couche, je dessine d'abord une base noir et blanc de l'image à colorer. Puis je crée un rectangle de la couleur à afficher. Je masque ce rectangle avec la couche alpha du vêtement et je superpose cette image en utilisant une combinaison de bits.

    Habituellement, avec les anciennes version, les couleurs sont douces, là on dirait qu'il applique un négatif de la couleur au dessus de certains seuils.

    Je n'arrive pas à comprendre, les spécifications ont-elle été modifiées ou est-ce temporaire ? J'ai vu le même bug chez un ami qui venait d'installer la dernière version de Java.

    Qu'est donc ce bug ?

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ton affichage se fait-il directement sur les composant visibles de la fenetre? Si oui, es-tu bien certain de faire ces opération à l'intérieur du Thread d'affichage? Beaucoup de bug "curieux" concernant les interfaces graphique sont du à des problèmes de concurrence entre un Thread de dessin et le Thread awt qui travaillent en meme temps sur les composants...

    L'idéal pour bien voir le problème serait une partie réduite du code gérant l'affichage et peut etre un screenshot comparatif avec la version "qui fonctionne" de java

  3. #3
    Expert confirmé

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 818
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 818
    Par défaut
    Salut,

    A tout hasard, tu as essayé en désactivant DirectDraw, avec un petit:

    en paramètre de ta commande java?
    Pour voir...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  4. #4
    Membre expérimenté
    Avatar de anadoncamille
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 395
    Billets dans le blog
    1
    Par défaut
    Beaucoup de bug "curieux" concernant les interfaces graphique sont du à des problèmes de concurrence entre un Thread de dessin et le Thread awt qui travaillent en meme temps sur les composants...
    j'ai désactivé le thread d'affichage awt, je suis en monotache sur une JFrame modifiée pour faire du plein écran, donc à priori, ça ne vient pas de là. En plus, sur les anciennes versions de JRE ou JDK, ça fonctionne correctement, c'est dans la dernière version que le bug apparait. J'ai réinstallé une ancienne version et ça fonctionne à nouveau.

    Voici un screenshot qui montre des couleurs plus habituelles :



    Pour le paramètre D3D, je vais essayer, mais ça ne m'emballe pas, je risque d'y perdre en performances, non ?

    Pour la partie de code que je suppose défectueuse, la voici, mais ça fait longtemps que j'y avais pas travaillé :

    La classe contenant la méthode de dessin est une encapsulation d'image avec des paramètres pour la charger au bon moment.
    L'image contenue s'appelle image.
    Le paramètre drawnBounds est un Rectangle qui indique la zone utile de l'image, c'est à dire la partie intérieure non vide de l'image.
    Pour les paramètres de méthode, x et y sont les coordonnées où on veut afficher, et le tableau de couleurs indique quelles couleurs seront utilisées pour la superposition du dégradé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void draw(Graphics2D g, int x, int y, Color[] c) {
        if (image == null)
          load();
        g.drawImage(image, x + drawnBounds.x, y + drawnBounds.y, null);
        PaintToolkit.drawAdditionnalGradient(g, image, c, x + drawnBounds.x, y + drawnBounds.y);
      }
    Vient ensuite le service de la classe PaintToolkit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    // ajoute la couche colorée sur une image
      public static void drawAdditionnalGradient(Graphics2D g, BufferedImage i, Color[] c, int x, int y) {
        int w = i.getWidth();
        int h = i.getHeight();
        BufferedImage b0 = DirectBufferIO.createBuffer(w, h, Transparency.TRANSLUCENT);
        BufferedImage b1 = DirectBufferIO.createBuffer(w, h, Transparency.TRANSLUCENT);
        Graphics2D g0 = b0.createGraphics();
        Graphics2D g1 = b1.createGraphics();
     
        int alpha = c[0].getAlpha();
        if (alpha < 255)
          g0.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)alpha / 255f));
        g0.drawImage(i, 0, 0, null);
        PaintToolkit.fillOpaqueGradient(g1, c, new Rectangle(0, 0, w, h));
        b1.getAlphaRaster().setRect(b0.getAlphaRaster());
        g.drawImage(b1, x, y, null);
     
        g0 = null;
        g1 = null;
        DirectBufferIO.flushBuffer(b0);
        DirectBufferIO.flushBuffer(b1);
      }
     
    // remplit un rectangle avec un tableau de dégradés rendus opaques
      public static void fillOpaqueGradient(Graphics2D g, Color[] c0, Rectangle b) {
        Color[] c = new Color[c0.length];
        for (int i = 0 ; i  < c0.length ; i++)
          c[i] = ColorToolkit.setAlpha(c0[i], 255);
        fillGradient(g, c, b);
      }
     
    // remplit un rectangle avec un tableau de dégradés
      public static void fillGradient(Graphics2D g, Color[] c, Rectangle b) {
        int n = c.length - 1;
        if (n == 0) {
          fillGradient(g, c[0], c[0], b);
          return;
        }
        int h = b.height / n;
        n--;
        Rectangle r = new Rectangle(b.x, b.y, b.width, h);
        for (int i = 0 ; i < n ; i++) {
          fillGradient(g, c[i], c[i + 1], r);
          r.y += h;
        }
        r.height = b.y + b.height - r.y;
        fillGradient(g, c[n], c[n + 1], r);
      }
     
    // remplit un rectangle avec un dégradé de c0 à c1
      private static void fillGradient(Graphics2D g, Color c0, Color c1, Rectangle r) {
        Paint p = g.getPaint();
        if (c0.getRGB() != c1.getRGB())
          g.setPaint(new GradientPaint(r.x, r.y, c0, r.x, r.y + r.height, c1));
        else
          g.setColor(c0);
        g.fillRect(r.x, r.y, r.width, r.height);
        g.setPaint(p);
      }

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par anadoncamille Voir le message
    j'ai désactivé le thread d'affichage awt, je suis en monotache sur une JFrame modifiée pour faire du plein écran
    Euh... Que veux-tu dire par là exactement ?
    Comment fait tu pour désactiver le thread d'affichage ????

    Citation Envoyé par anadoncamille Voir le message
    En plus, sur les anciennes versions de JRE ou JDK, ça fonctionne correctement, c'est dans la dernière version que le bug apparait. J'ai réinstallé une ancienne version et ça fonctionne à nouveau.
    Les bugs lié aux accès concurrents sont non seulement difficile à débugger, mais également très fluctuant. Dans certain cas cela pourrait marcher mais cela ne veut pas dire que le code est correct

    Est-ce que tu utilises bien le méthode paint()/paintComponent() d'AWT/Swing (selon le cas) ?

    a++

  6. #6
    Membre expérimenté
    Avatar de anadoncamille
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 395
    Billets dans le blog
    1
    Par défaut si si si !
    je publierai un code allégé et commenté de la frame en question, mais je n'utilise pas paint mais la méthode BufferStrategy.show().

    Voici la méthode de dessin :

    Soit EAppli une interface contenant entre autres les méthodes suivantes :
    - live(); : fait un tour de calculs
    - draw(Graphics2D g, Rectangle r); : dessine dans le graphics g pour le rectangle r

    buffStrat est le BufferStrategy de la JFrame.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      private void liveAppli(EAppli ap) {
        ap.live();
        ap.draw((Graphics2D)buffStrat.getDrawGraphics(), drawBounds);
        if ((!buffStrat.contentsLost()) && (!buffStrat.contentsRestored()))
          buffStrat.show();
      }
    Voici maintenant l'initialisation de la frame :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
      public KFrame(int width, int height, int depth, EAppli app) {
        super("");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            exit();
          }
        });
        setUndecorated(true);
        setResizable(false);
        setFocusable(true);
        setVisible(true);
        DisplayMode displayMode = chooseDisplayMode();
        DisplayModeToolkit.setFullScreen(this, displayMode);
        createBufferStrategy(3);
        buffStrat = getBufferStrategy();
        drawBounds = getBounds();
      }
    et la méthode pour le plein écran :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
      public static boolean setFullScreen(Window wi, DisplayMode dm) {
        boolean ok = graphicsDevice.isFullScreenSupported();
        if (ok)
          graphicsDevice.setFullScreenWindow(wi);
        else
          return false;
        ok = graphicsDevice.isDisplayChangeSupported();
        if (ok) {
          try {
            graphicsDevice.setDisplayMode(dm);
          }
          catch (Exception e) {
            currentDisplayMode = startingDisplayMode;
            graphicsDevice.setDisplayMode(startingDisplayMode);
            graphicsDevice.setFullScreenWindow(null);
            return false;
          }
        }
        else
          return false;
        currentDisplayMode = dm;
        return true;
      }
    Mais je ne crois pas que le bug vienne de là, seuls les personnages colorés par code sont buggés, les autres s'affichent normalement.

    Ce que j'envisage actuellement est plutôt une redéfinition du paramètre SRC_OVER qui effectue la combinaison des images.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec la nouvelle version de Qt
    Par cedrix57 dans le forum Débuter
    Réponses: 1
    Dernier message: 17/02/2011, 15h22
  2. Problème d'affichage avec une nouvelle librairie
    Par reito dans le forum Struts 1
    Réponses: 0
    Dernier message: 22/07/2010, 12h22
  3. problème d'affichage avec printf
    Par sorari dans le forum C++
    Réponses: 12
    Dernier message: 08/03/2005, 18h30
  4. Réponses: 6
    Dernier message: 19/10/2004, 13h46
  5. Problème d'affichage avec trace
    Par WriteLN dans le forum Flash
    Réponses: 10
    Dernier message: 22/10/2003, 16h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo