随笔 - 96  文章 - 255  trackbacks - 0
<2008年2月>
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 488849
  • 排名 - 37

最新评论

阅读排行榜

评论排行榜

作者:龙飞

3.1:试验——硬件渲染下关闭双缓存。
现象:front图片出现不断被“撕裂”的效果。

        双缓存的概念,是在计算机速度还不足以满足“即时作图”的情况下的一种技术。即,在屏幕(即前台的帧缓存framebuffer)上显示一帧图片的同时,在后台一个帧缓存的映射中作图。这样,只有当屏幕画面需要改变的时候,后台的缓存才交换到前台来,这样就避免了在前台出现计算机“作图”的过程。
        关闭双缓存之后,我们实际上看到的是计算机在不停的“作图”——blit一次back,然后blit一次front,然后循环,所以被“撕裂”的画面,实际上是back和front图片“混合”的效果。
        在软件渲染的时候,为什么没有双缓存也不会出现这个问题呢?我的猜想是:图片的像素数据实际上还是储存在内存中的,无论是系统内存还是显存,实际上都是通过一种影射提供给真正“成像”的帧缓存的。所以,实际上,无论软渲染还是硬渲染,图片实际上都是被“双缓存”的,所不同的是,在使用硬件渲染的时候,SDL试图给我们提供直接访问硬件的接口,导致我们对创建在hw下的surface的操作,就类似在直接操作帧缓存,但是,我们是不是真的就直接访问了帧缓存呢?

3.2:试验——单帧硬件渲染下打开双缓存。
现象:图片出现闪烁。

        闪烁实际上是图片与一个空屏(全黑,0像素)交互显示的结果。为了验证这个猜想,我们可以尝试blit同一个surface两次,则可以解决这个问题。这个试验其实更形象的显示了什么是“双”缓存,两次blit可以让两个缓存都存储上相同的图片,渲染时候就不会出现闪烁。

3.3:我们可以直接访问缓存的地址吗?

        SDL官方推荐的那篇论文介绍可以通过pScreen->pixels查看像素缓存的地址,并且认为如果地址改变则映射交换缓存的实质是传递了数据结构的指针;而如果不变则是直接拷贝了数据结构的数据——事实真的是这样吗?
        我们知道,pScreen是通过SDL_SetVideoMode()函数获得的。这是一个特殊的surface,因为它既具有一般surface的属性,而且也是SDL用于实际显示的窗口surface。我们建立起pScreen的时候,并没有赋予他任何的像素数据。
        如果在软件渲染的环境下,pScreen->pixels可以成功返回一个地址;但是在硬件渲染的环境下,pScreen->pixels则返回了空指针!这意味着什么?要么就真是一个空指针(因为pScreen实际上的像素数据为空),另外一个可能是——这个地址我们不可以访问!我其实倾向于后者的解释,因为软件渲染下,同样为空像素的pScreen并不返回空指针。所以,我的猜想是,SDL中,帧缓存并不能被直接访问,但是我们可以访问帧缓存的映射,并且模拟访问帧缓存的效果。

3.4:对于双缓存现象的另外一种解释。

        在SDL官方推荐的那篇论文中,作者认为出现“撕裂”现象的原因是硬件加速与软件的不同步。简单来说,在软件渲染情况下,语句被一条条逐步执行,比如:1、blit back;2、blit front;3、flip screen。这3个步骤,即使都需要一定的执行时间,也是有先后秩序的。但在硬件渲染环境下,这3条指令被程序直接仍给了显卡,有可能前面两次blit还没执行完,就flip了。所以,作者认为,SDL_DOUBLEBUF位标的使用实际上是改变了SDL_Flip()的执行效果:无双缓存的时候,将直接把当时的情况flip出来;打开双缓存的时候,flip指令则成为了递交了请求,然后不暂定的等待(所谓轮询),直到所有的“作图”指令执行完才显示出来——似乎也说得过去,但是我以为如此解释原理过于的复杂的。当然,也可能我对鸟语理解得不对,欢迎大家继续讨论这个话题。

posted on 2008-02-15 17:35 lf426 阅读(4098) 评论(4)  编辑 收藏 引用 所属分类: SDL入门教程

FeedBack:
# 补充1 2008-02-15 18:15 lf426
补充一个问题:当把一个surface blit 到另外一个surface上的时候,引起后者像素数据变化了吗?或者说,源surface的数据“画”到了目的surface上了吗?我的试验结果是,如果在blit后释放源surface,程序会出现问题。这至少说明blit不是真正的“画”图。  回复  更多评论
  
# re: SDL入门教程(四):3、SDL的软、硬件渲染的深入试验和分析 2010-10-16 20:58 fly
对于实验1.实验结果,图像平稳,并未有撕裂现象.用的代码是上一节的.
根据我的理解,对代码做了以下修改:
SCREEN_FLAGS = SDL_FULLSCREEN | SDL_HWSURFACE;
去掉SDL_DOUBLEBUF.
运行.图片正常.

对于实验2.实验结果并未出现闪烁.图像平稳.
恢复代码.修改loopRender函数中的
把源表面修改成任意相同的.
if ( SDL_BlitSurface(pBack, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();
if ( SDL_BlitSurface(pBack, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();


我理解的对吗?  回复  更多评论
  
# re: SDL入门教程(四):3、SDL的软、硬件渲染的深入试验和分析[未登录] 2011-06-16 08:54 wonder
我和你做的一样,也没有出现作者说的实验结果@fly
  回复  更多评论
  
# re: SDL入门教程(四):3、SDL的软、硬件渲染的深入试验和分析 2011-08-04 17:32 waynewonk
我出现了:去掉双缓存,Front撕裂的情况。
但是在单帧情况下没有出现闪烁。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理