我正在设计一个应用程序,它有一个OpenGL处理管道(着色器集合),同时要求最终用户看到未处理的摄像机预览。
例如,假设您要向用户显示摄像机预览,同时计算从摄像机接收到的场景中的红色对象的数量,但是用户不应该看到任何用于计数对象(如色调过滤等)的着色器。
我该怎么做才能把这件事做好?
我知道我可以设置一个摄像机预览,然后在回调上以YUV格式接收相机帧数据,然后将其转储到一个OpenGL纹理中,然后以这种方式处理该帧,然而,这与它的性能问题有关。我必须往返从相机硬件到VM的数据,然后把它传回GPU内存。我使用SurfaceTexture直接以OpenGL可理解的格式从相机获取数据,并将其传递给我的着色器来解决这个问题。
我想我可以向最终用户展示相同的未处理SurfaceTexture,但是TextureView没有构造函数或设置器,可以将它传递给我希望它呈现的SurfaceTexture。它总是创造自己的。
以下是我当前设置的概述:
显然,通过这个设置,我向用户展示了处理过的帧,这不是我想要的。此外,帧的处理不是实时的.基本上,我运行从相机输入通过链一次,一旦所有的过滤器完成,我调用updateTexImage从相机抓取下一帧。在Nexus 4上,我的处理速度大约是每秒10帧。
我觉得我可能需要使用2个GL上下文,一个用于实时预览,一个用于处理,但我不确定。我希望有人能把我推向正确的方向。
发布于 2013-09-11 19:26:17
你能上传一些你正在使用的代码吗?
您可能可以在创建的纹理上调用glDrawArrays并绑定到最初用于显示预览的表面视图,然后刷新它并将单独的纹理绑定到其他纹理以进行分析。就像这样
GLES20.glUseProgram(simpleProgram);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glUseProgram(crazyProgram);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);在这里,相机的预览表面被绑定到纹理,然后为texture1创建一个单独的表面解析式
也许吧?
发布于 2014-05-18 12:18:12
除非您的处理速度慢于实时,否则答案很简单:只需将原始相机纹理保持不变,将处理后的图像计算成不同的纹理,并在单个GLView中并排显示给用户。保持一个线程,因为所有的处理都发生在GPU上。多线程只会使事情变得复杂。
处理步骤的数量并不重要,因为可以有任意数量的中间纹理(也请参见ping-ponging),它们从未显示给用户--没有人和任何东西强迫您这样做。
实时的概念在这里可能令人困惑。只要把一个框架想象成一个不可分割的时间快照。通过这样做,您将忽略图像从摄像机到屏幕所需的延迟,但是如果您可以将其保持在交互帧速率(例如至少每秒20帧),那么这一点可以被忽略。
另一方面,如果您的处理要慢得多,您需要在相机馈送中引入延迟和只处理每一个第N帧,或者交替地实时显示每个摄像机帧,然后让下一个处理帧落后。要做到这一点,您可能需要两个单独的呈现上下文来启用异步处理,这可能很难在Android上完成(或者就像创建第二个GLView一样简单,因为您可以在上下文之间不进行数据共享)。
https://stackoverflow.com/questions/18449162
复制相似问题