支持HW团队,就支付宝领取下面的红包吧! (打开支付宝就能领取!er1OEj73Uj), (打开支付宝收索“516503473”), 你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

Login or Sign up | Validate
| Search

博主:初学MPEG

初学MPEG 本博客-采用Python的web框架Django与Mysql数据库,致力于对Python、Django的了解 与研究
Django技术QQ群:XXXXXXX
Python技术QQ群:XXXXXXX

Category

Keywords

本站最新博文

友情链接  

[转]视频属性信息(VideoInfo)

类别:游戏 状态:游客可见,可回,会员可关联(良好) 阅读:4216 评论:0 时间:May 9, 2013, 11:04 p.m.
关键字:SDL

  来源:http://www.cppblog.com/lf426/archive/2008/02/10/42619.html        作者:龙飞

1:获取视频属性信息。

const SDL_VideoInfo *SDL_GetVideoInfo(void);

我们在前一小节中,为了尽快实现一个SDL的运行窗口,跳过了很多细节,也留下了很多问题。其中一个很重要的问题就是:我们到底有没有使用到显卡的硬件加速?因为硬件的差异性,直接使用硬件接口的时候,会出现很多新的问题。这些问题在第(四)章中,我将以自己的操作系统和显卡硬件配置,通过试验得到结论,而在这之前,我们还必须弄清楚其他几个问题。
SDL_GetVideoInfo()将返回当前SDL运行窗口的视频属性信息,其数据组织在一个名为SDL_VidioInfo的结构中。该函数就是返回这个只读结构的指针。

typedef struct
{
        Uint32 hw_available:1; // 创建硬件surface的可行性(1表示可以,0表示不可以,后同)
        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; // 当前显示驱动(video device)的像素格式(pixel format)
        int current_w; // 当前窗口的宽
        int current_h; // 当前窗口的宽
} SDL_VideoInfo;

初看这个结构似乎有点让人头大,其实分析起来很简单,成员名称也很友好,容易让人记忆。hw_availabale表示创建硬件surface的可行性(1表示可以,0表示不可以,后同);wm_available表示是否存在可用的窗口管理器;3-9行表示了一系列硬件到硬件,软件到硬件加速的可行性;video_men表示显存大小;vfmt是当前显示驱动(video device)的像素格式(pixel format);current_w和current_h是当前窗口的宽和高。
我们在使用在系统内存中建立SDL运行窗口的方式来察看这些成员数据。

SDL_Init(SDL_INIT_VIDEO);
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。

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的位标信息,其中就包括是否建立到了显存里面(否则就在系统内存中)。

typedef struct SDL_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;

这里我们继续忽略其他不熟悉的数据成员,直接将flags的信息读出来。

cout << "pScreen->flags = ";
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:SDL的环境设置。

寻找问题和试验的过程很曲折。我在这里直接说结论,在下一节中,再进行具体的试验。SDL有个环境设置的概念。这是因为SDL是跨平台的,在不同的操作系统和不同的GUI之上,SDL试图建立起一个与以上因素无关的封装。但是因为硬件(主要指显卡)的具体多样性,SDL在不同的OS和不同的GUI之上,使用不同的“驱动”,以windows为例,SDL在windows上的驱动有GDI(windib)和DirectX(directx)两种(Linux下则更多,请参考官方资料),我们可以通过一个函数知道当前SDL使用的驱动版本。

char *SDL_VideoDriverName(char *namebuf, int maxlen);

如果返回空指针,则表示SDL_Init()没有装载或出现异常。我们可使用下面这样的语句查看当前SDL使用的驱动版本名字。

char driverName[20];
SDL_VideoDriverName(driverName, 20);
cout << "SDL_VideoDriverName = " << driverName << endl;

结果是:windib。为什么SDL官方资料显示,默认值是directx呢?(这不是反问,这是我的疑问,请知道答案的同学跟我联系,谢谢)——结论是,windib无法打开硬件加速,要使用硬件加速,必须使用directx。官方资料上用了很简短的描述来说明进行SDL的环境设置。在后面的章节中,我们将使用:

putenv("SDL_VIDEODRIVER=directx");

注意:这个函数必须用在SDL_Init();之前才有实际效果。来设置为directx环境。(VC下为了解除编译警告,也可使用SDL_putenv()来代替putenv(),效果都一样。)之后除了用SDL_VideoDriverName()获取显示驱动信息,还可以使用:(同样,VC下可使用SDL_getent()替换)

const char* myvalue = getenv("name") ;

来获取相关的环境信息(包括显示驱动信息。"name"换为"SDL_VIDEODRIVER")。

操作:

Please Login (or Sign Up) to leave a comment