Opengl es 2.0 draw bitmap overlay on video

走远了吗. 提交于 2019-12-05 06:55:41

I see two things that seems wrong to me.

  1. You are trying to bind everything at the same time, and hope that one call to GLES20.glDrawArrays() will draw everything.

  2. You have only one shader, where you should have two : one for doing video texture rendering, and another for your bitmap layer rendering.

What you must know is that a frame can be draw by multiple call to glDrawArrays, each call will just paint a little part over previously drawn stuff (basically).


The first part of rendering a frame in your case should look to this :

init

loadShaderForVideo()

loadShaderForBitmapLayer()

prepareYourArraysEtc()

...

loop

GLClear()

updateVideoTexture()

drawFrame(){

drawVideo(){

    bindYourActiveTextureToVideo()

    setYourVertexAttribAndUniform()

    GLES20.glDrawArrays()

}

drawBitmap() {

    bindYourActiveTextureToBitmap()

    setYourVertexAttribAndUniform() // This should be the same as above for video
    // Considering you want to draw above your video, consider activating the blending for transparency :

    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

    GLES20.glDrawArrays()

}

}


Concerning the shader, just take a look at these :

A common Vertex Shader for both :

public static final String vertexDefaultShaderCode =
        "uniform mat4 uVPMatrix;" +
                "uniform mat4 uModelMatrix;" + // uniform = input const
                "attribute vec3 aPosition;" +  // attribute = input property different for each vertex
                "attribute vec2 aTexCoordinate;" +
                "varying vec2 vTexCoordinate;" +// varying = output property different for each pixel

                "void main() {" +
                "vTexCoordinate = aTexCoordinate;" +
                "gl_Position = uVPMatrix * uModelMatrix * vec4(aPosition,1.0);" +
                "}";

Then a basic fragment shader ( for your bitmap 2D texture ) :

    public static final String fragmentDefaultShaderCode =
        "precision mediump float;" +
                "uniform sampler2D uTexture;" +
                "varying vec2 vTexCoordinate;" +

                "void main() {" +
                "  gl_FragColor = texture2D(uTexture, vTexCoordinate);" +
                "}";

Then a different version for video rendering :

    public static final String fragmentExternalShaderCode =
        "#extension GL_OES_EGL_image_external : require\n" +
                "precision mediump float;" +
                "uniform samplerExternalOES sTexture;" +
                "varying vec2 vTexCoordinate;" +

                "void main() {" +
                "  gl_FragColor = texture2D(sTexture, vTexCoordinate);" +
                "}";

Thus you will need two Programs, one with the defaultVertexShader + defaultFragmentShader and another with defaultVertexShader + fragmentExternalShaderCode.

I hope that only these modifications will solve your problem.

Regards

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!