Click here to Skip to main content
15,894,405 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
It seems the flickering is generated by the CombineRgn function, but I really have no idea why this happens, since i've never used regions that much I'm possibly missing some knowledge on the matter.

Some events in the program triggers the addition of little rectangles to the main region, here's the code that handles that:
C++
HRGN ActualRegion = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hwnd, ActualRegion);
HRGN AddedRect = CreateRectRgn(//long code that creates a rectangle)
CombineRgn(ActualRegion, ActualRegion, AddedRect, RGN_OR);

SetWindowRgn(hwnd, ActualRegion, FALSE);
InvalidateRect(hwnd, NULL, FALSE);


White Flickering appears only after the invalidation if new regions where combined to the main one.


Here's how I'm implementing double buffering in WM_PAINT:
PLEASE NOTE that on creation i'm enabling the DWM blur behind function with an invalid region (different from the Main one) which means that everything painted with BLACK_BRUSH will result in a 100% "invisible" portion of the program
C++
RECT r;	GetClientRect(hwnd, &r);

		PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps);
		HDC MemDc = CreateCompatibleDC(hdc);
		HBITMAP hBmp = CreateCompatibleBitmap(hdc, r.right, r.bottom);
		HBITMAP hOld = (HBITMAP)SelectObject(MemDc, hBmp);

		//Making sure this dc is filled with "invisible" pixels to display
		SelectObject(MemDc, GetStockObject(BLACK_BRUSH));
		Rectangle(MemDc, //arbitrary values that matches the entire screen);

		BitBlt(hdc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), MemDc, 0, 0, 		SRCCOPY);

		//clean-up
		SelectObject(MemDc, hOld);
		DeleteObject(hBmp);
		DeleteDC(MemDc);
		EndPaint(hwnd, &ps);


WM_ERASEBKGND obviously returns TRUE without further handling, the WNDCLASSEX instance of the window has a default BLACK_BRUSH as the hbrBackground field.
Is it something that i'm possibly missing ? I can't really understand what may be causing white flickering in this scenario
Posted
Updated 5-May-15 12:57pm
v2
Comments
Sergey Alexandrovich Kryukov 5-May-15 19:09pm    
Roughly speaking, the nature of flicker is re-drawing of the scene in two or more steps, when the intermediate image is different from the final one. Say, if you image is black spot on white background, and the move of the spot is redrawing background first, and then drawing a black spot on a shifted place, you have a big flicker between the all-white image and image with the spot. In specialized motion (animation), you can fight flicker with partial invalidation, but really radical way is double buffering: pre-render new frame on some bitmap, and than draw the whole bitmap. No intermediate images — no noticeable flicker.
—SA

1 solution

Please see my comment to the question. To understand the idea, see, for example,
http://snipd.net/double-buffering-with-a-back-buffer-in-vc[^],
http://www.robertelder.ca/doublebuffering[^].

—SA
 
Share this answer
 
Comments
Member 11287295 6-May-15 15:25pm    
I do understand the nature of the problem, and that's what actually bugs me. I'm doing everything necessary to avoid intermediate drawcalls, everything handled inside the WM_PAINT uses a backbuffer. Do you see any errors in the actual implementation of the double buffering?
Also i'd like to mention i'm not working with images/bitmaps. Everything is drawn with gdi/gdi+, and in no place i'm actually issuing a "white" redraw that may possibly cause said flicker. I'm a bit lost here
Sergey Alexandrovich Kryukov 6-May-15 15:31pm    
Even with GDI, you may need to work with a bitmap, because this is how double buffering is implemented.
The approaches without buffering cannot be universal, they are specialized, so, understanding of what exactly flickers, depends on what exactly is there in your regions.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900