【发布时间】: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 通道数据。如果您有任何问题,请给我打电话。