作者:龍飛
3.1:獲取視頻屬性信息。
SDL_GetVideoInfo()將返回當(dāng)前SDL運(yùn)行窗口的視頻屬性信息,其數(shù)據(jù)組織在一個(gè)名為SDL_VidioInfo的結(jié)構(gòu)中。該函數(shù)就是返回這個(gè)只讀結(jié)構(gòu)的指針。
Uint32 hw_available:1;
Uint32 wm_available:1;
Uint32 blit_hw:1;
Uint32 blit_hw_CC:1;
Uint32 blit_hw_A:1;
Uint32 blit_sw:1;
Uint32 blit_sw_CC:1;
Uint32 blit_sw_A:1;
Uint32 blit_fill:1;
Uint32 video_mem;
SDL_PixelFormat *vfmt;
int current_w;
int current_h;
} SDL_VideoInfo;
我們?cè)谑褂迷谙到y(tǒng)內(nèi)存中建立SDL運(yùn)行窗口的方式來(lái)察看這些成員數(shù)據(jù)。
atexit(SDL_Quit);
SDL_Surface* pScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
SDL_Flip(pScreen);
const SDL_VideoInfo* myInfo = SDL_GetVideoInfo();
cout << "Is it possible to create hardware surfaces? " << myInfo->hw_available << endl;
cout << "Is there a window manager available? " << myInfo->wm_available << endl;
cout << "Are hardware to hardware blits accelerated? " << myInfo->blit_hw << endl;
cout << "Are hardware to hardware colorkey blits accelerated? " << myInfo->blit_hw_CC << endl;
cout << "Are hardware to hardware alpha blits accelerated? " << myInfo->blit_hw_A << endl;
cout << "Are software to hardware blits accelerated? " << myInfo->blit_sw << endl;
cout << "Are software to hardware colorkey blits accelerated? " << myInfo->blit_sw_CC << endl;
cout << "Are software to hardware alpha blits accelerated? " << myInfo->blit_sw_A << endl;
cout << "Are color fills accelerated? " << myInfo->blit_fill << endl;
cout << "Total amount of video memory in Kilobytes? " << myInfo->video_mem << endl;
cout << "Width of the current video mode? " << myInfo->current_w << endl;
cout << "Height of the current video mode? " << myInfo->current_h << endl;
結(jié)果似乎是可以預(yù)料的,創(chuàng)建硬件surface和硬件加速都是不可行的。接下來(lái),我們將flag 從使用系統(tǒng)內(nèi)存的SDL_SWSURFACE換成使用顯存的SDL_HWSURFACE。
3.2:我的顯卡不支持硬件加速??!!
好吧,也許是我運(yùn)氣不好。問(wèn)題來(lái)了!
我的軟件環(huán)境是windows server 2003,硬件環(huán)境是GeForce 4 Ti 4200 AGP 8x。當(dāng)我第一次看到SDL反饋給我的信息:創(chuàng)建硬件surface不可行!硬件加速不可性!顯存大小為0!!——我快喘不過(guò)氣來(lái)。
我的第一反應(yīng)是SDL不支持我的顯卡——后面一想,不對(duì)啊,SDL到今天(2008年2月)還在更新,我顯卡可算是古董了——一定是什么地方搞錯(cuò)了,或者還有我沒(méi)有了解到的問(wèn)題。
伴隨而來(lái)的另外一個(gè)問(wèn)題是:我是不是真正把surface建立到顯存中了——盡快我要求SDL這么做。這里,我要第三次提到函數(shù)SDL_SetVideoMode()了。我們之前介紹過(guò),這個(gè)函數(shù)的返回值是一個(gè)SDL_Surface結(jié)構(gòu)的指針。而SDL_Surface結(jié)構(gòu)中有一個(gè)數(shù)據(jù)成員flags儲(chǔ)存了這個(gè)surface的位標(biāo)信息,其中就包括是否建立到了顯存里面(否則就在系統(tǒng)內(nèi)存中)。
Uint32 flags; /* Read-only */
SDL_PixelFormat *format; /* Read-only */
int w, h; /* Read-only */
Uint16 pitch; /* Read-only */
void *pixels; /* Read-write */
SDL_Rect clip_rect; /* Read-only */
int refcount; /* Read-mostly */
/* This structure also contains private fields not shown here */
} SDL_Surface;
showHex(pScreen->flags);
cout << boolalpha;
cout << "SDL_SWSURFACE? " << !(bool((pScreen->flags) & SDL_HWSURFACE)) << endl;
cout << "SDL_HWSURFACE? " << bool((pScreen->flags) & SDL_HWSURFACE) << endl;
cout << "SDL_DOUBLEBUF? " << bool((pScreen->flags) & SDL_DOUBLEBUF) << endl;
cout << noboolalpha;
請(qǐng)注兩點(diǎn):函數(shù)showHex()顯示16進(jìn)格式,在前面章節(jié)有原形和定義;SDL_SWSURFACE是0,是偽位標(biāo),因?yàn)樗cSDL_HWSURFACE只能二取一的,所以他的實(shí)際狀態(tài)可以用如上方式表示。另外,SDL_DOUBLEBUF是在開(kāi)啟硬件畫(huà)surface和加速時(shí)候很重要的位標(biāo),在后面會(huì)有介紹。
結(jié)果是——很不幸,surface沒(méi)有建立在顯存中。
3.3:SDL的環(huán)境設(shè)置。
尋找問(wèn)題和試驗(yàn)的過(guò)程很曲折。我在這里直接說(shuō)結(jié)論,在下一節(jié)中,再進(jìn)行具體的試驗(yàn)。SDL有個(gè)環(huán)境設(shè)置的概念。這是因?yàn)镾DL是跨平臺(tái)的,在不同的操作系統(tǒng)和不同的GUI之上,SDL試圖建立起一個(gè)與以上因素?zé)o關(guān)的封裝。但是因?yàn)橛布ㄖ饕革@卡)的具體多樣性,SDL在不同的OS和不同的GUI之上,使用不同的“驅(qū)動(dòng)”,以windows為例,SDL在windows上的驅(qū)動(dòng)有GDI(windib)和DirectX(directx)兩種(Linux下則更多,請(qǐng)參考官方資料),我們可以通過(guò)一個(gè)函數(shù)知道當(dāng)前SDL使用的驅(qū)動(dòng)版本。
SDL_VideoDriverName(driverName, 20);
cout << "SDL_VideoDriverName = " << driverName << endl;