OpenGLES渲染颜色问题

时间:2017-12-19 18:12:30

标签: android opengl-es

我对OpenGLES很陌生。我试图将Android相机帧(YUV)渲染为四边形。我使用的方法类似于here

问题是我遇到了这个颜色问题,如下所示。我不认为这是一个着色器问题,因为我已尝试过其他着色器并且导致了相同的渲染。

enter image description here enter image description 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);

感谢。

2 个答案:

答案 0 :(得分:0)

在提交UV缓冲区之前无法切换纹理单元 - 看起来你已经省略了GLES20.glActiveTexture(GLES20.GL_TEXTURE1);

假设这不是复制和粘贴错误,它会覆盖您的亮度纹理,因此您最终会对亮度和色度的UV纹理进行采样。我希望能给你非常灰色的图像,因为U和V的范围是(-0.5,0.5),这意味着当渲染为字节0时,亮度为128.

建议的诊断检查:完全跳过UV,只需上传并将Y显示为灰度。

您还可以在建立着色器输入时跳过将活动纹理重新绑定到采样器。

答案 1 :(得分:0)

通常,使用SurfaceTexture直接将相机数据导入为EGLImage,然后使用GL_OES_EGL_image_external扩展名通过{{本地访问YUV数据 - 效率更高片段着色器中的1}}。这将自动处理颜色转换和多平面采样,让您不必担心它(因为它可能因平台而异)。