Bitblt () Dual buffering solution for image flickering

Source: Internet
Author: User

There are many questions about how to avoid flickering and how to improve the display efficiency. Most people think that the efficiency of the MFC plot function is very low, and they always want to seek other solutions. The drawing efficiency of MFC is indeed not high, but it is not bad, and its drawing function is very simple to use, as long as the use of appropriate methods, plus some skills, with MFC can get a very efficient drawing program. I would like to share some of my views on my long-term experience in using MFC plotting (of course, I only have more than two years. 1. Why does the displayed image flash? Most of our drawing processes are stored in the ondraw or onpaint functions. ondraw calls onpaint for screen display. When the window needs to be re-painted for any reason, the display area is always cleared with the background color before onpaint is called. The background color is often in a large contrast with the drawing content, in this way, the background color and the display image appear alternately in a short period of time, making the display window appear flashing. If you set the background to null, the duplicate drawing will not flash. Of course, this will make the display of the window messy, because during the re-painting, there is no background color to clear the original drawing, and a new image is superimposed. Some people may say that the blinking is caused by the drawing speed being too slow or the display graphics being too complex. In fact, this is not true. The influence of the display speed of the drawing on the flashing is not fundamental. For example, in ondraw (CDC * PDC), write: PDC-> moveTo (100,100); PDC-> lineto ); this drawing process should be very simple and fast, but it will still flash when pulling the window changes. In fact, in principle, the more complex the process of drawing, the slower the process, and the fewer flashes it should be, because the larger the ratio of the time used for drawing to the time used to clear the screen with the background, the less obvious the person will feel. For example, when the screen time is 1 s, the drawing time is also 1 s, so that the continuous re-painting within 10 s will flash 5 times; if the screen time is 1 s, the drawing time is 9 s, so that the continuous re-painting within 10 s will only Flash once. This can also be tested. In ondraw (CDC * PDC), write: For (INT I = 0; I <100000; I ++) {PDC-> moveTo (0, i); PDC-> lineto (1000, I);} Oh, the program is abnormal, but the problem can be explained. Some people may want to talk about it again. Why does a simple image look like a complex one? This is because the area occupied by complex images is large, and the contrast caused by the re-painting is relatively large, so I feel that the flash is more severe, but the flash frequency is lower. So why does the animation appear non-flashing when its re-painting frequency is high? Here, I want to emphasize again, what is flashing? Flashing means contrast. The larger the contrast, the more powerful the blinking. The animation does not seem to flash because the difference between two consecutive frames is very small. If you don't believe it, you can add a pure white frame in the middle of each frame of the animation. 2. How to Avoid blinking after you know the reason why the image is flickering is displayed. The first step is to remove the background rendering process provided by MFC. There are many implementation methods. * You can set NULL for the registration background of the window when the window is formed * or you can modify the background static cbrush brush (RGB (, 0) after the window is formed )); setclasslong (this-> m_hwnd, gcl_hbrbackground, (long) (hbrush) brush); * to be simple, you can reload onerasebkgnd (CDC * PDC) to directly return true, the graphic display of the results is indeed not flashing, but the display is also messy as mentioned above. What should I do? This requires the dual-Cache method. In addition to displaying images on the screen, the dual-buffer mode also displays images in the memory. We can plot the image to be displayed in the memory first, and then overwrite the image in the memory to the screen one by one point at a time (this process is very fast, because it is a very regular copy of memory ). In this way, when drawing in the memory, any background color with a large contrast will not flash, because it cannot be seen. When it is attached to the screen, the final image in the memory is slightly different from the screen display image (if there is no motion, of course there is no difference), so that it will not flash. 3. How to implement dual-buffering first, give the implementation program, and then explain that it is also in ondraw (CDC * PDC): CDC memdc; // first define a display device object cbitmap membitmap; // define a bitmap object // then create a memory display device memdc compatible with the screen display. createcompatibledc (null); // No drawing is available at this time, because there is no place to draw ^_^ // The following creates a bitmap compatible with the screen display. As for the bitmap size, you can use the window size membitmap. createcompatiblebitmap (PDC, nwidth, nheight); // select the bitmap to the memory display device. // only the memory display device with the bitmap selected has a place for plotting, cbitmap * poldbit = memdc. selectObject (& membitmap); // first clear the bitmap with the background color. Here I use white as the background. // You can also Use the appropriate color memdc. fillsolidrect (255,255,255, nwidth, nheight, RGB (); // plot memdc. moveTo (......); Memdc. lineto (......); // Copy the image in the memory to the screen to display the PDC-> bitblt (, nwidth, nheight, & memdc, srccopy); // clear the membitmap after the drawing is complete. deleteobject (); memdc. deletedc (); the comment above should be very detailed, so I will not talk much about it. 4. How to Improve the drawing efficiency I mainly do the CAD software for the Network Graphics of the power system. In a window, thousands of Power elements are usually displayed, each component is composed of basic figures such as points, lines, and circles. If you really want to re-draw so many elements in a re-painting process, it can be imagined that this process is very long. If you have added the Image Browsing function, you need to re-paint a lot when you move the mouse to scroll the image. The speed will be too slow for users to endure. What should I do? We only need to study the Drawing Process of MFC. In fact, not all charts drawn in ondraw (CDC * PDC) are displayed. For example, you have drawn two rectangles in ondraw, although the painting functions of the two rectangles are executed in one painting, there may be only one display. This is because MFC sets the cropping area to improve the repainting efficiency. The purpose of the cropping area is to ensure that only the plotting process in this area is valid and that the plotting function is not displayed even if it is executed outside the area. In most cases, the re-painting of a window is mostly due to partial occlusion of the window or scrolling of the window. The changed area is not the whole graph but only a small part, this part needs to be changed in the cutting area of the PDC. Because the display (display to memory or video memory) is much more time-consuming than the calculation of the drawing process, only the display part should be displayed after the cropping area, greatly improving the display efficiency. However, this cropping area is set by MFC, which has improved the display efficiency. How can we further improve the efficiency when drawing complex images? Then, only the plotting process outside the cropping area is removed. You can first use PDC-> getclipbox () to obtain the cropping area, and then determine whether your image is in this area during the drawing. If you are painting it, you will not draw it if you are not. If your drawing process is not complex, this may not improve your drawing efficiency.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.