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 :

Creation de surfaces sur une zone de mémoire déja allouée


Sujet :

DirectX

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut Creation de surfaces sur une zone de mémoire déja allouée
    Bonsoir, je dois creer une surface IDERCTDRAWSURFACE7, mais qui doit représenter un espace en mémoire déja alloué. Je definis pour cela avant d'appeller CereateSurface :

    - la taille de la structure DDSURFACEDESC2
    - la hauteur et la largeur de la surface
    - le pitch
    - la taille de la strructure decrivant le format des pixels
    - le format des pixels
    - le pointeur vers la zone de mémoire
    - les caps avec ddscaps = DDSCAPS_OFFSCREENPLAIN

    mais lors de l'appel de la fonction j'ai l'erreur

    DDERR_INVALIDCAPS
    One or more of the capability bits passed to the callback function are incorrect.

    Qu'est cee que j'ai oublié ou mal fait ?

  2. #2
    mat.M
    Invité(e)
    Par défaut
    *soit la carte vidéo ne supporte pas la résolution demandée :
    ex 800 x 600 en 24 bits alors que la carte vidéo ne comporte que 4 Mo de RAM graphique.

    * soit la surface est plus grande que la résolution d'écran , ce qui ne fonctionne pas

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Mais je ne crée pas de surface dans la mémoire vidéo puisque l'espace de la surface est déja alloué. Et la surface n'est pas cencé représenter une zone affichable, donc peu importe sa taille non ? En fait, j'ai peut etre mal traduis la description de OFFSCREENPLAIN (je suis nul en anglais). Mais quoiqu'il en soit, si je met rien ca pose problème, si je met rien dans ddscaps, j'ai la même erreur. La résolution de ma surface est 320 * 200 * 8 bits

  4. #4
    mat.M
    Invité(e)
    Par défaut
    mais qui doit représenter un espace en mémoire déja alloué
    Est-ce par malloc ,new ???
    Pour allouer une surface , il faut utiliser la méthode Create.
    Après pour copier un tampon il faut utiliser les méthodes Lock et Unlock

  5. #5
    mat.M
    Invité(e)
    Par défaut
    Un exemple tiré de ddutil.cpp

    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
     
    extern "C" IDirectDrawSurface7*
    DDLoadBitmap( IDirectDraw7* pdd, LPCSTR szBitmap, int dx, int dy)
    {
        HBITMAP                 hbm;
        BITMAP                  bm;
        DDSURFACEDESC2          ddsd;
        IDirectDrawSurface7    *pdds;
     
        //
        //  Try to load the bitmap as a resource, if that fails, try it as a file
        //
        hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx,
                                  dy, LR_CREATEDIBSECTION);
        if (hbm == NULL)
            hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
                                      LR_LOADFROMFILE | LR_CREATEDIBSECTION);
        if (hbm == NULL)
            return NULL;
        //
        // Get size of the bitmap
        //
        GetObject(hbm, sizeof(bm), &bm);
        //
        // Create a DirectDrawSurface for this bitmap
        //
        ZeroMemory(&ddsd, sizeof(ddsd));
        ddsd.dwSize = sizeof(ddsd);
        ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
        ddsd.dwWidth = bm.bmWidth;
        ddsd.dwHeight = bm.bmHeight;
        if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
            return NULL;
        DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
        DeleteObject(hbm);
        return pdds;
    }

  6. #6
    mat.M
    Invité(e)
    Par défaut
    La résolution de ma surface est 320 * 200 * 8 bits
    Attention !!! Ce mode vidéo est de moins en moins supporté !!
    Il vaut mieux configurer en 640*480 et "blitter" en 320*200 ( plutôt 320*240)

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    lool mais c'est fini oui ?? Bon, je voulais pas expliquer, mais je vais etre obligé. Je suis en train d'ecrire un émulateur x86. Pour l'instant en emulation du rmode, je crée une mémoire "virtuelle" de 1 Mo et a l'adresse 0A0000h j'ai la mémoire du vga. Pour l'instant je m'iteresse au mode 13h donc 320*200*8. Mais ce ne serait qu'une mauvaise idée de copier la mémoire virtuelle vers une surface en utilisant Lock(). C'est une perte de temps inutile. Mais il y a la solution dans l'aide dede DirectX en fait :

    Creating Client Memory Surfaces

    il me manquait ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
                               DDSCAPS_SYSTEMMEMORY;
    Et efectivement on utilise DirectDrawCreate mais en specifiant les flags DDSD_LPSURFACE, DDSD_PITCH et DDSD_PIXELFORMAT. Et en definissant lpSurface vers la zone déja allouée. Bon j'ai eu quelques problèmes, mais j'ai fini par trrouver. Juste que maintenant j'ai des problème pour le blit de cette surface. M'enfin ca je vais chercher un peu, j'ai pas eu trop le temps.

    Sinon tu peux me dire si l'alpha blending est une fonction 2D ? si elle est implementée dans DirectX9 ? ou si on est obligé d'utiliser les textures ?

    Et puis pour la question "allouée par new, malloc ?", par GlobalAlloc :)

  8. #8
    mat.M
    Invité(e)
    Par défaut
    Mais ce ne serait qu'une mauvaise idée de copier la mémoire virtuelle vers une surface en utilisant Lock(). C'est une perte de temps inutile
    Ce n'est pas une perte de temps inutile . C'est LA SEULE METHODE pour accéder directement à une surface....

    Sinon tu peux me dire si l'alpha blending est une fonction 2D ?
    Pour dire la vérité je ne sais pas du tout.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    nop j'y arrive maintenant. j'ai une surface à laquelle je peux accedder sans Lock() puisuqe c'est moi qui est alloué l'espace affichable de la surface avant d'appeller CreateSurfac

  10. #10
    mat.M
    Invité(e)
    Par défaut
    j'ai une surface à laquelle je peux accedder sans Lock() puisuqe c'est moi qui est alloué l'espace affichable de la surface avant d'appeller CreateSurfac
    D'accord et comment vas-tu faire pour afficher la surface à l'écran ???
    Parce que à part Lock et UnLock il n'ya pas d'autres moyens , sinon bonjour les plantages.

    Il ne faut pas perdre de vue que lorsqu'on verrouille toute surface DDraw avec Lock c'est qu'elle est effectivement verrouillée c.a.d. que , comme on peut le penser c'est une zone en mémoire et que le Système d'exploitation n'y touche pas ( pas de déplacement de la zone mémoire vers une autre ).

    Avant sous DOS on déclarait un FAR POINTER avec la macro MK_FP à l'adresse A000:000 .
    Mais c'etait sous DOs , ça ne bougeait pas.
    Avec win32 et Direct X , l'OS fait "sa cuisine".


    Il yaurait un autre moyen c'est de passer par le GDI avec SetDIBBits et obtenir un HDC pour une surface mais c'est à mon avis plus lent

  11. #11
    mat.M
    Invité(e)
    Par défaut
    Mais ce ne serait qu'une mauvaise idée de copier la mémoire virtuelle vers une surface en utilisant Lock(). C'est une perte de temps inutile
    Je le répéte encore : on ne fait pas par exemple memcpy d'un bloc vers un autre comme on le ferait sous DOS !!!
    Sous win32 et Direct X ça n'existe pas

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Mais j'ai jamais dit que je fesait ca. d'ailleurs je ne connaissait pas memcopy (et j'ai jamais programmé pour dos)

  13. #13
    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
    l'Alpha blending n'est pas supporte
    par Ddraw il faut le faire a la main (il doit
    y avoir du code sur le web) ou utiliser des textures
    dans Direct 3D.

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Oki Merci Le Greg. M'enfin si c'est en software, mieux vaut plutot utiliser les textures (Sinon l'algo de l'alpha blending en sois n'est pas bien compliqué)

  15. #15
    mat.M
    Invité(e)
    Par défaut
    tout cela ne nous dit pas comment tu fais pour accélerer l'affichage d'une surface avec un buffer.....

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    M'enfin !

    Imagine que tu es une zonne de mémoire que ton programme utilise
    Il se trouve que les données sur cette zone sont srtucturée comme une surfacec 8 bits palettisé
    Imagine encore qu'il serait plus long que ton programme ecrive sur une surface dont DirectDraw gère l'allocation plutot qu'il l'ecrive là ou il le fait actuellement

    Alors tu peux creer une surface mais dont lpsurface ne pointe pas vers une zone de emémoire gérée par DirectDraw, mais vers ta zone de mémoire a toi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    +--------+  Surfacee->Lock()  +---------+ PrimarySurface->BltFast() +--------------+
    | Buffer |  --------------->  | Surface | ------------------------> | Frame Buffer |
    +--------+                    +---------+                           +--------------+
     
    +--------+  PrimarySurface->BltFast() +--------------+
    | Buffer |  ------------------------> | Frame Buffer |
    +--------+                            +--------------+
    Buffer c'est la zone que toi tu alloue, Surface, une surfacee intermediaire. Quelle methoded tu préfères ??


    Tout ca n'est pas très compliqué, je comprends pas ce qui te gène.

  17. #17
    mat.M
    Invité(e)
    Par défaut
    Alors tu peux creer une surface mais dont lpsurface ne pointe pas vers une zone de emémoire gérée par DirectDraw, mais vers ta zone de mémoire a toi.
    OK.
    Mais dans d'autres modes vidéos ,cela ne marchera pas à cause de l'alignement des octets en mémoire .

    Tout ca n'est pas très compliqué, je comprends pas ce qui te gène.
    Absolument rien.
    Mais il ya risque de plantages...
    ça ne marchera pas sur toutes les machines...
    Faites comme vous voulez l'ami.
    Si Microsoft dans son SDK préconise Lock/Unlock c'est pas pour faire joli !
    Il ya bien une raison...

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    certes, mais tu peux lire ce que dit microsoft un truc du style "Creating systeme memory surfaces". Il faut que je retrouve le titre exact, mais c'est tout a fait prévu.

Discussions similaires

  1. evenement sur une zone jTextfieled.
    Par Essefi_K dans le forum JBuilder
    Réponses: 1
    Dernier message: 24/03/2006, 10h09
  2. Blit d'une surface sur une autre...?
    Par Invité dans le forum SDL
    Réponses: 6
    Dernier message: 14/06/2005, 18h24
  3. menu popup sur une zone de text
    Par jesus144 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 26/05/2005, 23h15
  4. se déplacer sur une zone de liste
    Par bb62 dans le forum IHM
    Réponses: 12
    Dernier message: 31/01/2005, 10h47
  5. [c++ builder] creation de surface sur TPanel
    Par JEG dans le forum DirectX
    Réponses: 7
    Dernier message: 23/09/2002, 22h41

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