翻转 Surface (Direct3D 9)

Direct3D 应用程序通常通过在后台缓冲区中生成动画帧并按顺序呈现动画序列来显示动画序列。 后台缓冲区组织成交换链。 交换链是一系列一个接一个地“翻转”到屏幕的缓冲区。 这可用于在内存中呈现一个场景,然后在渲染完成后将场景翻转到屏幕。 这避免了所谓的撕裂现象,并允许更流畅的动画。

在 Direct3D 中创建的每个设备至少有一个交换链。 初始化第一个 Direct3D 设备时,需要设置 D3DPRESENT_PARAMETERS 的 BackBufferCount 成员,这将告知 Direct3D 交换链中的后台缓冲区数。 对 IDirect3D9::CreateDevice 的调用随后会创建 Direct3D 设备和相应的交换链。

使用 IDirect3DDevice9::P resent 请求表面翻转操作时,将交换指向前面缓冲区和后端缓冲区的 Surface 内存的指针。 翻转是通过切换显示设备用于引用内存的指针来执行的,而不是通过复制表面内存来执行的。 当翻转链包含一个前缓冲区和多个后部缓冲区时,指针以圆形模式切换,如下图所示。

具有一个前缓冲区和两个后部缓冲区的翻转链图

可以通过调用 IDirect3DDevice9::CreateAdditionalSwapChain 为设备创建附加交换链。 应用程序可以为每个视图创建一个交换链,并将每个交换链与特定窗口相关联。 应用程序在每个交换链的后台缓冲区中呈现图像,然后单独呈现它们。 IDirect3DDevice9::CreateAdditionalSwapChain 采用的两个参数是指向 D3DPRESENT_PARAMETERS 结构的指针和指向 IDirect3DSwapChain9 接口的指针的地址。 然后,可以使用 IDirect3DSwapChain9::P resent 将下一个后台缓冲区的内容显示到前缓冲区。 请注意,一个设备只能有一个全屏交换链。

可以通过调用 IDirect3DDevice9::GetBackBufferIDirect3DSwapChain9::GetBackBuffer 方法获取对特定后台缓冲区的访问权限,这些方法返回指向表示返回的后台缓冲区图面 的 IDirect3DSurface9 接口的指针。 请注意,调用此方法会增加 IDirect3DDevice9 接口上的内部引用计数,因此请务必在使用此图面时调用 IUnknown ,否则会出现内存泄漏。

请记住,Direct3D 通过交换链中的表面内存指针(而不是通过交换表面本身)来翻转表面。 这意味着将始终呈现到接下来显示的后台缓冲区。

请务必注意显示适配器驱动程序执行的“翻转操作”与应用于使用 D3DSWAPEFFECT_FLIP 创建的交换链的“演示”操作之间的区别。

术语“翻转”通常表示更改显示适配器用于生成其输出信号的视频内存地址范围的操作,从而导致显示以前隐藏的后台缓冲区的内容。 在 Direct3D 9 中,术语通常用于描述使用D3DSWAPEFFECT_FLIP交换效果创建的任何交换链中的后台缓冲区的表示形式。

虽然当交换链为全屏时,这种“Present”操作几乎总是通过翻转操作实现的,但当交换链开窗时,它们必须通过复制操作来实现。 此外,显示适配器驱动程序可能会根据D3DSWAPEFFECT_DISCARD和D3DSWAPEFFECT_COPY使用翻转来实现针对全屏交换链的“演示”操作。

上述讨论适用于使用 D3DSWAPEFFECT_FLIP 创建的全屏交换链的常见用例。

有关窗口和全屏交换链的不同交换效果的更一般讨论,请参阅 D3DSWAPEFFECT

Direct3D Surfaces