快照(渲染到纹理)

快照 对象允许您将一组对象作为单个图像进行快照。然后,您可以修改对象并更新快照图像。与屏幕捕获 API(例如 display.capture(),它会生成包含捕获结果的新静态显示对象)相比,这提供了额外的灵活性。

创建快照

使用 Corona 的 display.newSnapshot() 方法可以轻松创建快照对象。您可以通过访问快照的 group 属性向快照添加子对象。此属性类似于普通的 GroupObject,但它不会直接影响场景。相反,这些对象会被渲染到屏幕外的纹理中,并且该纹理决定了快照渲染的内容。

快照对象通过将子对象捕获到单个缓存图像中来运行。当您第一次创建快照对象时,该对象会被初始化为在下一次渲染过程中更新此缓存图像。但是,稍后您可能需要显式指示快照更新缓存图像。例如,如果您修改了快照的子对象,则必须调用 snapshot:invalidate() 以在下一次渲染过程中更新快照。

这是一个设置快照并将其子对象插入其组的基本示例

local snapshot = display.newSnapshot( 200, 200 )

math.randomseed( 0 )

-- Add 4 fish images to the screen
for i = 1,4 do

    -- Create a fish
    local fish = display.newImage( "fish-small-red.png" )

    -- Move it to a random position relative to the snapshot's origin
    fish:translate( math.random( -100, 100 ), math.random( -100, 100 ) )

    -- Insert the fish into the snapshot
    snapshot.group:insert( fish )
end

snapshot:translate( display.contentCenterX, display.contentCenterY )  -- Center the snapshot on the screen
snapshot:invalidate()                                                 -- Invalidate the snapshot
transition.to( snapshot, { alpha=0, time=2000 } )                     -- Fade the snapshot out

矩形与快照

快照继承了矩形的所有功能。例如,所有 2.5D 效果 都可用于快照对象。

群组与快照

显示组 相比,快照有几个主要区别

边界

显示组的宽度和高度由其子对象决定,特别是子对象边界的并集。相反,快照具有预定义的宽度和高度,因此位于这些边界之外的子对象将不会被渲染。

混合

显示组分别渲染每个子对象,这会影响 alpha 的传播方式。在组中,alpha 会传播到每个子对象,并且由于每个子对象都是单独渲染的,因此当它们重叠时会发生混合。相反,快照作为单个对象进行渲染,因此 alpha 仅在子对象渲染到快照的图像后才应用。

管理子对象

快照的子对象通常包含在一个特殊的 快照组 中。因此,您不是直接将子对象添加到快照对象,而是添加到其 group 属性。

子对象失效

显示组会自动检测子对象的属性何时发生更改,例如子对象的位置。因此,在下一次渲染过程中,子对象将重新渲染。相反,快照**不会**自动检测子对象的属性何时发生更改。因此,当您修改子对象时,必须通过调用 snapshot:invalidate() 来清除快照的缓存图像。这会使快照的图像失效,以便在下一次渲染过程中进行更新。

锚点

默认情况下,组不考虑 锚点,因为它们没有预定义的边界。但是,快照是 形状对象,它们具有可控的锚点。

快照画布

通常,snapshot:invalidate() 会导致在将快照组的子对象渲染到纹理之前清除纹理。相反,当快照 canvas 失效时,子对象会渲染到纹理,而不会先清除纹理。

以下是支持画布样式在快照上进行操作的相关 API

性能

开销

快照对象依赖于 OpenGL 中称为帧缓冲区对象的功能,该功能允许您“渲染到纹理”。这是通过执行在屏幕外发生的额外渲染过程来实现的。换句话说,有一个额外的渲染过程会绘制到纹理中,并且每当通过 snapshot:invalidate() 使快照失效时,都会触发这些额外的渲染过程。由于这些额外的过程会带来一些性能损失,因此您应该避免一次调用过多的失效操作。

设备依赖性

帧缓冲区对象的性能取决于设备,因此您的结果可能会有所不同。通常,iOS 设备已针对帧缓冲区对象优化了其 OpenGL 管道,因此您可以预期获得不错的性能。