【问题标题】:Android OpenGL ES process yuv preview as RGBAAndroid OpenGL ES 进程 yuv 预览为 RGBA
【发布时间】:2013-06-17 01:14:23
【问题描述】:

我想在Android平台上使用OpenGL处理​​来自相机的数据,格式为NV21。

我的代码如下:

顶点着色器:

attribute vec4 position;
attribute vec2 inputTextureCoordinate;
varying vec2 v_texCoord;
void main()
{
   gl_Position = position;
   v_texCoord = inputTextureCoordinate;
}

片段着色器:

precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D yTexture; 
uniform sampler2D uvTexture;
const mat3 yuv2rgb = mat3(
                        1, 0, 1.2802,
                        1, -0.214821, -0.380589,
                        1, 2.127982, 0
                        );

void main() {    
    vec3 yuv = vec3(
                1.1643 * (texture2D(yTexture, v_texCoord).r - 0.0627),
                texture2D(uvTexture, v_texCoord).a - 0.5,
                texture2D(uvTexture, v_texCoord).r - 0.5
                );
    vec3 rgb = yuv * yuv2rgb;
    gl_FragColor = vec4(rgb, 1.0);
}

我发送 yTexture:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, w, h, 0,                  GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE,                           ByteBuffer.wrap(data));

其中 data 是相机预览的 nv21 格式字节数组 我发送 uvTexture:

byte[] luminanceAlpha = new byte[w * h / 2];
System.arraycopy(data, w * h, luminanceAlpha, 0, w * h / 2);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,            GLES20.GL_LUMINANCE_ALPHA, w / 2, h / 2, 0,                             GLES20.GL_LUMINANCE_ALPHA,                              GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(luminanceAlpha));

这就是我认为重要的所有代码。但是当我运行程序时,我发现 GLSurfaceView 中的结果看起来更蓝。我的代码有什么问题吗。我很麻烦。

【问题讨论】:

  • 你为什么要在你的shader里做1.1643 * ()?看起来你没有使用 Y 纹理。
  • 哦,对不起。这只是一个输入错误。我已经修改过了。
  • 我觉得没问题。您确定数据包含您所期望的吗?
  • 我已经解决了这个问题。我的 yuv 数据没问题。问题是当我使用方法“GLES20.glUniform1i(mGLUniformTexture, 0)”将uvTexture发送到opengl时,我忘记添加第二个参数。所以我在片段着色器中的 uvTexture 得到了错误的值。非常感谢。
  • 在摄像头开始预览之前,可以设置PreviewCallback,然后通过onPreviewCallback方法返回摄像头数据。它是一个字节数组,格式为 NV21。您应该查看 NV21 格式文档,您将了解如何复制 y 通道数据和 uv 通道数据。如果您有任何问题,请给我打电话。

标签: android opengl-es


【解决方案1】:

为什么不使用GLSurfaceView 并生成SurfaceTexture,然后使用setPreviewTexture 将其传递给相机?如果要像素RGB数据,使用glReadPixels获取缓冲区数据。

【讨论】:

  • 感谢您的建议。因为 SurfaceTexture 只支持 API 11 及以上。而且我在使用 SurfaceTexture 时也遇到了问题。会提示警告信息'updateTexImage: clearing GL error: 0x502',但这不影响渲染。如何删除警告?
  • 你试过这个帖子Modifying camera output using SurfaceTexture and OpenGL吗?我使用VideoSurfaceview作为我的渲染环境并将MediaPlayer源更改为相机,我没有任何警告消息。
  • 我已经看到了,但不是同样的问题。我的警告根本不会影响跑步。我只是想知道。
  • 我只能猜测您的 OpenGL ES 渲染设置可能有点错误。如上所述,尝试 Google 的测试项目。 :)
  • 我找到了原因。因为我将 GL_TEXTURE_EXTERNAL_OES 作为 GL_TEXTURE_2D 发送,所以
猜你喜欢
  • 2013-06-10
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 2023-03-30
相关资源
最近更新 更多