【问题标题】:Render-to-texture and synchronization渲染到纹理和同步
【发布时间】:2013-02-26 05:45:41
【问题描述】:

我有一个使用标准渲染到纹理设置的跨平台代码库(iOS 和 Android)。每一帧(初始化后),发生如下顺序:

  1. 带有纹理颜色附件的帧缓冲区的glBindFramebuffer
  2. 渲染一些东西
  3. *
  4. glBindFramebuffer 默认帧缓冲区(Android 上为 0,iOS 上通常为 2)
  5. glBindTexture 作为第一个帧缓冲区的颜色附件的纹理
  6. 使用绑定纹理进行渲染

在 iOS 和某些 Android 设备(包括模拟器)上,这可以正常工作并且符合预期。在其他设备上(当前位于运行 4.0.4 的三星 Galaxy Note 前面),使用纹理的第二阶段渲染看起来“跳跃”。其他动画在与“跳跃”位相同的屏幕上继续以 60 fps 运行;我的结论是目标纹理的变化在第二次渲染过程中并不总是可见的。

为了验证这个理论,我在上面标有 * 的步骤中插入了一个 glFinish()。现在,在所有设备上,这具有正确的行为。有趣的是, glFlush() 并不能解决问题。但是 glFinish() 很昂贵,而且我还没有看到任何文档表明这应该是必要的。

所以,我的问题是:在完成对纹理的渲染后,我必须做什么才能确保最近绘制的纹理在以后的渲染过程中可用?

【问题讨论】:

  • 听起来不像是合理的 OpenGL 行为。我不是 ES 专家,但我很确定 ES(至少按照规范)不会改变这种基本的同步行为。如果这不成立,你就不能依赖任何东西,比如在渲染之前依赖缓冲区写入的完成。这些操作没有其他显式同步机制,因此命令队列必须按顺序正确同步。
  • 我认为没有其他人观察到这一点?当然,很可能是特定于设备/构建的,但这并不好玩。

标签: android opengl-es


【解决方案1】:

你描述的代码应该没问题。

只要您使用的是单个上下文,并且没有选择加入任何放松同步行为的扩展(例如 EXT_map_buffer_range),那么每个命令的执行都必须看起来与指定的完全相同的顺序执行一样在 API 中,在您的 API 使用中,您在读取纹理之前先渲染纹理。

鉴于此,您可能会在这些设备上遇到驱动程序错误。你能列出哪些设备遇到了这个问题吗?您可能会找到常见的硬件或驱动程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多