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

DevIL Discussion :

[DEVIL] Jpeg à l'envers


Sujet :

DevIL

  1. #1
    Membre confirmé
    [DEVIL] Jpeg à l'envers
    Bonjour à vous.

    Mon moteur charge parfaitement pour les bmp et les tga (que j'ai codé moi même). Mais j'avais envie d'accélérer le développement de mon moteur 3d, je suis passé à DevIL, et ça coince sur les jpeg : l'image est à l'envers, avec on dirait qu'il y a comme un glColor sur le bleu.
    Image originale:

    Bug:

    Comme vous pouvez le voir, la texture blanche (blanc.jpg) est bien blanche. D'où peux venir le problème ? Y a t-il inversion des couleurs dans un jpeg ?

    J'utilise ce code pour ajouter la texture à OpenGL dans le manager de textures:
    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
     
    GLuint        id = 0;                     // id de la texture à retourner
    GLubyte     *pixels = 0;              // tableau de pixels de la texture
    int            width, height;            // dimensions de la texture
    int            bpp = 0;                   //bit per pixel
    ...
    LoadJPG(szFilename.c_str(), &pixels, &width, &height, &bpp);
    ...
    // Création et initialisation de la texture opengl
    glGenTextures( 1, &id );
    glBindTexture( GL_TEXTURE_2D, id );
    g_log.Write(LOG_WARNING, "MTextureManager:: ID = %i", id);
     
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
     
    //seulement là pour tester les jpeg
    mode = GL_RGBA;
    components = 4;
     
    gluBuild2DMipmaps(GL_TEXTURE_2D, components, width, height, mode, GL_UNSIGNED_BYTE, pixels);
    La fonction de chargement du jpeg avec devIL (largement inspirée du tutoriel sur le YES engine):
    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
     int    MTextureManager::LoadJPG(const char *name, unsigned char **pixels, int *width, int *height, int *bpp)
    {
        g_log.Write(LOG_FAILURE, "MTextureManager:: Début DevIL");    
     
    // Génération d'une nouvelle texture
        unsigned int Texture;
        ilGenImages(1, &Texture);
        ilBindImage(Texture);
     
        // Chargement de l'image
        if (!ilLoadImage(const_cast<ILstring>(name)))
        {
            g_log.Write(LOG_FAILURE, "MTextureManager:: Erreur DevIL : l'appel à ilLoadImage a échoué sur %s", name );
            return 0;
        }
     
        // Récupération de la taille de l'image
        *width = ilGetInteger(IL_IMAGE_WIDTH);
        *height = ilGetInteger(IL_IMAGE_HEIGHT);
        *bpp = ilGetInteger(IL_IMAGE_BPP);
     
        g_log.Write(LOG_PLAINTEXT, "MTextureManager:: Width = %i Height = %i, Bpp = %i", *width, *height, *bpp);
     
        // Récupération des pixels de l'image
        *pixels = new unsigned char[(*width) * (*height) * (*bpp)];
        memcpy(*pixels, ilGetData(), (*width) * (*height) * (*bpp));
     
        // Suppression de la texture
        ilBindImage(0);
        ilDeleteImages(1, &Texture);
     
        g_log.Write(LOG_PLAINTEXT, "MTextureManager:: DevIL fin");
        return 1;
    }
    Merci !

  2. #2
    Membre émérite
    Il faut ajouter

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    		ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
    		ilEnable(IL_ORIGIN_SET);


    Qui permet d'indiquer à DevIL de charger toutes les images avec la même origine.

  3. #3
    Membre confirmé
    Le soucis, c'est que c'est déjà fait : j'ai repris le code du tutoriel sur le Yes Engine :

    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
    bool MTextureManager::Initialize( void )
    {
        ////////////////////////////DevIL Init...
        // Initalisation de DevIL
        ilInit();
     
        // On indique que l'origine des images se trouve sur le coin haut-gauche
        ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
        ilEnable(IL_ORIGIN_SET);
     
        // On autorise l'écrasement de fichiers déjà existants, pour la sauvegarde
        ilEnable(IL_FILE_OVERWRITE);
     
        // On force le chargement des images en 32 bits BGRA
        ilSetInteger(IL_FORMAT_MODE, IL_BGRA);
        ilEnable(IL_FORMAT_SET);
     
        //Le reste ne concerne plus DevIL
     
        //////////////////////////
        // vide la base de données
        ReleaseTextures();
        ...
    En recopiant le code, j'ai remarqué que je charge avec IL_BGRA. Sous OpenGL, je n'ai trouvé que GL_RGB ou GL_RGBA. En mettant IL_RGBA, la couleur est parfaite, mais le jpeg toujours à l'envers.
    Il va falloir que je convertisse moi même ? Pourtant, avec un bmp, il n'y a pas de problème...

    Je serai allé aussi vite en codant le chargement de jpeg moi là...

  4. #4
    Membre habitué
    ... Sauf qu'il ne faut pas mettre UPPER_LEFT mais LOWER_LEFT (le repère OpenGL est en bas à gauche). Le YesEngine retourne manuellement les pixels de l'image une fois chargée pour une utilisation avec OpenGL.

  5. #5
    Membre confirmé
    Merci beaucoup, c'est résolu !
    Comment galérer alors que ça ne tient qu'à un paramètre que l'on voie tellement qu'il est invisible...

  6. #6
    Membre émérite
    Le YesEngine retourne manuellement les pixels de l'image une fois chargée pour une utilisation avec OpenGL.
    La c'est peut être un "bug" du yes::engine, car autant le faire directement avec DevIL

    Laurent ?

  7. #7
    Rédacteur

    Le YesEngine retourne manuellement les pixels de l'image une fois chargée pour une utilisation avec OpenGL.
    Non.

  8. #8
    Membre habitué
    Citation Envoyé par Laurent Gomila Voir le message
    Non.
    Je me souviens avoir vu un Flip()
    Je vais vérifier.

    EDIT:
    http://loulou.developpez.com/tutorie.../partie5/#L4.2
    J'ai confondu avec la sauvegarde

    Mais alors Laurent, il y a quand même quelque chose que je ne comprends pas ; pourquoi tu n'as pas besoin de retourner ton image avec OpenGL, alors que LapinGarou lui, doit utiliser LOWER_LEFT ?

    RE-EDIT: grillé.

  9. #9
    Rédacteur

    C'est uniquement dans la fonction de sauvegarde, pas au chargement

  10. #10
    Membre confirmé
    Oui, tiens, c'est vrai ça, pourquoi je dois la retourner moi ??

  11. #11
    Membre actif
    J'ai exactement le même problème que lapingarou. Je me suis aussi fortement inspiré du Yes engine
    J'aimerai aussi savoir d'ou ca vient. afin de corriger
    J'ai pas envie de trainer un test d'extension .jpg pour remettre à l'endroi

  12. #12
    Membre confirmé
    J'ai gardé le test (pas si grave, puisque c'est au chargement des textures, on perd quoi, 1 millionème de seconde ? ), mais j'ai cherché 3 jours en comparant au Yes Engine, et je n'ai rien remarqué. Donc, je ne sais toujours pas pourquoi je dois changer le paramètre de coin. (Ou plus simple, tu peux sauver tous les jpg flipés, mais c'est pas pratique quand on les créé ou les modifie plus tard)

  13. #13
    Membre actif
    J'ai remarqué qu'en fait j'ai des jpeg chargées à l'endroit et d'autres chargées à l'envers. Je suis sur de ce que je dit car j'ai des textures jpeg sur des modele 3D: certaines sont bien placées et d'autres non alors qu'avant tout était parfait.
    Mon ancien systeme de chargement "à la main" chargeait toutes les images dans le même sens!!

    Doit cela vient t'il?

  14. #14
    Membre confirmé
    Bon, j'ai un nouveau bug. En voulant faire mumuse avec un heightmap de ET:QW, cela m'a révélé nouveau problème sur les jpeg et un sur les dds:


    Le jpeg du sol (le 2eme en bas à gauche) est de taille :2048x2048.
    Le jpeg en bas à gauche de plante est de taille 256*256, et lui aucun problème.
    La dernière image est 2048x2048 en format dds.
    La première image en bas à gauche est l'image en bmp, pour référence...

    Alors ? C'est DevIL qui fait les choses de traviole ? Ou bien j'ai rien compris finalement ? (J'ai beau réduire la taille de texture du sol, ça fait toujours cette espèce de demi-mirroir sur l'image)

    EDIT> Je viens d'y penser : serait ce un bug lors de la copie avec :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
        // Récupération des pixels de l'image
        *pixels = new unsigned char[(*width) * (*height) * (*bpp)];
        memcpy(*pixels, ilGetData(), (*width) * (*height) * (*bpp));
    Je mets mon code complet, si ça peut aider :

    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
    int MTextureManager::LoadImage(const char *name, unsigned char **pixels, int *width, int *height, int *bpp)
    {
        // Génération d'une nouvelle texture
        unsigned int Texture;
        ilGenImages(1, &Texture);
        ilBindImage(Texture);
        ilOriginFunc(IL_ORIGIN_LOWER_LEFT);    //bug sur jpg...?
        ilEnable(IL_ORIGIN_SET);
     
        // Chargement de l'image
        if (!ilLoadImage(const_cast<ILstring>(name)))
        {
            g_log.Write(LOG_FAILURE, "MTextureManager:: Erreur DevIL : l'appel à ilLoadImage a échoué sur %s", name );
            return 0;
        }
     
        // Récupération de la taille de l'image
        *width = ilGetInteger(IL_IMAGE_WIDTH);
        *height = ilGetInteger(IL_IMAGE_HEIGHT);
        *bpp = ilGetInteger(IL_IMAGE_BPP);
     
        //g_log.Write(LOG_PLAINTEXT, "MTextureManager:: Width = %i Height = %i, Bpp = %i", *width, *height, *bpp);
     
        // Récupération des pixels de l'image
        *pixels = new unsigned char[(*width) * (*height) * (*bpp)];
        memcpy(*pixels, ilGetData(), (*width) * (*height) * (*bpp));
     
        // Suppression de la texture
        ilBindImage(0);
        ilDeleteImages(1, &Texture);
     
        return 1;
    EDIT 2> En rajoutant ceci :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        if(strstr(name, ".jpg") || strstr(name, ".jpeg") || strstr(name, ".dds"))    
        {
            ilOriginFunc(IL_ORIGIN_UPPER_LEFT);    //bug sur bmp
        }
        if(strstr(name, ".bmp"))    
            ilOriginFunc(IL_ORIGIN_LOWER_LEFT);    //bug sur jpg... RHAAAAA !!
        ilEnable(IL_ORIGIN_SET);
    le jpg et le dds sont affichés presque normalement : il faut faire un flip vertical. Mais si je flip vertical, la texture du sol ne correspond plus au heightmap... Je fatigue là : c'est DevIL qui met le souk, ou bien mon moteur, ou les 2 ???

###raw>template_hook.ano_emploi###