程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> Windows下的動畫特技—淡入淡出

Windows下的動畫特技—淡入淡出

編輯:vc教程

動畫程序設計是多煤體程序設計的另一個方面,在程序設計中適當的引入動畫特技,能夠使程序更加生動活潑。與其它多煤體程序設計不同的是,動畫並不需要特殊的多煤體硬件設備加以支持。本文將以動畫特技中的“淡入淡出”技術為例來說明如何協同Windows和Visual C++來共同完成動畫程序設計。

一. 淡入淡出(Dissolve)

淡入淡出技術源於電影業,電影制作人利用淡入淡出技術來完成一副圖象A到另一副圖象B的轉換。電影中的淡入淡出技術可以通過制作許多中間過渡圖象來實現。

然而,在計算機上完成淡入淡出則是另一回事,使用過渡圖象的方法既不實際也不必要。一種可行的辦法是∶在已顯示的位圖A上,不斷開些小洞,在小洞內顯示位圖B的象素,隨著小洞逐漸增多,位圖A越來越模糊,位圖B越來越清晰,最後,位圖A消失,位圖B完整的顯示出來。

二. Windows調色板

完成淡入淡出,首先必須能夠正確的顯示圖象,這要求能夠正確的處理顏色。彩色顯示器能夠顯示很多種顏色,但在一般情況下,在給定的時刻只能顯示一定數目的顏色。在VGA和SVGA這類顯示控制器上都使用調色板來限制應用程序所能使用的顏色的數目。調色板規定了一個顏色集合(一般為256項),屏幕象素值對應調色板的一個表項的索引。在Windows系統下,系統中同時會有多個應用程序在運行,桌面上將顯示多個窗口,而每個窗口對顏色的需求可能是不一樣的。然而,整個顯示是共用一個物理調色板,若某個窗口出於本身的需要改變了物理調色板,則可能造成其它窗口顯示不正確的顏色。為解決上述矛盾,Windows引入了邏輯調色板和系統調色板的概念。系統調色板(或稱硬件調色板)即物理調色板,它是整個桌面的調色板,應用程序通過創建一個或多個邏輯調色板的方法來使用系統調色板。當一個窗口請求使用其邏輯調色板時,系統完成邏輯調色板到系統調色板的映射,映射的過程如下∶

系統調色板保留前10種和後10種顏色作為靜態色,用於Windows系統顏色。邏輯調色板中的項與系統調色板中的項做完全匹配(RGB值相同的項)。對邏輯調色板中不完全匹配的項,Windows將其設置到系統調色板中的未用項。如果系統調色板的所有項都被使用,Windows將邏輯調色板其余的項匹配到系統調色板中盡可能相近的表項上(稱為不完全匹配)。Windows總是先滿足活動窗口對顏色的需求,對於剩下的窗口,Windows沿Z次序(窗口鋪放在桌面的次序)滿足最近接收到輸入焦點的窗口。VC++的MFC提供了類Cpalette和CDC進行對調色板的有關操作。下面是一些常用的函數∶

Cpalette::CreatePalette()
創建調色板
CDC::SelectPalette()
將調色板選進設備
CDC::RealizePalette()
調色板實現

三. BitBlt()與三元光珊操作

在MFC中CDC::BitBlt()在兩個設備對象的位圖之間進行邏輯操作。其原型為∶BOOL BitBlt(int x , int y , int nWidth , int nHeight , CDC* pSrcDC , int xSrc , int ySrc ,DWord dwRop) ;其中,xSrc,ySrc是源設備上要移動的位圖的起始點,x,y,nWidth,hHeight參數表示目的設備矩形起始點坐標,寬和高,nWidth和nHeight也用於源設備。dwRop是三元光珊操作代碼。BitBlt在進行位圖復制時要對三個對象進行邏輯組合(因此稱為三元光珊操作)∶目的設備中選定的畫刷,源設備中所要復制的矩形中的位圖和目的設備中矩形的位圖。畫刷是一個8*8的位圖,可以使用CDC::CreatePatternBrush()創建。淡入淡出實際上就是通過BitBlt()函數進行∶將位圖A放入目的設備,將位圖B放入源設備,利用畫刷在位圖A上打洞並以位圖B的象素填入,不斷改變畫刷使洞越來越多進行BitBlt()操作,最後完成整個過程。完成上述過程需要選擇一個合適的ROP操作碼,下面說明如何計算這個操作碼∶上述過程實際上可以分成兩步進行∶

1. 利用畫刷在目的位圖上打洞

2. 將位圖B的象素填入洞中。

完成第一步可以采用AND操作,即∶Pattern & Destination。通過這個操作,畫刷中的黑點對應的象素值為0 (0&Destination=0),濾去了Destination的象素;而畫刷中的白點對應象素處仍保持Destination的象素值(1&Destination=Destination)。同樣道理,第二步可以采用操作(~Pattern) & Source將畫刷黑點對應象素置為Source的象素值,畫刷白點對應象素值為0。最後,兩各操作進行OR即可完成指定操作。因此,最後的ROP操作為∶(Pattern & Destination) | ((~Pattern) &Source))取Pattern =11110000,Destination =10101010,Source=11001100可以計算出ROP碼為10101100=0xAC,查ROP操作碼表可得最後的ROP碼為0x00AC0744。

四. 淡入淡出例程

下面的例程說明了淡入淡出特技的實現過程。創建該例程的步驟如下∶1. 利用AppWizard創建一個基於對話框的工程。

2. 添加產生畫刷的過程
 
Cbrush *Cdissolve::CreateDissolveBrush(int Step)
{
  // 創建畫刷所需數據
  static int data[65] =
  {
    1, 5, 33, 37, 19, 23, 51, 55, 17, 21, 49, 53, 3, 7, 35, 39, 10, 14, 42, 46,
      28, 32, 60, 64, 26, 30, 58, 62, 12, 16, 44, 48, 8, 4, 40, 36, 22, 18, 54,
      50, 24, 20, 56, 52, 6, 2, 38, 34, 15, 11, 47, 43, 29, 25, 61, 57, 31, 27,
      63, 59, 13, 9, 45, 41
  };
  if (Step < 0 || Step > m_maxstep - 1)
    return NULL;
  Cbrush *pBrush = new Cbrush;
  // 最後一步使用黑畫刷
  if (Step == m_maxstep - 1)
  {
    pBrush->CreateSolidBrush(RGB(0, 0, 0));
    return pBrush;
  }
  // 計算畫刷數據
  BYTE pixels[16];
  for (int I = 0; I < 8; I++)
    pixels[I *2] = 0xFF;
  for (I = 1; I <= (Step *(64 / m_maxstep)); I++)
  {
    int row = (data[I] - 1) / 8;
    int col = (data[I] - 1) % 8;
    pixels[row *2] = pixels[row *2] &(~(BYTE)pow(2, col));
  }

  // 創建畫刷
  Cbitmap bitmap;
  if (!bitmap.CreateBitmap(8, 8, 1, 1, pixels))
  {
    m_LastError = ERR_BMP_CREATE;
    return NULL;
  }
  if (!pBrush->CreatePatternBrush(&bitmap))
  {
    m_LastError = ERR_BRUSH_CREATE;
    return NULL;
  }

  return pBrush;
}
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved