Thread: Flickery API graphics

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Flickery API graphics

    I'm experiencing some flickery graphics in this windows program. I tried using a double buffer, but I must've
    done something wrong (though I'm pretty sure I did it all right).
    Or is it that you cannot have completely flicker-free graphics in windows API, especially in this case where
    a 640x480 screen is copied from the double buffer?
    BmpPlayer and BmpTile are the HBITMAPs for the graphics.
    I call this when the WM_PAINT message is sent (I invalidate the whole window if something is updated).
    Code:
    void RenderMap(HWND Handle)
    {
       //Data
       RECT Rect;
       PAINTSTRUCT PaintStruct;
       HDC HdcWindow;
       HDC HdcBitmap;
       HDC HdcBuffer;
       HBITMAP DoubleBuffer;
       HBITMAP OldBuffer;
       HBITMAP OldDevice;
    
       //Setup
       Rect.left = 0;
       Rect.top = 0;
       Rect.right = SCREENWIDTH;
       Rect.bottom = SCREENHEIGHT;
       HdcWindow = BeginPaint(Handle, &PaintStruct);
       HdcBuffer = CreateCompatibleDC(HdcWindow);
       DoubleBuffer = CreateCompatibleBitmap(HdcWindow, SCREENWIDTH, SCREENHEIGHT);
       OldBuffer = (HBITMAP)SelectObject(HdcBuffer, DoubleBuffer);
    
       //Clear background
       FillRect(HdcBuffer, &Rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    
       //Draw the tiles
       HdcBitmap = CreateCompatibleDC(HdcWindow);
       OldDevice =(HBITMAP)SelectObject(HdcBitmap, BmpTile);
       BitBlt(HdcBuffer, 32, 64, 32, 32, HdcBitmap, 0, 0, SRCCOPY);
       BitBlt(HdcBuffer, 128, 96, 32, 32, HdcBitmap, 32, 0, SRCCOPY);
    
       //Draw the items
    
       //Draw the enemies
    
       //Draw the effects
    
       //Draw the player
       SelectObject(HdcBitmap, BmpPlayer);
       BitBlt(HdcBuffer, Header.StartPosition.X, Header.StartPosition.Y, 32, 64, 
              HdcBitmap, 0, 0, SRCCOPY);
    
       //Copy data from buffer to window
       BitBlt(HdcWindow, 0, 0, SCREENWIDTH, SCREENHEIGHT, HdcBuffer, 0, 0, SRCCOPY);
    
       //Shutdown
       SelectObject(HdcBuffer, OldBuffer);
       DeleteDC(HdcBuffer);
       SelectObject(HdcBitmap, OldDevice);
       DeleteDC(HdcBitmap);
       DeleteObject(DoubleBuffer);
       EndPaint(Handle, &PaintStruct);
    }
    PS: This will only be the level editor for the game. The real game will be made in DX .
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    julie lexx... btq's Avatar
    Join Date
    Jun 2002
    Posts
    161
    when you invalidate the rect to update the window are you sure the eraseflag isn't set..?
    cause that will cause flickering!
    otherwise it's prettymuch up to you videocard but, offcourse depending on the amount you blt, I've had no problems with bliting 640x480 bitmaps...and my graphiccard is ****ty!!


    /btq
    ...viewlexx - julie lexx

  3. #3
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Argh, you were right. The erase flag was set to TRUE.
    It's fixed now, and no more flicker .
    Thanks alot for the quick answer!

  4. #4
    julie lexx... btq's Avatar
    Join Date
    Jun 2002
    Posts
    161
    np...

    /btq
    ...viewlexx - julie lexx

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    With double buffering ALL the drawing should be done BEFORE the paint is called.

    I have an array of structs (in my C progs) that contains all the details of a window. (HDCBuffer, HDCScreen, HWND ect)

    When the app starts I create and init these.
    While it runs they are global.
    When it closes I free them.

    Code:
    resize DC's
    draw to framebuffer
    copy framebuffer to screenbuffer
    call for paint
    the actual paint function should not have any more in it than one BitBlt()

    Code:
    find update region (GetUpdateRect() )
    BeginPaint
    copy screenbuffer to paint DC (no stretching here)
    EndPaint
    also look at returning TRUE to any WM_ERASEBKGND msg's (if controls flicker rather than DC's).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Jim(U)
    Guest
    Also could you put all this junk:

    HdcBuffer = CreateCompatibleDC(HdcWindow);
    DoubleBuffer = CreateCompatibleBitmap(HdcWindow, SCREENWIDTH, SCREENHEIGHT);
    OldBuffer = (HBITMAP)SelectObject(HdcBuffer, DoubleBuffer);

    and this:

    HdcBitmap = CreateCompatibleDC(HdcWindow);
    OldDevice =(HBITMAP)SelectObject(HdcBitmap, BmpTile);

    into your WM_CREATE message.

    And all the deleting stuff:

    DeleteDC(HdcBuffer);
    DeleteDC(HdcBitmap);
    DeleteObject(DoubleBuffer);

    into your WM_DESTROY

    As your using them more or less permamently there is absolutely no use on creating them 5.000.000 times and destroying them immediately afterwards.

    Also you could put the

    (HBRUSH)GetStockObject(WHITE_BRUSH));

    into WM_CREATE and use that handle from then on in your RenderMap... this reduces quite some overhead

  7. #7
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    >>Also could you put all this junk:

    As long as you change the variables to STATIC's

    And you can get the right HDC to create one compatible with.

    Use GetDC() wth the HWND of the control or dialog or even the main screen (and remember to ReleaseDC() when finished with one you 'Get')

    As I said

    "When the app starts I create and init these.
    While it runs they are global.
    When it closes I free them. "
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  8. #8
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Thanks for the tips.

    I already knew that it wasn't so good to recreate the double buffer in every render call, but since speed wasn't that big concern in this program, I was too lazy to do change it .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 3d graphics without API
    By h3ro in forum Game Programming
    Replies: 6
    Last Post: 05-31-2008, 11:51 AM
  2. Which graphics API?
    By homeyg in forum Game Programming
    Replies: 6
    Last Post: 03-27-2005, 05:05 PM
  3. BGI Graphics in Windows API
    By AtomRiot in forum Windows Programming
    Replies: 1
    Last Post: 07-29-2003, 05:32 PM
  4. n00b needs help with api graphics acting very weird
    By CheeseWeaver in forum Windows Programming
    Replies: 2
    Last Post: 03-18-2003, 03:15 PM