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

DirectX Discussion :

Charger beaucoup de grosses textures -> plantage


Sujet :

DirectX

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut Charger beaucoup de grosses textures -> plantage
    Bonjour,
    Je suis en train de creer un jeu avec DirectX et pour l'accelerer un peu, je charge toutes mes textures au début. Actuellement, j'utilise des .png et je viens de rajouter un niveau. Mon probleme c'est que j'ai maintenant trop de texture et j'ai un D3DERR_OUTOFVIDEOMEMORY au bout d'un moment lorsque je charge mes textures...
    J'ai donc décider de convertir mes .png en .gif et là,
    D3DXCreateTextureFromFileEx me renvoie D3DXERR_INVALIDDATA dès la première image... pourquoi?
    Et si quelqu'un a une solution pour que je puisse garder mes .png, je suis preneur.

    merci d'avance

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je comprends pas trop ce que ça va changer d'avoir des gif à la place de png. Et je ne pense pas que D3DX sache lire les gif, d'où ton erreur.

    Tu ferais mieux d'utiliser des formats de texture optimisés, genre DXTC si ta carte le supporte.

    Et puis il faut le faire quand même pour exploser la mémoire vidéo en textures, ton niveau est énorme ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    Je me disais qu'en utilisant des gif, je réduirais la taille en KO de mes images et aussi la complexité mais apparement, ça ne donnera rien: j'ai d'abord converti en gif puis je suis revenu en png; ça a réduit leur taille de plus de la moitié mais j'ai encore eu ces problèmes de mémoire.

    Pour info, je charge 35 textures dont la plupart ont une résolution superieure à 720x1000. elles sont donc de grande taille (la plus grande fait 1248x1152).
    Je ne voit malheureusement pas comment diminuer ce nombre ni leur taille car chaque image est un spriteSheet d'ennemi ou du hero et les niveaux sont optimisés au max...
    Il n'y a pas moyen d'augmenter la mémoire allouée?

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je me disais qu'en utilisant des gif, je réduirais la taille en KO de mes images et aussi la complexité mais apparement, ça ne donnera rien: j'ai d'abord converti en gif puis je suis revenu en png; ça a réduit leur taille de plus de la moitié mais j'ai encore eu ces problèmes de mémoire.
    La taille des fichiers sur le disque importe peu, c'est la taille des textures en mémoire vidéo qu'il faut optimiser. Tu peux très bien avoir un gif, un png ou un bmp, si ta texture reste en ARGB 32 bits ça ne changera rien. Comme je te l'ai dit tu peux utiliser les formats compressés : avec le DXT5 les textures peuvent être 4 fois plus petites.
    Si c'est de la 2D, tu peux aussi éviter de créer les niveaux de mipmap.

    Pour info, je charge 35 textures dont la plupart ont une résolution superieure à 720x1000. elles sont donc de grande taille (la plus grande fait 1248x1152).
    Je ne voit malheureusement pas comment diminuer ce nombre ni leur taille car chaque image est un spriteSheet d'ennemi ou du hero et les niveaux sont optimisés au max...
    C'est quel genre de niveau ? Tu as une capture d'écran ? Parce que bon, tu pourrais peut-être réduire la taille de tes textures, à moins d'avoir besoin d'une très bonne qualité.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 267
    Points : 275
    Points
    275
    Par défaut
    'Alut.

    Il te faut absolument travailler avec des textures plus petites et/ou compressées et/ou ne les envoyer vers la carte graphique uniquement lorsque c'est nécessaire.

    A mon avis, ta carte graphique n'a pas assez de mémoire pour ces énormes textures. Et tu ne peux pas augmenter la taille de la mémoire de ta carte graphique.

    Pour info, je charge 35 textures dont la plupart ont une résolution superieure à 720x1000. elles sont donc de grande taille (la plus grande fait 1248x1152).
    Je ne voit malheureusement pas comment diminuer ce nombre ni leur taille car chaque image est un spriteSheet d'ennemi ou du hero et les niveaux sont optimisés au max...
    C'est quel genre de niveau ? Tu as une capture d'écran ? Parce que bon, tu pourrais peut-être réduire la taille de tes textures, à moins d'avoir besoin d'une très bonne qualité.
    Si ton niveau ne s'affiche pas sur l'écran dans son intégralité, tu peux aussi découper tes textures, et ne les envoyer que lorsque c'est nécessaire.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    le probleme c'est que mon niveau, ce n'est pas une image toute bete, c'est une page regroupant tous les types de décors. Par exempe une montagne dans mon jeu est crée par une matrice où chaque élément correspond à un rectangle du niveau. donc meme si mon niveau est tres grand, la taille de ma texture sera toujours la meme.
    Ci joint, deux images: par exemple, la texture est l'image Niveau.jpg et l'image est Ecran.jpg.
    Cela vous donnera une bonne idée de ce que je fais.
    Sinon, j'ai remarqué que sur un autre ordi, ça plantait aussi. pourtant, l'autre c'est un bete de course avec Vista et une bonne dose de memoire vidéo...
    Ca vient donc peut etre d'autre chose.
    Images attachées Images attachées   

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 267
    Points : 275
    Points
    275
    Par défaut
    OK.

    Pour info, ma carte graphique ne supporte pas les textures supérieures à 4096x4096 ( c'est une 7800GTX (mais certes que 256Mo)). Autre info une texture 4096x4096 en 32bits non compressés occupe 64Mo!! (si pas d'erreurs dans mes calculs). Les textures qu tu utilises sont vraiments énormes!

    tu peux aussi découper tes textures, et ne les envoyer que lorsque c'est nécessaire.
    En gros pourquoi ne pas avoir une petite texture pour l'herbe, une autre pour l'herbe avec des fleurs, etc... et ne les envoyers vers ta carte graphique que lorsque c'est nécessaire? Garde-les en mémoires systeme et envoye-les vers la mémoires vidéo quand tu en as besoin.

    Enfin sache que la doc du SDK directx conseille d'utiliser des textures 256x256 ou plus petites si possible (rubrique performance optimization).

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    35 tilesets de l'ordre de 1000x1000, si on prend 32x32 pour une tile, ça fait... environ 35000 tiles. Ca fait pas un peau beaucoup ? Et as-tu toujours besoin de tes 35 tilesets en même temps ?

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    Je veux bien ne les envoyer vers la carte que lorsque c'est nécéssaire mais comment? Si je fais un D3DXCreateTextureFromFileEx à chaque fois, ça prend trop de temps... il Y a un moyen de faire autrement? j'ai vu D3DXCreateTextureFromFileExInMemory; ça peut marcher? Comment ça s'utilise?
    Sinon, je peux aussi diminuer la taille de mes textures mais ça va forcement augementer le nombre... Ca risque de me poser le même probleme... non?

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 267
    Points : 275
    Points
    275
    Par défaut
    Sinon, je peux aussi diminuer la taille de mes textures mais ça va forcement augementer le nombre
    Oui, mais en diminuant la taille d'une tile. Je compte 10*13 tile sur la texture que tu nous donne. Avec une tile de taille 32*32, ça donne du 320*416 en taille de texture.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    Pour répondre à laurent, je n'utilise pour les niveaux que 3 tilesets d'une taille de 720x1000 avec un tile de 40x40. Les autres sont des spitesheets pour les ennemis. En fait, entre chaque niveau, je pourrais juste charger les textures que j'utilise mais ca met beaucoup de temps entre chaque niveau pour charger; c'est pour ça que je voulais tous charger au début pour les utiliser quand j'en ai besoin.

    Sinon, Albenejean, je ne comprend pas bien ce que tu veux dire: pour un niveau comme je l'ai dit, j'ai des tiles de 40x40 (celui que j'ai posté est celui d'un ancien jeu) et ils font 720x1000 (je te laisse calculer). je ne peux pas diminuer ce nombre ni la taille d'un tile. donc comment faire? séparer mon tileset en 2 ou 4?

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 267
    Points : 275
    Points
    275
    Par défaut
    Je veux bien ne les envoyer vers la carte que lorsque c'est nécéssaire mais comment? Si je fais un D3DXCreateTextureFromFileEx à chaque fois, ça prend trop de temps... il Y a un moyen de faire autrement? j'ai vu D3DXCreateTextureFromFileExInMemory; ça peut marcher? Comment ça s'utilise?
    Apparement, il suffirait de créer ta texture avec le flag D3DPOOL_MANAGED (d'après la doc, je n'ai pas testé...).
    Sinon tu peux aussi chercher ce que dit la doc sur UpdateTexture (je n'ai pas encore utilisé non plus).

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si tu n'as pas assez de mémoire vidéo il faudra de toute façon gérer ça intelligemment. Je ne pense pas qu'il y ait d'autre solution que de ne charger que les tilesets nécessaires au niveau courant.

    Tu as essayé quand même de passer tes textures en DXT5 ? Tu économiseras déjà 3/4 de la mémoire vidéo.

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 267
    Points : 275
    Points
    275
    Par défaut
    J'ai réalisé un petit test et j'ai réussi à créer 50 textures 2048*2048 et à en afficher une. Voilà le code:


    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
     
    m_Texture = new LPDIRECT3DTEXTURE9[50];
     
    if(FAILED( D3DXCreateTexture( 
                              m_D3DDevice, m_NbPointX, m_NbPointY, 1, 0,
                              D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
                              &m_Texture[0])))
        {
            return false;
        }
     
    for(int i=1;i<50;++i)
    {
        if(FAILED( D3DXCreateTextureFromFileEx(
                            m_D3DDevice, FileName.c_str(), 0, 0, 1, 0, 
                            D3DFMT_UNKNOWN, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 
                            0, NULL, NULL, &m_Texture[i]) ))
        {
            return false;
        }
    }
        if(FAILED(m_D3DDevice->UpdateTexture(m_DensityTexture[1], m_DensityTexture[0])))
        {
            return false;
        }
    et ça marche!

    Par contre si je passe à 75 textures ça plante (pas assez de mémoire pour créer les mipmap qu'il me dit). Pas assez de mémoire systeme?

  15. #15
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Note que pour de la 2D tu n'as pas besoin de mipmaps.

    Et... toujours pas intéressé par les formats compressés ?

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    De retour de bon matin:
    Merci pour ces réponses;
    Laurent, je suis interressé par ton format compressé mais je ne sais pas comment passe mes textures en DXT5 ni comment les utiliser... Une aide serait la bien venue. De plus, comment expliquer à ce cher DirectX que les mipmaps, on s'en fout... (en plus, je sais meme po ce que c'est )
    Albenejean, j'ai essayé avec en utilisant les mêmes options que toi dans le createSurface et j'ai planté au même endroit... sniff...

  17. #17
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Laurent, je suis interressé par ton format compressé mais je ne sais pas comment passe mes textures en DXT5 ni comment les utiliser...
    Change D3DFMT_A8R8G8B8 par D3DFMT_DXT5 par exemple, lorsque tu crées ta texture. Ca ne change rien d'autre, c'est juste un autre format interne pour ta texture.

    Tu peux tester si un format de texture particulier est supporté ou non par ta crate graphique avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool Supported = SUCCEEDED(Direct3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
    De plus, comment expliquer à ce cher DirectX que les mipmaps, on s'en fout... (en plus, je sais meme po ce que c'est )
    Les mipmaps sont des copies de ta texture, plus petites. Par exemple si tu as une texture de 256x256 et que tu crées toute la pyramide de mipmaps, le mipmap 1 fera 128x128, le mipmap 2 fera 64x64, etc... jusqu'à 1x1. Ensuite plus un triangle est éloigné de la caméra, plus on choisira un niveau de mipmap petit, ça permet de lisser les pixels lointains et d'éviter des effets pas toujours très beaux.
    Pour dire à DirectX de ne pas créer les niveaux de mipmap, il faut spécifier 1 au paramètre "NbMipmaps" à la fonction qui crée la texture (voir dans le SDK pour les détails).

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    Ok, j'ai essayé:
    Tout d'abord, je ne charge pas mes textures en D3DFMT_A8R8G8B8 directement, j'essaie d'abord en D3DFMT_A1R5G5B5 si ca plante en D3DFMT_A4R4G4B4 et si ça plante encore en D3DFMT_A8R8G8B8.
    J'ai donc rajouté en premier le D3DFMT_DXT5. Ce qui est bizarre, c'est que certaines textures passent bien mais d'autre non... etrange n'est ce pas si ça ne dépend que de la carte graphique...
    J'ai ensuite essayé de voir combien de texture de 256x256 je pouvais charger avant plantage et j'arrive à 377...
    Avec la methode de Albenejean (je me suis trompé dans le précédent post... le plantage était causé par une texture qui manquait...) je suis monté jusqu'à 3000 et apres j'ai stoppé... Mais si j'ai bien compris la methode, je charge ces textures dans la mémoire du system, je crée des textures vide dans la mémoire vidéo et je place la texture que j'ai besoin dans ma texture vide avec la fonction update. c'est bien ça?

  19. #19
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    J'ai donc rajouté en premier le D3DFMT_DXT5. Ce qui est bizarre, c'est que certaines textures passent bien mais d'autre non... etrange n'est ce pas si ça ne dépend que de la carte graphique...
    Les textures compressées sont soumises à certaines conditions (void SDK), notamment d'avoir des dimensions en multiples de 4 (car la compression fonctionne par blocs de 4x4 pixels).

    Avec la methode de Albenejean (je me suis trompé dans le précédent post... le plantage était causé par une texture qui manquait...) je suis monté jusqu'à 3000 et apres j'ai stoppé... Mais si j'ai bien compris la methode, je charge ces textures dans la mémoire du system, je crée des textures vide dans la mémoire vidéo et je place la texture que j'ai besoin dans ma texture vide avec la fonction update. c'est bien ça?
    C'est ça. Ca peut être une bonne alternative, si tu veux réduire les temps de chargement entre niveaux (il n'y a qu'un update par texture à faire, au lieu du chargement complet). Par contre ça suppose que les textures "vides" créées en mémoire vidéo ont déjà la taille qu'il faut pour recevoir les textures en mémoire système, taille qui n'a pas l'air d'être constante dans ton cas.

  20. #20
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 80
    Points : 39
    Points
    39
    Par défaut
    Ok merci beaucoup pour toutes ces précisions.
    Je vais faire un mix des deux solutions: je vais charger mes textures avec si possible D3DFMT_DXT5 (dans le pire des cas, j'augmente un peu la taille pour avoir le format qui convient)
    Je vais ensuite uniformiser la taille de tous mes spritesheet pour n'avoir aucun problème de taille pour ma texture vide.

    une dernier question: est ce que D3DFMT_DXT5 est moins lourd que D3DFMT_A1R5G5B5?

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/04/2014, 10h16
  2. [Texture] charger simplement des png?
    Par kacedda dans le forum OpenGL
    Réponses: 6
    Dernier message: 08/03/2006, 08h40
  3. copier une petite texture sur une grosse texture
    Par gaut dans le forum DirectX
    Réponses: 5
    Dernier message: 15/10/2004, 22h12
  4. Grosses, tres grosses textures
    Par Invité(e) dans le forum DirectX
    Réponses: 8
    Dernier message: 06/10/2004, 18h50
  5. Charger 16x16 sur une texture 256x256
    Par Johngame dans le forum DirectX
    Réponses: 4
    Dernier message: 06/03/2004, 17h16

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