日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC中的双缓冲绘图技术

發布時間:2023/12/18 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC中的双缓冲绘图技术 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前在做圖形繪制的時候,發現在拖動圖形時候,會出現閃爍的情況,后來就上網找了一下雙緩沖繪圖,本文非原創,只是想保存下來,以后要用的時候不用再到處去搜,也希望能幫助有這方面困惑的朋友


原文來自http://www.cppblog.com/wrhwww/archive/2011/03/01/140913.html


VC 雙緩沖繪圖

在圖形圖象處理編程過程中,雙緩沖是一種基本的技術。我們知道,如果窗體在響應WM_PAINT消息的時候要進行復雜的圖形處理,那么窗體在重繪時由于過頻的刷新而引起閃爍現象。解決這一問題的有效方法就是雙緩沖技術。

??? 因為窗體在刷新時,總要有一個擦除原來圖象的過程OnEraseBkgnd,它利用背景色填充窗體繪圖區,然后在調用新的繪圖代碼進行重繪,這樣一擦一寫造成了圖象顏色的反差。當WM_PAINT的響應很頻繁的時候,這種反差也就越發明顯。于是我們就看到了閃爍現象。

??? 我們會很自然的想到,避免背景色的填充是最直接的辦法。但是那樣的話,窗體上會變的一團糟。因為每次繪制圖象的時候都沒有將原來的圖象清除,造成了圖象的殘留,于是窗體重繪時,畫面往往會變的亂七八糟。所以單純的禁止背景重繪是不夠的。我們還要進行重新繪圖,但要求速度很快,于是我們想到了使用BitBlt函數。它可以支持圖形塊的復制,速度很快。我們可以先在內存中作圖,然后用此函數將做好的圖復制到前臺,同時禁止背景刷新,這樣就消除了閃爍。以上也就是雙緩沖繪圖的基本的思路。

??? 一、普通方法:

??? 先按普通做圖的方法進行編程。即在視類的OnDraw函數中添加繪圖代碼。在此我們繪制若干同心圓,代碼如下:

?CBCDoc* pDoc = GetDocument();?

ASSERT_VALID(pDoc);?

CPoint ptCenter;?

CRect rect,ellipseRect;?

GetClientRect(&rect);?

ptCenter = rect.CenterPoint();?

for(int i=20;i>0;i--)?

{?

ellipseRect.SetRect(ptCenter,ptCenter);?

ellipseRect.InflateRect(i*10,i*10);?

pDC->Ellipse(ellipseRect);?

}


??? 編譯運行程序,嘗試改變窗口大小,可以發現閃爍現象。

??? 二、雙緩沖方法:

??? 在雙緩沖方法中,首先要做的是屏蔽背景刷新。背景刷新其實是在響應WM_ERASEBKGND消息。我們在視類中添加對這個消息的響應,可以看到缺省的代碼如下:

?BOOL CMYView::OnEraseBkgnd(CDC* pDC)?

{?

return CView::OnEraseBkgnd(pDC);?

}


??? 是調用父類的OnEraseBkgnd函數,我們屏蔽此調用,只須直接return TRUE;即可。

??? 下面是內存緩沖作圖的步驟。

?CPoint ptCenter;?

CRect rect,ellipseRect;?

GetClientRect(&rect);?

ptCenter = rect.CenterPoint();?

CDC dcMem; //用于緩沖作圖的內存DC?

CBitmap bmp; //內存中承載臨時圖象的位圖?

dcMem.CreateCompatibleDC(pDC); //依附窗口DC創建兼容內存DC?

bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//創建兼容位圖?

dcMem.SelectObject(&bmp); //將位圖選擇進內存DC?

//按原來背景填充客戶區,不然會是黑色?

dcMem.FillSolidRect(rect,pDC->GetBkColor());?

for(int i=20;i>0;i--) //在內存DC上做同樣的同心圓圖象?

{?

ellipseRect.SetRect(ptCenter,ptCenter);?

ellipseRect.InflateRect(i*10,i*10);?

dcMem.Ellipse(ellipseRect);?

}?

pDC->BitBlt(0,0,rect.Width(),rect.Height(),?

&dcMem,0,0,SRCCOPY);//將內存DC上的圖象拷貝到前臺?

