我对OpenGLES很新。我试图将Android相机帧(YUV)渲染为四边形。我正在使用类似于here的方法。
问题是我得到了这个颜色问题,如下所示。我不认为这是一个着色器问题,因为我已经尝试了其他着色器并且它导致了相同的渲染。
这是我的渲染代码:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureYHandle);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
mWidth, mHeight, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, mBufferY);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureUVHandle);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE_ALPHA,
mWidth/2, mHeight/2, 0, GLES20.GL_LUMINANCE_ALPHA, GLES20.GL_UNSIGNED_BYTE, mBufferUV);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, GLES20.GL_NONE);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureYHandle);
mTextureYHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_InputImageTexture0");
GLES20.glUniform1i(mTextureYHandle, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureUVHandle);
mTextureUVHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_InputImageTexture1");
GLES20.glUniform1i(mTextureUVHandle, 1);
GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
0, quadVertices);
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false,
0, quadTextureCoordinates);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, GLES20.GL_NONE);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, GLES20.GL_NONE);
谢谢。
在提交UV缓冲区之前,您无法切换纹理单元 - 看起来您已经省略了GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
。
假设这不是复制和粘贴错误,它会覆盖您的亮度纹理,因此您最终会对亮度和色度的UV纹理进行采样。我希望能给你非常灰色的图像,因为U和V的范围是(-0.5,0.5),这意味着当渲染为字节0时,亮度为128。
建议的诊断检查:完全跳过UV,只需上传并将Y显示为灰度。
您还可以在建立着色器输入时跳过将活动纹理重新绑定到采样器。
通常,使用SurfaceTexture
直接将相机数据导入为EGLImage更有效,然后使用GL_OES_EGL_image_external
扩展通过片段着色器中的samplerExternalOES
本地访问YUV数据。这将自动处理颜色转换和多平面采样,并且您不必担心它(因为它可能因平台而异)。