How to efficiently render double buffered window without any tearing effect?

I want to create my own tiny windowless GUI system, for that I am using GDI+. I cannot post code here because it got huge(c++) but bellow is the main steps I am following...

  • Create a bitmap of size equal to the application window.
  • For all mouse and keyboard events update the custom control states (eg. if mouse is currently held over a particular control etc)
  • For WM_PAINT event paint the background to offscreen bitmap and then paint all the updated controls on top of it and finally copy entire offscreen image to the front buffer via Graphics::DrawImage(..) call.
  • For WM_SIZE/WM_SIZING delete the previous offscreen bitmap and create another one with new window size.
  • Also there are some checks to prevent repeated drawing of controls ie controls are drawn only when it needs repainting in other words when the state of a control is changed only then it is painted etc

    The system is working fine but only with one exception...when window is being resizing something sort of tearing effect appears. Now what I mean by tearing effect I shall try to explain ...

    On the sizing edge/border there is a flickering gap as I drag the border.It is as if my DrawImage() function returns immediately and while one swap operation is half done another image drawing starts up.

    Now you may think that it is common artifact that happens in many other application for the fact that resizing backbuffer is not always as fast as resizing window are but in other applications I noticed in other applications that although there is a leg between window size and client area size as window grows in size nothing flickers near the edge (its usually just white background that shows up as thin uniform strips along the border). Also the dynamic controls which move with window resize acts jerky during sizing.

    At first it seemed to me that using a constant fullscreen size offscreen surface could minimize the artifact but when I tried it results are not that satisfactory. I also tried to call Sleep() during sizing so that the flipping is done completely before another flip starts but strangely even that won't worked for me!

    I have heard that GDI on vista is not hardware accelerated, could that might be the problem?

    Also I wonder how frameworks such as Qt renders windowless GUI so smoothly, even if you size a complex Qt GUI window very fast negligibly little artifact appears. As far as I know Qt can use opengl for GUI rendering but that is second option.

    If I use directx then real time resizing is even harder, opengl on the other hand seems to be nice for resizing without any problem but I will loose all the 2d drawing capability of GDI+.

    If any of you have done anything like this before please guide me. Also if you have any pointer that I should consider for custom user interface design then provide me the links.

    Thanks!

    I always wished to design interfaces like windows media player 11 but can someone tell me that there is a straight forward solution for a c++ programmer (I want to know how rather than use some existing framework etc.)? Subclassing, owner drawing, custom drawing nothing seems to give you such level of control, I dont know a way to draw semitransparent control with common controls, so I think this question deserves some special attention . Thanks again.


    Could it be a WM_ERASEBKGND message that's causing it?

    see this question: GDI+ double buffering in C++

    Also, if you need fast response from your GUI I would advise against GDI+.

    链接地址: http://www.djcxy.com/p/8876.html

    上一篇: Chrome上使用drawImage和Canvas非常缓慢

    下一篇: 如何有效地渲染双缓冲窗口而没有任何撕裂效应?