dcMem.DeleteDC(); //刪除DC?

bm.DeleteObject(); //刪除位圖


??? 由于復雜的畫圖操作轉入后臺,我們看到的是速度很快的復制操作,自然也就消除了閃爍現象。
??? 注意:bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());

??? 這里面CreateCompatibleBitmap第一個參數不能用dcMem,這樣的話創建的是黑白位圖。如果你要創建彩色位圖,需要用pDC,它用來創建了內存DC. 詳細請見下面的MSDN:?

?When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the hDC that was used to create the memory device context, as shown in the following code:?

HDC memDC = CreateCompatibleDC ( hDC );?

HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );?

SelectObject ( memDC, memBM );




雙緩沖技術繪圖

當數據量很大時,繪圖可能需要幾秒鐘甚至更長的時間,而且有時還會出現閃爍現象,為了解決這些問題,可采用雙緩沖技術來繪圖。   雙緩沖即在內存中創建一個與屏幕繪圖區域一致的對象,先將圖形繪制到內存中的這個對象上,再一次性將這個對象上的圖形拷貝到屏幕上,這樣能大大加快繪圖的速度。雙緩沖實現過程如下:   1、在內存中創建與畫布一致的緩沖區   2、在緩沖區畫圖   3、將緩沖區位圖拷貝到當前畫布上   4、釋放內存緩沖區   在圖形圖象處理編程過程中,雙緩沖是一種基本的技術。我們知道,如果窗體在響應WM_PAINT消息的時候要進行復雜的圖形處理,那么窗體在重繪時由于過頻的刷新而引起閃爍現象。解決這一問題的有效方法就是雙緩沖技術。因為窗體在刷新時,總要有一個擦除原來圖象的過程OnEraseBkgnd,它利用背景色填充窗體繪圖區,然后在調用新的繪圖代碼進行重繪,這樣一擦一寫造成了圖象顏色的反差。當WM_PAINT的響應很頻繁的時候,這種反差也就越發明顯。于是我們就看到了閃爍現象。    我們會很自然的想到,避免背景色的填充是最直接的辦法。但是那樣的話,窗體上會變的一團糟。因為每次繪制圖象的時候都沒有將原來的圖象清除,造 成了圖象的殘留,于是窗體重繪時,畫面往往會變的亂七八糟。所以單純的禁止背景重繪是不夠的。我們還要進行重新繪圖,但要求速度很快,于是我們想到了使用 BitBlt函數。它可以支持圖形塊的復制,速度很快。我們可以先在內存中作圖,然后用此函數將做好的圖復制到前臺,同時禁止背景刷新,這樣就消除了閃 爍。以上也就是雙緩沖繪圖的基本的思路。    首先給出實現的程序,然后再解釋,同樣是在OnDraw(CDC *pDC)中:    CDC MemDC; //首先定義一個顯示設備對象    CBitmap MemBitmap;//定義一個位圖對象 //隨后建立與屏幕顯示兼容的內存顯示設備 MemDC.CreateCompatibleDC(NULL); //這時還不能繪圖,因為沒有地方畫 ^_^    //下面建立一個與屏幕顯示兼容的位圖,至于位圖的大小嘛,可以用窗口的大小,也可以自己定義   (如:有滾動條時就要大于當前窗口的大小,在BitBlt時決定拷貝內存的哪部分到屏幕上)   MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //將位圖選入到內存顯示設備中 //只有選入了位圖的內存顯示設備才有地方繪圖,畫到指定的位圖上    CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //先用背景色將位圖清除干凈,這里我用的是白色作為背景 //你也可以用自己應該用的顏色    MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //繪圖    MemDC.MoveTo(……); MemDC.LineTo(……); //將內存中的圖拷貝到屏幕上進行顯示    pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); //繪圖完成后的清理 //把前面的pOldBit選回來.在刪除MemBitmap之前要先從設備中移除它    MemDC.SelectObject(pOldBit); MemBitmap.DeleteObject(); MemDC.DeleteDC(); 雙緩沖(two way soft-closing)

總結

以上是生活随笔為你收集整理的VC中的双缓冲绘图技术的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。