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 :

Chargement d'une texture a partir de la mémoire


Sujet :

DirectX

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Chargement d'une texture a partir de la mémoire
    Bonjour,

    Je voudrais savoir comment on charge une texture directX 8 a partir de la mémoire et non a partir d'un fichier. Ce serais a partir d'une structure TStream.

    Si vous ne savez pas comment charger a partir de TStream, vous pouvez tout de même me donnez des indications.

    Dans la documentation ,il y a quelques fonction qui pourrait être utiles:
    - CreateTexture; cette fonction crée la texture et alloue la mémoire cepandant comment la remplir avec mon image ?
    - D3DXCreateTextureFromFileEx; pour creer la texture partir d'un bitmap.
    - D3DXCreateTextureFromFileInMemory; j'arrive pas a l'utiliser parceque je ne connais pas la structure du fichie en mémoire
    - D3DXCreateTextureFromResource; idme je ne connais pas la structure d'une resource

    Comment vous faite pour charger plusieures textures à partir d'un unique fichier ?

    Merci - Logramme

  2. #2
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    D3DXCreateTextureFromFileInMemory; j'arrive pas a l'utiliser parceque je ne connais pas la structure du fichie en mémoire
    il s'agit simplement d'un fichier image (bmp, jpg, tga) charge integralement en memoire, donc tu lui passes un pointeur sur le debut du fichier en memoire. de meme pour la ressource, c'est un objet charge dans l'executable dans l'editeur de ressources.

    je ne sais pas ce qu'est une TStream (c'est borland??)
    par contre je peux te dire que pour charger une texture d'une autre facon que possible par les fonctions D3DX, il faut creer la texture
    avec les fonctions d3d (CreateTexture), faire un lock sur la texture pour recuperer un pointeur sur le debut de la memoire de la texture, et ecrire directement en memoire (attention il faut faire tes calculs de conversion coordonnees->emplacement memoire toi-meme bien entendu mais je suppose que c'est a ta portee si tu fais de la prog DirectX ). Attention, le format de ton fichier en memoire n'est en general pas le meme que celui utilise par D3D donc n'oublie pas de convertir (rgb et rgba, argb, 32 bits 16 bits, palette, etc..).
    Tu dois egalement lui dire de faire le calcul des niveaux de mipmaps si tu veux utiliser le mipmapping sur ta texture. Il y a une fonction dediee dans D3DX je crois sinon, tu peux le faire a la main si tu as une fonction un peu meilleure pour calculer le reechantillonnage ou si cela a deja ete fait en pretraitement.

    LeGreg

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Merci pour la réponse. Pouvez vous me dire comment on fait pour charger un fichier en mémoire et récuperer son pointeur.

    Est ce que c'est ça ?

    FILE *fichier;
    fichier = fopen("monfichier.bmp","r");
    D3DXCreateTextureFromFileInMemory(...,fichier,...);

    Merci - Logramme

  4. #4
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    ARGH non

    quand je parle de fichier charge en memoire je ne parle pas de pointeur vers une structure FILE (qui ne contient aucune donnee du fichier mais juste le descripteur de fichier systeme) mais un fichier INTEGRALEMENT CHARGE EN MEMOIRE (sous forme raw, bref du binaire brut).

    Et ca c'est si tu veux utiliser les fonctions de conversions automatiques de D3DX.

    Si tu as un format un peu exotique (png, ..) tu devras ecrire ton convertisseur toi-meme (a partir du flux issu d'un decompresseur).

    Si tu n'as aucune idee a quoi ressemble un convertisseur, voici un exemple de code qui charge un fichier de texture tga dans une texture D3D:

    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
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    CmError LoadTextureTGA(char *_strFile, LPDIRECT3DTEXTURE8* ppTexture)
    {
        struct _stat stat_buf;
        char buf[256];
        CmError cmError;
        TGA_HEADER *header;
        void *buffer;
     
        header = new TGA_HEADER;
        if (header==NULL)
        {
            _snprintf(buf,256,"chargement de %s: memoire insuffisante",_strFile);   
            _RPTF1(_CRT_WARN, "%s\n", buf);
            return CmError(buf);
        }
     
        FILE* fFile = fopen(_strFile,"rb");
        if (fread(header,sizeof(TGA_HEADER),1,fFile) != 1) 
        {
            delete header;
            fclose(fFile);
            _snprintf(buf,256,"chargement de %s: le fichier ne possède pas d'entete TGA valide",_strFile);  
            _RPTF1(_CRT_WARN, "%s\n", buf);
            return CmError(buf);
        }
     
        //pas egal car on peut rajouter des données à la fin du fichier
        //si erreur vérifier la taille du champ 1 = identification length ! ici on suppose 0!
        if ( stat_buf.st_size < (int)(sizeof(TGA_HEADER) + header->height*header->width*header->pixel_size/8))
        {
            delete header;
            fclose(fFile);
            _snprintf(buf,256,"chargement de %s: la taille du fichier ne correspond pas à la description du header",_strFile);  
            _RPTF1(_CRT_WARN, "%s\n", buf);
            return CmError(buf);
        }   
     
        buffer = new char[header->height*header->width*header->pixel_size/8];
        if (buffer == NULL)
        {
            delete header;
            fclose(fFile);
            sprintf(buf,"chargement de %s: header corrompu ou memoire insuffisante",_strFile);  
            _RPTF1(_CRT_WARN, "%s\n", buf);
            return CmError(buf);
        }
     
        if (fread(buffer,header->height*header->width*header->pixel_size/8,1,fFile) != 1) 
        {
            delete header;
            delete[] buffer;
            fclose(fFile);
            sprintf(buf,"chargement de %s: erreur en cours de chargement",_strFile);    
            _RPTF1(_CRT_WARN, "%s\n", buf);
            return CmError(buf);
        }
     
        fclose(fFile);
     
        HRESULT hr; 
     
        if (header->pixel_size == 32 ) //cool il y a de l'alpha
        {
            D3DFORMAT d3dFormat ;
            if (pcmCore->cmDeviceParameters.iDevice_Texturebpp == 16) 
                d3dFormat = D3DFMT_A4R4G4B4;
            else
                d3dFormat = D3DFMT_A8R8G8B8;
     
            //level DEFAULT = 0, mipmap genere a la suite..
            if (FAILED(hr = D3DXCreateTexture(pd3dDevice, header->width, header->height, 0,
                0, d3dFormat,
                D3DPOOL_MANAGED, ppTexture )))
            {
                delete header;
                delete[] buffer;
                sprintf(buf,"chargement de %s: la création de la texture a échouée",_strFile);  
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            D3DSURFACE_DESC Desc;
            hr = (*ppTexture)->GetLevelDesc(0,&Desc);
            if (FAILED(hr) || Desc.Format != d3dFormat) {
                sprintf(buf,"Format Texture indisponible : %s!!",_strFile);
                (*ppTexture)->Release();
                (*ppTexture) = NULL;
     
                delete header;
                delete[] buffer;
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            D3DLOCKED_RECT d3dlr;
            hr = (*ppTexture)->LockRect( 0, &d3dlr, NULL, 0 );
            if (FAILED(hr)) {
                sprintf(buf,"Impossible de locker Texture %s!!",_strFile);
                (*ppTexture)->Release();
                (*ppTexture) = NULL;
                delete header;
                delete[] buffer;
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            //ATTENTION: pour les TGA il faut renverser l'ordre des lignes, c con mais c comme ca !
            if (Desc.Format == D3DFMT_A8R8G8B8) 
            {
                BYTE *pBuffer;
                BYTE *pBits = (BYTE *)d3dlr.pBits;       
                for (int j=(header->height-1);j>=0;j--)
                {
                    pBuffer = (BYTE*)buffer + j*header->width*header->pixel_size/8;
                    memclone(pBits,pBuffer,header->pixel_size*header->width/8);
                    pBits+= header->width*header->pixel_size/8;
                }
            } else if (Desc.Format == D3DFMT_A4R4G4B4) {
                BYTE *pBuffer;
                WORD *pBits = (WORD *)d3dlr.pBits;       
                for (int j=(header->height-1);j>=0;--j)
                {
                    pBuffer = (BYTE*)buffer + j*header->width*header->pixel_size/8;
                    for (int i=0;i<header->width;++i)
                    {
                        //on met l'alpha:
                        *pBits = (*pBuffer)>>4;
                        *pBits |= ((*(++pBuffer))>>4)<<4;
                        *pBits |= ((*(++pBuffer))>>4)<<8;
                        *pBits |= ((*(++pBuffer))>>4)<<12;
                        ++pBits;++pBuffer;
                    }
                }
            }
            (*ppTexture)->UnlockRect(0);
        }
        else // pas d'alpha 
        {
            D3DFORMAT d3dFormat;
            if (pcmCore->cmDeviceParameters.iDevice_Texturebpp == 16) 
                d3dFormat = D3DFMT_R5G6B5;
            else
                d3dFormat = D3DFMT_R8G8B8;
     
            //level DEFAULT = 0, mipmap genere a la suite..
            if (FAILED(hr = D3DXCreateTexture(pd3dDevice, header->width, header->height, 0,
                0, d3dFormat,
                D3DPOOL_MANAGED, ppTexture )))
            {
                delete header;
                delete[] buffer;
                sprintf(buf,"chargement de %s: la création de la texture a échouée",_strFile);  
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            D3DSURFACE_DESC Desc;
            hr = (*ppTexture)->GetLevelDesc(0,&Desc);
            if (FAILED(hr) || 
                (Desc.Format != D3DFMT_R8G8B8 
                && Desc.Format != D3DFMT_X8R8G8B8
                && Desc.Format != D3DFMT_R5G6B5) ) {
                sprintf(buf,"Le périphérique ne supporte pas ce format de texture %s!!",_strFile);
                (*ppTexture)->Release();
                (*ppTexture) = NULL;
                delete header;
                delete[] buffer;
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            D3DLOCKED_RECT d3dlr;
            hr = (*ppTexture)->LockRect( 0, &d3dlr, 0, 0 );
     
            if (FAILED(hr)) {
                sprintf(buf,"Impossible de locker Texture %s!!",_strFile);
                (*ppTexture)->Release();
                (*ppTexture) = NULL;
                delete header;
                delete[] buffer;
                _RPTF1(_CRT_WARN, "%s\n", buf);
                return CmError(buf);
            }
     
            if (Desc.Format == D3DFMT_R8G8B8) 
            {
                //ATTENTION: pour les TGA il faut renverser l'ordre des lignes, c con mais c comme ca !
                BYTE *pBuffer;
                BYTE *pBits = (BYTE *)d3dlr.pBits;       
                for (int j=(header->height-1);j>=0;--j)
                {
                    pBuffer = (BYTE *)buffer + j*header->width*header->pixel_size/8;
                    for (int i=0;i<header->width;++i)
                    {
                        //on met l'alpha:
                        *pBits = *pBuffer;
                        *(++pBits) = *(++pBuffer);
                        *(++pBits) = *(++pBuffer);
                        ++pBits;++pBuffer;
                    }
                }
            } else if (Desc.Format == D3DFMT_X8R8G8B8) {
                //ATTENTION: pour les TGA il faut renverser l'ordre des lignes, c con mais c comme ca !
                BYTE *pBuffer;
                BYTE *pBits = (BYTE *)d3dlr.pBits;       
                for (int j=(header->height-1);j>=0;--j)
                {
                    pBuffer = (BYTE*)buffer + j*header->width*header->pixel_size/8;
                    for (int i=0;i<header->width;++i)
                    {
                        //on met l'alpha:
                        *pBits = *pBuffer;
                        *(++pBits) = *(++pBuffer);
                        *(++pBits) = *(++pBuffer);
                        *(++pBits) = 0xFF;
                        ++pBits;++pBuffer;
                    }
                }            
            } else if (Desc.Format == D3DFMT_R5G6B5) {
                //ATTENTION: pour les TGA il faut renverser l'ordre des lignes, c con mais c comme ca !
                BYTE *pBuffer;
                WORD *pBits = (WORD *)d3dlr.pBits;       
                for (int j=(header->height-1);j>=0;--j)
                {
                    pBuffer = (BYTE*)buffer + j*header->width*header->pixel_size/8;
                    for (int i=0;i<header->width;++i)
                    {
                        *pBits  =  (*pBuffer)>>3;
                        *pBits |= ((*(++pBuffer))>>2)<<5;
                        *pBits |= ((*(++pBuffer))>>3)<<11;
                        ++pBits;++pBuffer;
                    }
                }            
            }
            (*ppTexture)->UnlockRect(0);
        }
     
        // LEGREG : Generate Mipmap levels Qualite haute (plus long)
        if (FAILED(D3DXFilterTexture(*ppTexture,NULL,0,D3DX_FILTER_TRIANGLE))) {
            sprintf(buf,"chargement de %s: erreur lors de la creation des mipmaps",_strFile);
            (*ppTexture)->Release();
            (*ppTexture) = NULL;
            delete header;
            delete[] buffer;
            return CmError(buf);
        };
     
        delete header;
        delete[] buffer;
     
        return NullErrorConst;
    }
    LeGreg

  5. #5
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Avec C++ builder :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    TMemoryStream * l_stream = new TMemoryStream();
    l_stream->LoadFromFile("c:\\toto.bmp");
    l_stream->Position = 0;
    D3DXCreateTextureFromFileInMemoryEx(...., l_stream->Memory, l_stream->Size, .....);
    delete l_stream;

  6. #6
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    C'est le code d'un programme de test qui met juste en valeur la façon de rattacher le stream avec la fonction directX.

    si tu préfères voici la fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void loadFromStream(TStream * _stream)
    {
              D3DXCreateTextureFromFileInMemoryEx(...., l_stream->Memory,  l_stream->Size, .....); 
    }
    le reste étant un exemple d'appel de cette fonction

  7. #7
    JEG
    JEG est déconnecté
    Membre éclairé
    Avatar de JEG
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 211
    Points : 727
    Points
    727
    Par défaut
    Maintenant j'aimerai faire la fonction inverse, c à dire à partir d'une texture reconstituer un stream correspondant à l'image (en vu d'en faire Graphics::TBitmap, pour ceux qui connaissent builder), est-ce possible ? Si oui comment ?

Discussions similaires

  1. OpenGL et Qt : Chargement d'une texture
    Par 0_Azerty_0 dans le forum OpenGL
    Réponses: 1
    Dernier message: 22/05/2013, 17h17
  2. Réponses: 9
    Dernier message: 28/06/2011, 17h19
  3. Réponses: 7
    Dernier message: 23/12/2008, 18h30
  4. [c#] chargement d'une texture a partir d'un objet Image
    Par elguignardo dans le forum DirectX
    Réponses: 2
    Dernier message: 29/03/2006, 09h18
  5. Réponses: 2
    Dernier message: 06/02/2006, 09h12

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