I’m trying to show a simple texture in OpenGL ES 2.0 (Android 4.0.4, Galaxy Nexus) as fullscreen background using a vertex and a fragment shader. The final result should be to display the camera image there, but for a start, simple texture from a file would be sufficient. I tested many things and for a short while it worked as I used OpenGL ES 1.x but as I plan to use shader for YUV->RGB conversion, I have to go with 2.0.
I have the following vertex shader:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main() {
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy
}
and this fragment shader:
varying highp vec2 textureCoordinate;
uniform sampler2D videoFrame;
void main() {
gl_FragColor = texture2D(videoFrame, textureCoordinate);
}
Shader creation as such should be ok, because when I write gl_FragColor=vec4(1,0,0,0) it works perfectly well and shows me a red background.
OnSurfaceCreated I do the following:
a = makeFloatBuffer(squareVertices);
b = makeFloatBuffer(textureVertices);
with squareVertices and textureVertices as follows:
static float squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
1.0f, 1.0f, };
static float textureVertices[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, };
OnSurfaceChanged I do the following:
GLES20.glViewport(0, 0, width, height);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.raw.htc);
GLES20.glGenTextures(1, textures, 0);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
R.raw.htc is 128×128 pixels png.
And OnDrawFrame:
GLES20.glUseProgram(program);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame"),0);
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
GLES20.glClearDepthf(1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
int x = GLES20.glGetAttribLocation(program, "position");
int y = GLES20.glGetAttribLocation(program, "inputTextureCoordinate");
GLES20.glEnableVertexAttribArray(x);
GLES20.glVertexAttribPointer(x, 2, GLES20.GL_FLOAT, false, 0, a);
GLES20.glEnableVertexAttribArray(y);
GLES20.glVertexAttribPointer(y, 4, GLES20.GL_FLOAT, false, 0, b);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
The only thing I see is a completely black screen and I have no idea why. I saw some other posts here with similar problems but none of the proposed solution helped me out or no solution was given at all.
As said above, we could find a solution for the issue although we don’t know exactly the reason why it is working now and was not before (we changed several things and suddenly it worked). Nonetheless I want to share our working version:
The shader are now completed to also do the YUV->RGB conversion:
The vertex shader:
The fragment shader:
OnSurfaceCreatedis still the same but the definition of the vertices changed a bit:OnSurfaceChanged:OnDrawFrame: