作者:龙飞
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入门教程