gpt4 book ai didi

java - OpenGL ES 2.0 - 如何有效地将纹理复制到帧缓冲区中

转载 作者:太空宇宙 更新时间:2023-11-04 12:47:54 25 4
gpt4 key购买 nike

简而言之 - 我有一个 OpenGL 纹理,需要在 OpenGL ES 2.0 下以最有效的方式将其复制到 FBO 或另一个纹理中。

目前我只是将第一个纹理绘制到 FBO 中。

有没有更有效的方法?例如。某种像素复制,不涉及将像素数据拉回 RAM,然后缓冲到另一个纹理 - 在 ES 2.0 配置文件中。

为您提供背景信息 - 这是与视频渲染相关的:

我有一个 OpenGL 纹理,它使用来自 LibVLC 的视频帧数据进行缓冲,但由于我的应用程序重绘率和解码器刷新率之间的计时问题,OpenGL 纹理可能没有新的帧要更新,如果我将纹理绘制到屏幕上而没有要更新的帧,则非常奇怪 - 它不是包含前一帧的数据,而是绘制自己的一些奇怪的图像(它看起来像太空入侵者??) - 因此为什么我需要“缓存”前一帧的内容。

具体来说,这是一个 OpenGL 纹理,用于创建 Android SurfaceTexture,我必须手动调用 updateTexImage 和 releaseTexImage 来更新纹理的内容,然后在绘制 SurfaceTexture 的内容后标记它已完成。如果我不发布它,那么就无法更新它的新框架。如果我释放它,我就无法多次重绘同一帧。这导致我在纹理更新后对其进行缓存,以便解码器可以自由地写入它,并且如果当我再次绘制且尚未更新时,我仍然拥有前一帧。

谢谢。

最佳答案

该解决方案基于如何正确地与 Android SurfaceTexture 交互以避免必须完全缓存其内容。

如果有人想分享有关 OpenGL ES 2.0 中高效纹理副本的答案,请随意 - 这将适合我原来的问题。

对于任何感兴趣的人,这就是我所做的:

用于在 Android 上渲染视频的 GLPaint 类包含 SurfaceTexture 实例,它是从 JOGL OpenGL 纹理创建的(使用它的 ID) - 这使我能够将纹理绘制为 GLPaint.paint 函数的一部分。

该GLPaint实现了SurfaceTexture.OnFrameAvailableListener接口(interface)的onFrameAvailable方法。我有一个私有(private) boolean 值来标记第一帧何时被“写入” - 这是避免过早释放 SurfaceTexture 所必需的。

类 GUIThreadLock 是我对 ReentrantLock 的扩展 - 我扩展它以获得额外的调试信息并创建静态单例。这个锁定在我的 UI 中线程的“一进一出” Controller 中,确保一次只有一个线程在我的 UI 中处于 Activity 状态(通常只是主渲染器循环程序),而且每当一个线程分别获取和放弃锁时,也会处理将 OpenGL 上下文绑定(bind)或取消绑定(bind)到锁所有者线程。

@Override
public void onFrameAvailable( SurfaceTexture pSurfaceTexture )
{
try
{
GUIThreadLock.acquire();
if( written )
{
pSurfaceTexture.releaseTexImage();
}
pSurfaceTexture.updateTexImage();
written = true;
}
finally
{
GUIThreadLock.relinquish();
}
}

这意味着当新帧准备好时,SurfaceTexture 会释放旧帧并更新为新帧 - 然后它会与当前帧一起缓冲,用于我希望绘制视频的任何点,直到下一帧准备好。 GUIThreadLock 可以保护 SurfaceTexture 在我绘制内容时不更新内容,但也获取我的 GL 上下文,以便回调线程可以在此处实际执行更新。

我的重绘线程在绘制我的应用程序之前还需要 GUIThreadLock - 因此 GL 上下文受到保护,并且框架更新和框架绘制之间的关系得到巩固。

关于java - OpenGL ES 2.0 - 如何有效地将纹理复制到帧缓冲区中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36132302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com