Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3518332
  • 博文数量: 864
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10634
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/zytc2009/BigTeam_learning

文章分类

全部博文(864)

文章存档

2023年(1)

2021年(1)

2019年(3)

2018年(1)

2017年(10)

2015年(3)

2014年(8)

2013年(3)

2012年(69)

2011年(103)

2010年(357)

2009年(283)

2008年(22)

分类: C/C++

2010-12-27 09:30:14

3.1:获取视频属性信息。
const SDL_VideoInfo *SDL_GetVideoInfo(void);
        我们在前一小节中,为了尽快实现一个SDL的运行窗口,跳过了很多细节,也留下了很多问题。其中一个很重要的问题就是:我们到底有没有使用到显卡的硬件加 速?因为硬件的差异性,直接使用硬件接口的时候,会出现很多新的问题。这些问题在第(四)章中,我将以自己的操作系统和显卡硬件配置,通过试验得到结论, 而在这之前,我们还必须弄清楚其他几个问题。
        SDL_GetVideoInfo()将返回当前SDL运行窗口的视频属性信息,其数据组织在一个名为SDL_VidioInfo的结构中。该函数就是返回这个只读结构的指针。
typedef struct{
  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;
        初看这个结构似乎有点让人头大,其实分析起来很简单,成员名称也很友好,容易让人记忆。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(64048032, 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的位标信息,其中就包括是否建立到了显存里面(否则就在系统内存中)。

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.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")。
阅读(1496) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~