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

avec Java Discussion :

Lire un fichier binaire structuré.


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut Lire un fichier binaire structuré.
    Bonjour, j'espère que vous allez bien ? Je suis nouveau ici, mais je programme en Java depuis 2 bonnes années, je pense donc avoir les bases, même si l'OpenGL reste encore un peu flou pour moi. En effet, je me suis mis en tête, depuis plusieurs semaines, de lire un fichier de modèle 3d animé au format mdl (format utilisé par le vieux jeux-vidéo Quake I). Un tutoriel en Français explique très bine comment s'y prendre, mais le langage utilisé ici est le C, or je n'y ai jamais touché. J'ai donc essayé de retranscrire à ma manière, un code aux effets semblables, cette fois-ci en Java. Voici le lien du tutoriel, et ici mon début de code.
    J'ai donc parfaitement réussi à lire la partie "header" du fichier binaire en question. Mais dès qu'il s'agit de lire la variable data du type GLUbyte, c'est la catastrophe ! J'ai cru comprendre qu'en Java, on pouvait l'interpréter comme un tableau de byte, mais rien à faire, je ne parviens à la lire. Des pistes ? Merci d'avance !

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    package fr.plaigon.mdlloader;
     
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.channels.FileChannel;
     
    import com.google.common.io.LittleEndianDataInputStream;
     
    import fr.plaigon.md5loader.GLApp;
     
    public class MDLReader
    {
        public String filepath = "";
        public String filename = "";
     
        public MDLReader(String fileName)
        {
            loadobject(fileName);
        }
     
        public void loadobject(String objfilename)
        {
            if (objfilename != null && objfilename.length() > 0)
            {
                String[] pathParts = GLApp.getPathAndFile(objfilename);
                filepath = pathParts[0];
                filename = pathParts[1];
     
                try
                {
                    loadobject(GLApp.getInputStream(objfilename));
                }
                catch (Exception e)
                {
                    System.out.println("MDLReader.loadobject(): Failed to read file: " + objfilename + " " + e);
                }
            }
        }
     
        public void loadobject(InputStream in)
        {
            if (in != null)
            {
                int skinWidth, skinHeight;
                FileInputStream fis = (FileInputStream)in;
                try
                {
                    LittleEndianDataInputStream dis = new LittleEndianDataInputStream(fis);
     
                    //Header start
     
                    System.out.println(dis.readInt());//ident or "magical number"
                    System.out.println(dis.readInt());//version
     
                    //Scale model vector coordinates
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
     
                    //Translation model vector coordinates
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
     
                    System.out.println(dis.readFloat());//Sphere radius
     
                    //Eyes model vector coordinates
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
                    System.out.println(dis.readFloat());
     
                    System.out.println(dis.readInt());//num_skins
                    System.out.println(skinWidth = dis.readInt());//skinwidth
                    System.out.println(skinHeight = dis.readInt());//skinheight
                    System.out.println(dis.readInt());//num_verts
                    System.out.println(dis.readInt());//num_tris
                    System.out.println(dis.readInt());//num_frames
                    System.out.println(dis.readInt());//synctype
                    System.out.println(dis.readInt());//flags
                    System.out.println(dis.readFloat());//average size of triangles
     
                    System.out.println(dis.readInt());
                    for(int i = 0; i < skinWidth * skinHeight; i++)
                        System.out.println(dis.readByte());
     
                    //Header end
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
     
        }

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    Quelques petites questions/remarques :
    • Il serait bon de faire remonter l'exception dans la méthode appelante :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      public void loadobject(InputStream in) throws IOException {
          [...] // Enlever le try et le catch dans le code.
      }
    • Tu utilises LittleEndianDataInputStream qui n'est pas une classe standard de l'API, tu utilises Guava ? Dans ce cas tu n'as pas besoin de caster ton InputStream en FileInputStream ce qui t’évitera des soucis dans le futur si tu est amené a lire un fichier sur le réseau/le net/en streaming.

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      LittleEndianDataInputStream dis = new LittleEndianDataInputStream(in);
    • Est-il possible d'avoir un petit fichier mdl de référence/de test et avoir les valeurs principales qui vont être retournées pour que ceux qui vont tenter de répondre a ta question puissent t'aider.
    • GLubyte ce sont juste des byte non-signes ou c'est autre chose ?


    Et je te rappelle également que les flux doivent être fermés après lecture du fichier. Ce qui est être fait automatiquement en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    try (final InputStream input = GLApp.getInputStream(objfilename)) {
         loadobject(input);
    }
    Accessoirement, en fouillant bien on peut trouver des apps/libs pour lire des fichiers MDL (ici pour du MD2, le format de Quake 2 ou encore ici pour le format MD3 de Quake 3 par exemple) au cas ou tu préférerai ne pas implémenter la tienne. Bon souvent c'est du code assez ancien par contre.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    A noter la methode readFully() dans la classe LittleEndianDataInputStream de Guava qui permet de lire un tableau d'octet intégralement.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Salut bouye,
    premièrement merci de ta réponse, ensuite je viens d'ajouter les fermetures de flux, merci de me l'avoir rappelé. Ensuite, je n'ai pas de fichier type mdl, dans la mesure où je ne sais pas quelles sont les valeurs de mon modèle, peut-être devrais-je essayer de le lire en C comme dans le tuto, mais ça m'embête d'aller apprendre ce lange pour si peu :/
    GLuByte, c'est un byte non-signé d'après mes rapides recherches, ouep. Après je ne vois pas comment compléter la méthode readFully. Du coup je peux me contenter de LittleEndianDataInputStream#readUnsignedByte, avec ma boucle for ?

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 900
    Billets dans le blog
    54
    Par défaut
    Ah un moment il va quand meme falloir lire quelque chose histoire de verifier que cela marche et que la version Java sort les memes valeurs que la version C

    EDIT -

    Après je ne vois pas comment compléter la méthode readFully.
    Ben c'est quoi le soucis ???

    EDIT 2 -

    Ah rien n'indique la taille du tableau / taille de la texture ? Dans ce cas est-ce que c'est sensé se terminer par le caractère null ? si oui effectivement il faudra libre octet par octet.

    EDIT 3 -

    time est un tableau de dimension nb et data est un tableau de nb tableaux de dimensions skinwidth * skinheight.
    Ben tu connais la taille du tableau donc tu peux le pré-initialiser et utiliser la méthode...
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Certes mais c'est dans le cas d'un "mdl_groupskin_t", que data suit cette indication, or moi je suis sur un "mdl_skin_t". J'ai vite fait le programme dans code::blocks, et quand je print la variable data, avec ce code:
    https://pastebin.com/ZWqy6Tre
    la console me renvoie la valeur: 163588216. Du coup comment dois-je m'y prendre pour retrouver ça dans eclipse ? Je dois faire un readFully, ou une boucle for avec readUnsignedByte ? Merci d'avance ! =)

    EDIT: J'ai réussi à print mon tableau de byte, mais l'adresse mémoire de celui-ci affiché par la console eclipse est le suivant: [B@77afea7d. Comment comparer celui-ci à 163588216, sorti par code::blocks, pour vérifier qu'ils sont bien tous les deux identiques ??

Discussions similaires

  1. Lire un fichier binaire en connaissant sa structure
    Par procrastination dans le forum MATLAB
    Réponses: 2
    Dernier message: 17/10/2014, 15h39
  2. comment lire des fichiers binaires
    Par compton dans le forum Autres Logiciels
    Réponses: 8
    Dernier message: 06/07/2006, 12h03
  3. [C#] Lire un fichier binaire
    Par LE NEINDRE dans le forum Windows Forms
    Réponses: 1
    Dernier message: 02/06/2006, 18h08
  4. lire un fichier binaire 8bit apr 8bit
    Par lykim dans le forum Entrée/Sortie
    Réponses: 21
    Dernier message: 12/05/2006, 17h09
  5. [NIO]Lire un fichier binaire
    Par Info-Rital dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 25/07/2005, 07h50

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