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

Windows Discussion :

problème fichier bitmap et buffering


Sujet :

Windows

  1. #1
    Membre à l'essai
    Homme Profil pro
    rien
    Inscrit en
    Février 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : rien
    Secteur : Services de proximité

    Informations forums :
    Inscription : Février 2013
    Messages : 13
    Points : 15
    Points
    15
    Par défaut problème fichier bitmap et buffering
    bonjour, comme dit le titre, je me trouve face à un problème dont je ne trouve pas l'erreur...

    Au départ, ce que je veut, c'est afficher un sprite bmp sur un fond.
    Pour cela je créé un DC memoire sur lequel je vais afficher mon fond, puis mon sprite(chargé from file avec loadImage) avant d'afficher ce hdc sur le hdc de la fenêtre(pour éviter les scintillements).
    mais rien ne s'affiche!
    en revanche si je dessine un rectangle en guise d'image:ça marche(mais pas d'image...)
    par contre: si j'affiche mon image directement dans le hdc de la fenetre, ça marche(mais plus de buffering)!

    mon but est d'afficher plusieurs images sur le même DC memoire et l'afficher ensuite à l'écran.
    ça à l'air tout bête, mais ça fait un bout de temps que je bloque.
    si quelqu'un sait pourquoi ça fait ça...Je veut bien savoir aussi!

    PS: Si vous voulez essayer chez vous, voici mon 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
    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
    #include <Windows.h>
    
    RECT rcSize;
    HDC hdcBackBuffer, hdcSprite;
    HBITMAP hbmBackBuffer, hbmSprite;
    int spriteX = 175, spriteY = 175;
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        static PAINTSTRUCT ps;
    
        switch (msg)
        {
        case WM_CREATE:
            {
                HDC hdcWindow = GetDC(hWnd);
    
                // make back buffer
                GetClientRect(hWnd, &rcSize);
                hdcBackBuffer = CreateCompatibleDC(hdcWindow);
                hbmBackBuffer = CreateCompatibleBitmap(hdcBackBuffer, rcSize.right - rcSize.left, rcSize.bottom - rcSize.top);
                SelectObject(hdcBackBuffer, hbmBackBuffer);  // SHOULD SAVE PREVIOUS...
                DeleteObject(hbmBackBuffer);
                // make sprite
                hdcSprite = CreateCompatibleDC(hdcWindow);
                //hbmSprite = CreateCompatibleBitmap(hdcSprite, 50, 50);
                hbmSprite = (HBITMAP)LoadImage(NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
                SelectObject(hdcSprite, hbmSprite);  // SHOULD SAVE PREVIOUS...
                DeleteObject(hbmSprite);
                //RECT rcSprite;
                //SetRect(&rcSprite, 0, 0, 50, 50);
                //FillRect(hdcSprite, &rcSprite, (HBRUSH)GetStockObject(WHITE_BRUSH));
    
                ReleaseDC(hWnd, hdcWindow);
                return 0;
            }
        case WM_KEYDOWN:
            {
                // SHOULD REALLY USE GetAsyncKeyState for game, but simplified here
                switch (wParam)
                {
                case VK_LEFT:
                    spriteX--;
                    break;
                case VK_RIGHT:
                    spriteX++;
                    break;
                case VK_UP:
                    spriteY--;
                    break;
                case VK_DOWN:
                    spriteY++;
                    break;
                }
                return 0;
            }
        case WM_ERASEBKGND:
            {
                return 1; // INDICATE THAT WE ERASED THE BACKGROUND OURSELVES
            }
        case WM_PAINT:
            {
                BeginPaint(hWnd, &ps);
                // clear back buffer
                FillRect(hdcBackBuffer, &rcSize, (HBRUSH)GetStockObject(BLACK_BRUSH));
                // render sprite to back buffer
                BitBlt(hdcBackBuffer, spriteX, spriteY, 50, 50, hdcSprite, 0, 0, SRCCOPY);
                // render back buffer to screen
                BitBlt(ps.hdc, 0, 0, rcSize.right - rcSize.left, rcSize.bottom - rcSize.top, hdcBackBuffer, 0, 0, SRCCOPY);
                EndPaint(hWnd, &ps);
                return 0;
            }
        case WM_DESTROY:
            {
                // TODO - DESTROY ALL BITMAPS AND DEVICE CONTEXTS
                PostQuitMessage(0);
                return 0;
            }
        default:
            {
                return DefWindowProc(hWnd, msg, wParam, lParam);
            }
        }
    }
    
    int WINAPI WinMain(HINSTANCE hPrevInstance, HINSTANCE hInstance, LPSTR lpCmdLine, int nShowCmd)
    {
        static TCHAR className[] = TEXT("GameClass");
        static TCHAR windowName[] = TEXT("A Game");
    
        WNDCLASSEX wcex;
    
        wcex.cbClsExtra = 0;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.cbWndExtra = 0;
        wcex.hbrBackground = NULL;
        wcex.hCursor = LoadCursor(hInstance, IDC_ARROW);
        wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
        wcex.hIconSm = NULL;
        wcex.hInstance = hInstance;
        wcex.lpfnWndProc = WndProc;
        wcex.lpszClassName = className;
        wcex.lpszMenuName = NULL;
        wcex.style = 0;
    
        if (!RegisterClassEx(&wcex))
            return 0;
    
        HWND hWnd = CreateWindow(className, windowName, WS_CAPTION | WS_BORDER | WS_SYSMENU, 0, 0, 400, 400, NULL, NULL, hInstance, NULL);
        if (!hWnd)
            return 0;
    
        ShowWindow(hWnd, nShowCmd);
        UpdateWindow(hWnd);
    
        MSG msg;
        for (;;)
        {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                {
                    break;
                }
                else
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
    
            InvalidateRect(hWnd, NULL, FALSE);
        }
    
        return msg.wParam;
    }
    Merci d'avance!

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Attention, si tu fais un CreateCompatibleBitmap() sur un DC nouvellement créé, tu obtiendras un bitmap monochrome.
    Aussi, tu as clairement un problème ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SelectObject(hdcBackBuffer, hbmBackBuffer);  // SHOULD SAVE PREVIOUS...
    DeleteObject(hbmBackBuffer);
    C'est très mauvais, ça.

    PS: Programmes-tu en C ou en C++?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Homme Profil pro
    rien
    Inscrit en
    Février 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : rien
    Secteur : Services de proximité

    Informations forums :
    Inscription : Février 2013
    Messages : 13
    Points : 15
    Points
    15
    Par défaut
    On vas dire que je préfère le C, et que j'utilise le C++ comme du C amélioré, plus convivial, mais sans entrer dans la poo.

    pour l'erreur, c'est que j'ai passé tellement d'heures à m'embrouiller à tourner tout ça dans tout les sens, que je finis par ne plus rien comprendre...
    je veut pas faire le gars ennuyant, mais si tu pouvait me dire comment je dois m'y prendre, ce qui ne vas pas... ou modifier mon source pour que je l'étudie...
    en tout cas merci quand même!

    EDIT:
    j'ai enlevé les DeleteObject, mais je ne vois pas ce qui cloche, je croyais que le DC prennait les caracteristiques de couleur, de taille,etc... lorsqu'on utilisait SelectObject...
    je me re-penche tout de suite dessus...

    EDIT: si il y à quelqu'un qui s'y connait, ça serait cool de me filer un petit coup de pouce, parce que là je galère grave et je n'avance pas d'un millimètre avec cette foutue API...

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    SelectObject() ne copie rien du tout, il est donc important que la durée de vie de l'objet excède celle du DC.

    L'usage normal de SelectObject(), c'est ceci:
    • Création des objets (bitmap, etc.) et du DC(GetDC()/CreateCompatibleDC()/etc.)
    • Sélection: HGDIOBJ hOldBitmap = SelectObject(hdc, hMyBitmap);
      • La même chose pour les autres objets GDI que tu utilises (par exemple, un Pen pour tracer des lignes: HGDIOBJ hOldPen = SelectObject(hdc, hMyPen);
    • Travail avec le DC
    • Restauration des anciens objets: SelectObject(hdc, hOldBitmap);
    • Destruction des objets et du DC.

    Pour toi, je te conseille d'utiliser des structures:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct BitmapsAndDC
    {
    	HDC hdc;
    	HBITMAP hOldBitmap;
    	HBITMAP hBitmap;
    };
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Citation Envoyé par leyhodolerondunord Voir le message
    pour l'erreur, c'est que j'ai passé tellement d'heures à m'embrouiller à tourner tout ça dans tout les sens, que je finis par ne plus rien comprendre...
    tout est indiqué dans le MSDN en ligne
    Il ne faut pas prendre la version française mais la version US
    On appelle DeleteObject en général lorsqu'on termine le programme
    Utiliser des libs comme SDL ça simplifie les choses
    Sinon j'ai un exemple que j'avais fait qui doit trainer, m'envoyer email

  6. #6
    Membre à l'essai
    Homme Profil pro
    rien
    Inscrit en
    Février 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : rien
    Secteur : Services de proximité

    Informations forums :
    Inscription : Février 2013
    Messages : 13
    Points : 15
    Points
    15
    Par défaut
    Merci Médinoc et Mat.M pour vos réponses, j'ai finalement trouvé mon erreur...
    c'est à la ligne 21 lors de l'appel à createcompatiblebitmap(), je lui passais hdcBackBuffer alors qu'il fallait selectionner hdcWindow...
    bref, beaucoup de temps perdu pour rien...
    merci encore de vous être penché sur mon problème les gars...
    PS: je clos le sujet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [BCB6]Problème Dimensions Bitmap
    Par vsavoir dans le forum C++Builder
    Réponses: 10
    Dernier message: 09/11/2004, 13h35
  2. [Debutant(e)] Problème fichier texte et vue
    Par solenn dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 21/07/2004, 09h23
  3. Sauvegarder la fenetre OpenGL sous un fichier bitmap
    Par corey_jx dans le forum OpenGL
    Réponses: 3
    Dernier message: 16/06/2004, 15h48
  4. [fread] Problème de lecture de buffer
    Par karl3i dans le forum C
    Réponses: 2
    Dernier message: 25/09/2003, 09h21
  5. transfert d'un fichier bitmap en socket tcp
    Par localhost dans le forum C++Builder
    Réponses: 5
    Dernier message: 29/07/2002, 00h40

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