OpenGLES渲染颜色问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGLES渲染颜色问题相关的知识,希望对你有一定的参考价值。

我对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);

谢谢。

答案

在提交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数据。这将自动处理颜色转换和多平面采样,并且您不必担心它(因为它可能因平台而异)。

以上是关于OpenGLES渲染颜色问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenGLES 之纹理

OpenGL

OpenGL

iOS开发-OpenGLES 入门踩坑

哪些 OpenGL ES 2.0 纹理格式可进行颜色、深度或模板渲染?

如何在渲染之间更改片段着色器颜色?