昨天闲来没事,特地跟踪了下Farcry2引擎的渲染流程,无意间发现Farcry2每帧竟然会多次调用BeginScene和EndScene函数,我以前的认识是每帧开始的时候BeginScene,Present之前EndScene,一般为了gpu和cpu的并行性,会在EndScene和Present函数之间插入一些计算代码(比如物理计算等),让cpu不至于等待gpu绘图。

很多人可能会认为在SetRenderTarget之后要BeginScene,使用完RenderTarget后要EndScene,网络上有很多例子也是这样写的,但这是完全错误的,渲染RenderTarget不需要Begin和End,否则会导致D3D_ERROR,如下:

Direct3D9: (ERROR) :BeginScene, already in scene. BeginScene failed.

就是说不允许连续两次的BeginScene调用,所以一般就是一帧调用一次Begin和End函数,而Farcry2非常奇怪,它存在如下函数调用顺序:
GetBackBuffer ->BackBuffer
SetRenderTarget
BeginScene
Some Draw Call
EndScene

BeginScene
Some Draw Call
EndScene

……

SetRenderTarget( BackBuffer )
BeginScene
Some Draw Call
EndScene

BeginScene
Some Draw Call
EndScene

……

Present

有时候甚至会出现一对空的

BeginScene
EndScene

中间什么也没干,我很好奇这些函数到底有什么特别的用法,我在DXSDK文档和google都搜索了,没有找到关于此的描述,不明白其中的原因,我猜想是不是这样可以提高cpu和gpu之间的并行率,但我以自己引擎来测试,把一些渲染代码放在一起Begin/End,没有发现有效率的提升,如果有那位看到此博客的朋友知道原因,希望不吝赐教。