作者:龙飞
3.1:获取视频属性信息。
SDL_GetVideoInfo()将返回当前SDL运行窗口的视频属性信息,其数据组织在一个名为SDL_VidioInfo的结构中。该函数就是返回这个只读结构的指针。
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;
我们在使用在系统内存中建立SDL运行窗口的方式来察看这些成员数据。
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;
结果似乎是可以预料的,创建硬件surface和硬件加速都是不可行的。接下来,我们将flag 从使用系统内存的SDL_SWSURFACE换成使用显存的SDL_HWSURFACE。
3.2:我的显卡不支持硬件加速??!!
好吧,也许是我运气不好。问题来了!
我的软件环境是windows server 2003,硬件环境是GeForce 4 Ti 4200 AGP 8x。当我第一次看到SDL反馈给我的信息:创建硬件surface不可行!硬件加速不可性!显存大小为0!!——我快喘不过气来。
我的第一反应是SDL不支持我的显卡——后面一想,不对啊,SDL到今天(2008年2月)还在更新,我显卡可算是古董了——一定是什么地方搞错了,或者还有我没有了解到的问题。
伴随而来的另外一个问题是:我是不是真正把surface建立到显存中了——尽快我要求SDL这么做。这里,我要第三次提到函数SDL_SetVideoMode()了。我们之前介绍过,这个函数的返回值是一个SDL_Surface结构的指针。而SDL_Surface结构中有一个数据成员flags储存了这个surface的位标信息,其中就包括是否建立到了显存里面(否则就在系统内存中)。
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;
请注两点:函数showHex()显示16进格式,在前面章节有原形和定义;SDL_SWSURFACE是0,是伪位标,因为它与SDL_HWSURFACE只能二取一的,所以他的实际状态可以用如上方式表示。另外,SDL_DOUBLEBUF是在开启硬件画surface和加速时候很重要的位标,在后面会有介绍。
结果是——很不幸,surface没有建立在显存中。
3.3:SDL的环境设置。
寻找问题和试验的过程很曲折。我在这里直接说结论,在下一节中,再进行具体的试验。SDL有个环境设置的概念。这是因为SDL是跨平台的,在不同的操作系统和不同的GUI之上,SDL试图建立起一个与以上因素无关的封装。但是因为硬件(主要指显卡)的具体多样性,SDL在不同的OS和不同的GUI之上,使用不同的“驱动”,以windows为例,SDL在windows上的驱动有GDI(windib)和DirectX(directx)两种(Linux下则更多,请参考官方资料),我们可以通过一个函数知道当前SDL使用的驱动版本。
SDL_VideoDriverName(driverName, 20 );
cout << " SDL_VideoDriverName = " << driverName << endl;