Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle the update rect/region/area in a Direct2D application?

In a traditional Windows program that uses GDI for graphics, you would have to worry about only drawing the area of the window that needs to be redrawn; this is the "update rect" and is accessed either by PAINTSTRUCT.rcPaint or by a call to GetUpdateRect(). (This is also available as an HRGN through other means.)

Do I need to do the same thing with Direct2D? All the examples on MSDN just draw the entire client area indiscriminately and searching online hasn't turned up anything else.

Or in other words, would anything bad happen to parts outside the update rect if I only draw within the update rect, for instance either manually or with PushAxisAlignedClip() or PushLayer()?

Furthermore, the documentation for ID2D1HwndRenderTarget::Resize() says

After this method is called, the contents of the render target's back-buffer are not defined, even if the D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS option was specified when the render target was created.

Does this mean that whatever update region would be caused by resizing (such as shown by this picture from this page) is invalid and I should redraw the whole window (for instance, by calling InvalidateRect(NULL)) on a resize?

Thanks.

like image 558
andlabs Avatar asked Oct 20 '22 00:10

andlabs


1 Answers

Yes. Use PushAxisAlignedClip with D2D1_ANTIALIAS_MODE_ALIASED.

Call ID2D1HwndRenderTarget::Resize when the window is resized. Do pay attention to the HRESULT it returns. It can return D2DERR_RECREATE_TARGET, but you may not know that it can also return D2DERR_DISPLAY_STATE_INVALID (which can also be returned by EndDraw, btw). And yes, call InvalidateRect(NULL) after that.

I also recommend using D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS because otherwise you'll run into nasty bugs on some stupid driver/hardware configurations and in other events. Don't ask me why -- it just doesn't behave well without this. You'll get bug reports that your whole rendering area just becomes filled with black. It took me months to figure out that all I had to do was to use that flag. I was never able to repro the problem locally.

like image 121
Rick Brewster Avatar answered Oct 23 '22 01:10

Rick Brewster