Android OpenGL结合了SurfaceTexture(外部图像)和普通纹理

Luk*_*zný 10 android textures image opengl-es android-camera

我想将相机预览SurfaceTexture与一些叠加纹理混合.我正在使用这些着色器进行处理:

    private final String vss = "attribute vec2 vPosition;\n"
        + "attribute vec2 vTexCoord;\n"
        + "varying vec2 texCoord;\n"
        + "void main() {\n" 
        + "  texCoord = vTexCoord;\n"
        + "  gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n"
        + "}";

private final String fss = "#extension GL_OES_EGL_image_external : require\n"
        + "precision mediump float;\n"
        + "uniform samplerExternalOES sTexture;\n"
        + "uniform sampler2D filterTexture;\n"
        + "varying vec2 texCoord;\n"
        + "void main() {\n"
        +"  vec4 t_camera = texture2D(sTexture,texCoord);\n"
        //+"  vec4 t_overlayer = texture2D(filterTexture, texCoord);\n" 
        //+ "  gl_FragColor = t_overlayer;\n" + "}";
        + "  gl_FragColor = t_camera;\n" + "}";
Run Code Online (Sandbox Code Playgroud)

我的目标是混合t_camera和t_overlayer.当我单独显示t_camera或t_overlayer时,它可以工作(显示相机预览或纹理).但是当我取消注释t_overlayer时,t_camera变成黑色(不知何故被严重抽样).我的覆盖层纹理是512x512和CLAMPT_TO_EDGE.此问题仅出现在以下示例:Android模拟器,HTC Evo 3D.但是在SGS3,HTC One X上,它运行得很好.

怎么了?是Evo 3D缺少一些扩展还是什么?

小智 5

我想你有这个问题是因为你没有在你的代码上设置正确的纹理 ID。这是假设上的典型错误,看似合乎逻辑,但实际上并未在文档中定义。如果您查看此扩展的文档,您会看到以下(已编辑)文本:

每个 TEXTURE_EXTERNAL_OES 纹理对象 对于它所绑定的每个纹理单元可能需要多达 3 个纹理图像单元。当设置为 TEXTURE_EXTERNAL_OES 时,此值将介于 1 和 3 (含)之间。对于其他有效的纹理目标,该值始终为 1。注意,当绑定 TEXTURE_EXTERNAL_OES 纹理对象时,单个纹理单元所需的纹理图像单元可能是 1、2 或 3,而对于其他纹理对象,每个纹理单元正好需要 1 个纹理图像单元。

这意味着至少一个额外的将起作用,前提是您使用 id 0。在你的情况下:

GLES20.glUniform1i(sTextureHandle, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
        sTextureId);
Run Code Online (Sandbox Code Playgroud)

对于您的 2D 纹理:

GLES20.glUniform1i(filterTextureHandle, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, filterTextureID);
Run Code Online (Sandbox Code Playgroud)

我相信这会为你锻炼。


小智 3

我的 Nexus 7 也遇到了同样的问题,这让我抓狂。访问samplerExternalOES 或sampler2D 工作得很好,但在同一个着色器中访问它们会产生意想不到的结果。有时输出会是黑色的。有时,其中一项查找的输出会产生不良的量化伪影。该行为也会根据采样器绑定的纹理单元而有所不同。我确实检查了每个 opengl 错误并验证了程序结果。

最终,有效的方法是使用单独的着色器来简单地访问相机输出并将其渲染为纹理。然后可以通过常规的 Sampler2D 访问生成的纹理,并且一切都完全按预期工作。我怀疑有一个与samplerExternalOES相关的错误。