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 :

Pb lors de l'accès à une surface DirectDraw


Sujet :

DirectX

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19
    Points : 7
    Points
    7
    Par défaut Pb lors de l'accès à une surface DirectDraw
    Bonjour à tous,

    J'utilise le mode 320x240x16 et je veux juste dessiner un rectangle rempli à l'écran.
    Le mode de couleurs utilisé est 565. Voici la méthode :

    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
    void DrawRectangle(int left, int top, int length, int height, WORD color)
    {
    	LockSurface();
     
    	int shift = 320 - length;
     
    	WORD *ptr = surface_pointer + top * 320 + left;
     
    	for (int y = 0; y < height; ++y)
    	{
    		for (int x = 0; x < length; ++x)
    			*ptr++ = color;
     
    		ptr += shift;
    	}
     
    	ReleaseSurface();
    }
     
    J'utilise les méthodes LockSurface et ReleaseSurface pour obtenir un pointeur sur la surface DirectDraw :
     
    BOOL LockSurface()
    {
    	DDSURFACEDESC2 ddsd;
     
    	dsd.dwSize = sizeof(ddsd);
     
    	HRESULT hr = g_backSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
     
    	surface_pointer = (WORD *) ddsd.lpSurface;
     
    	return hr == DD_OK;
    }
     
    void ReleaseSurface()
    {
    	g_backSurface->Unlock(NULL);
    }
    Cela marche nickek sur mon PC, mais sur celui d'un pote, seulement la moitié du rectangle
    est remplie et je ne comprends pas pourquoi. Bien entendu, j'ai pensé à des incompatibilités
    au niveau du mode graphique et j'ai réalisé quelques tests sur son PC : son mode d'encodage
    est aussi 565 et son pitch vaut aussi 640.

    Est-ce que avez idée de ce qui peut se passer ?

    Merci d'avance,
    Mark


    [Balises CODE rajoutées par Loulou24, merci d'y penser à l'avenir]

  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 : 40
    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
    A part le pitch, je ne vois pas ce que ça pourrait être. Tu es sûr que c'est le même ? Tu l'as vérifié comment ? Dans tous les cas tu devrais l'utiliser dans ton code, car le jour où il ne sera pas égal à la largeur de ta surface, tu auras ce genre d'erreur.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    Salut loulou,

    Voilà le code de test que j'ai utilisé pour tester le pitch et le mode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	lpDD->GetDisplayMode(&ddsd);
     
    	*outFile << "pitch = " << ddsd.lPitch << endl;
     
    	DWORD r = ddsd.ddpfPixelFormat.dwRBitMask;
    	DWORD g = ddsd.ddpfPixelFormat.dwGBitMask;
    	DWORD b = ddsd.ddpfPixelFormat.dwBBitMask;
     
    	*outFile << r << endl;
    	*outFile << g << endl;
    	*outFile << b << endl;
    Je stocke les valeurs dans un fichier (type ofstream). J'obtiens les
    valeurs suivantes :

    pitch = 640
    63488
    2016
    31

    Oui, je sais que je devrais utiliser le pitch dans mon code (et des masques
    différents selon que l'on est en 565 ou en 555) mais ça m'empêchera de
    réaliser des optimisations (comme des décalages au lieu des multiplications
    par 320). Pour l'instant, je vise surtout à faire quelque chose qui marche,
    je verrai après les éventuels problèmes de compatibilité. Mais là, j'avoue
    que ça me dépasse...

    A plus,
    Mark


    [Balises CODE encore rajoutées par Loulou24]

  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 : 40
    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
    Merci d'utiliser les balises CODE

    Il y a quelque chose qui me parait bizarre, ta surface fait 320 de largeur mais tu as un pitch de 640 (donc ils sont différents). Comment peux-tu avoir un résultat correct sans gérer cette différence ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    En fait, c'est un peu ce que je me demande...

    Il me semble bien qu'en C/C++, quand tu fais de l'arithmétique de pointeurs, c'est le compilateur qui va adapter l'offset ajouté/soustrait selon la taille de la donnée pointée. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int *i;
    int *j = i + 5; // ajoute en réalité 5 x 4 octets à la valeur du pointeur i
    Mais bon, je ferais mieux de me replonger dans un bon bouquin, je crois, car l'erreur a tout l'air de se trouver là... Mais ça fonctionne parfaitement chez moi, c'est surtout ça qui m'intrigue...

    Bonne nuit, ;-)
    Mark

  6. #6
    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 : 40
    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
    Oui, le compilo gère tout seul l'offset selon la taille des données. A part ça je ne sais pas quoi te dire d'autre, mais je pense qu'une fois que tu géreras le pitch correctement ça ira .

    Tu y étais presque pour les balises code : il faut utiliser des crochets (ou encore les boutons prévus à cet effet).

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    Bon, ok, tu peux remplacer la valeur 320 par ddsd.lPitch / (ddsd.dwRGBBitCount / 8) si ça te chante, mais le résultat reste le même car j'ai les mêmes valeurs de lPitch et de dwRGBBitCount sur le poste de mon pote. ;-)

    J'ai posté mon message sur les forums Microsoft, et ils ne voient pas ce qui cloche dans mon code. Apparemment, les pointeurs sont bien utilisés.

    Je précise que je suis sur 98 et mon pote sur XP.

    Je crois que la seule solution qui me reste est d'utiliser les API Windows pour tracers les lignes... Je te dis pas la lenteur...

    A plus,
    Mark

  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 : 40
    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
    Tant qu'à faire, tu peux aussi utiliser DirectGraphics.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    J'ai trouvé le problème. ;-)

    Je n'avais pas le bon pitch car je l'obtenais avec GetDisplayMode à partir de l'objet DirectDraw au lieu de l'obtenir avec GetSurfaceDesc à partir de la surface...

    Merci encore, et à plus !
    Mark

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/11/2006, 13h55
  2. Réponses: 8
    Dernier message: 10/05/2006, 20h56
  3. [TestStand] Erreur lors d'un accès à une Base de données
    Par capblans dans le forum Autres langages
    Réponses: 1
    Dernier message: 20/07/2005, 10h29
  4. Réponses: 1
    Dernier message: 12/05/2004, 19h02
  5. Effet Fade In / Fade Out sur une surface DirectDraw
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 08/09/2002, 17h37

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