為什麼要使用DDRAW中的Gamma控制功能來做淡出呢?有兩個主要原因:第一個是因為簡單;第二是因為使用Gamma淡出,你不會丟失任何存儲在主表面中的信息。
既然這樣,在實現這種技術之前,有些不顯眼的小事情我們必須給予注意。首先,你的主表面必須是16Bit色或更高;第二個是這種淡出只能在你的主表面上來做,因為這是在調整你的顯卡的gamma設置。
讓我們認真考慮一下:在DirectDraw庫中包含一個結構DDGAMMARAMP。這個結構由3個包含256個字的數組組成,分別是Red,Green和Blue。例如:
typedef struct DDGAMMARAMP { WORD red[256]; WORD green[256]; WORD blue[256]; }DDGAMMARAMP,FAR *LPDDGRAMMARAMP;
這個結構保存著我們的顯示卡當前的Gamma設定值。那麼,來聲明幾個我們程序中使用的變量。
//初始化Gamma控制以便應用
LPDIRECTDRAWGAMMACONTROL lpDDGammaControl = NULL;
//這個是我們將修改的斜坡值(ramp)
DDGAMMARAMP DDGammaRamp;
//這個結構用來保存原來的gamma值,以便淡出完成後恢復我們gamma值
DDGAMMARAMP DDGammaOld;
完成了這些之後我們需要查明顯示是否支持gamma控制(盡管如果顯卡硬件不支持它的話,DX將會用軟件模擬它),所以來查詢主表面:
lpddsprimary->QueryInterface(IID_IDirectDrawGammaControl,(void **)& lpDDGammaControl);
然後看顯卡當前的gamma設置是否正確,再存儲它到DDGAMMAOLD結構裡
lpDDGammaControl->GetGammaRamp(0,&DDGammaOld);
讓我們來做一下這個,並且保存值到DDGAMMARAMP結構裡,以便我們修改它的值:
lpDDGammaControl->GetGammaRamp(0,&DDGammaRamp);
現在除非一個用戶改變他們計算機上的GAMMA設定值,應當把你的DDGammaRamp結構的值增加到第256個。現在,因為每個Red,Green和Blue的值可以是任何0到65535的值,我們不想把它們值改到1。所以,我決定寫下盡可能快的代碼把所有的256的值到0然後每次刷新屏幕。下面是代碼實現:(這裡有些說不明白,附原文:
Now unless a user changes the values of the gamma on their computer the values should go up as you reach the 256th value in your DDGammaRamp structure. Now because each value of Red, Blue and Green can be anywhere from 0 to 65535 we wouldn't want to decrement our values by 1. Instead I decided to make the code as fast as possible so I set all 256 values to 0 and update the screen after each. Here is how the code looks) for(int blackloop=0;blackloop<256;blackloop++) { //如果一個值大於0的話,就把它設成0 if(DDGammaRamp.red[blackloop] > 0) { //set the current value of DDGammaRamp.Red to 0. DDGammaRamp.red[blackloop]=0; //now let's update our primary lpDDGammaControl->SetGammaRamp(0, &DDGammaRamp); surface with the new gamma setting } //這個程序有點太快了,所以讓它慢一點? Sleep(1); if(DDGammaRamp.green[blackloop] > 0) { //設當前DDGammaRamp.yellow的值到0. DDGammaRamp.green[blackloop]=0; lpDDGammaControl->SetGammaRamp(DDSGR_CALIBRATE, &DDGammaRamp); } Sleep(1); if(DDGammaRamp.blue[blackloop] > 0) { //設當前DDGammaRamp.Blue的值到0. DDGammaRamp. blue [blackloop]=0; lpDDGammaControl->SetGammaRamp(DDSGR_CALIBRATE, &DDGammaRamp); } Sleep(1); } //結束
現在fade完成了,我們需要恢復所有原來的gamma值,否則屏幕一直是黑的:
lpDDGammaControl->SetGammaRamp(0, &DDGammaOld);
然後這就把它偽裝好了。用這段代碼你還可以做些其他的事情。例如:你可以修改這段代碼使你的玩家被某物打中時,屏幕閃現紅色;游水到有毒廢料區時變成綠色;淹死了的時候變藍。你也可以修改這段代碼形成淡入,就留給其他人去做吧。