Andorid OpenGL 多层纹理

在opengl 可以使用多个纹理单元,从而实现了使用多成纹理渲染,在使用的时候也需要绑定多个纹理单元,然后在GLSL中使用多个纹理绘制即可。

话不多少直接上代码

public class TextureRender implements GLSurfaceView.Renderer {

private Context context;

private int program;
private final float vertext [] = {
        1, 1, 0,   // top right
        -1, 1, 0,  // top left
        -1, -1, 0, // bottom left
        1, -1, 0,  // bottom right
};

private final short position [] = {0, 1, 2, 2, 3, 0};


private FloatBuffer verextBuffer = null;
private ShortBuffer shortBuffer = null;
private FloatBuffer texBuffer;

private int v_position;
private int tex_position;
private int texture;
private int textureUniform;
private int matrix;
private int watermark;
private int watermarkUniform;

private float texure [] = {
        0f, 0f,
        1f, 0f,
        1f, 1f,
        0f, 1f };

public TextureRender(Context context){
    this.context =  context;
    verextBuffer = ByteBuffer.allocateDirect(vertext.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertext);
    verextBuffer.position(0);

    shortBuffer = ByteBuffer.allocateDirect(position.length * 2)
            .order(ByteOrder.nativeOrder()).asShortBuffer().put(position);
    shortBuffer.position(0);

    texBuffer = ByteBuffer.allocateDirect(texure.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer().put(texure);
    texBuffer.position(0);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    program = GLES20.glCreateProgram();
    int vertex = Util.createShade(GLES20.GL_VERTEX_SHADER,
            Util.readTextResourceFromRaw(context, R.raw.texture_vertex));
    int fragment = Util.createShade(GLES20.GL_FRAGMENT_SHADER,
            Util.readTextResourceFromRaw(context, R.raw.texture_fragment));

    GLES20.glAttachShader(program, vertex);
    GLES20.glAttachShader(program, fragment);
    GLES20.glLinkProgram(program);
    GLES20.glUseProgram(program);

    v_position = GLES20.glGetAttribLocation(program, "aPos");
    GLES20.glEnableVertexAttribArray(v_position);
    GLES20.glVertexAttribPointer(v_position, 3, GLES20.GL_FLOAT, false, 12, verextBuffer);

    tex_position = GLES20.glGetAttribLocation(program, "v_texCoord");
    GLES20.glEnableVertexAttribArray(tex_position);
    GLES20.glVertexAttribPointer(tex_position, 2, GLES20.GL_FLOAT, false, 0, texBuffer);

    textureUniform = GLES20.glGetUniformLocation(program, "u_samplerTexture");
    GLES20.glUniform1i(textureUniform, 0);

    watermarkUniform = GLES20.glGetUniformLocation(program, "watermark");
    GLES20.glUniform1i(watermarkUniform, 1);


    try {
        texture = Util.createTexture(BitmapFactory.decodeStream(context.getAssets().open("texture.png")));
        watermark = Util.createTexture(BitmapFactory.decodeStream(context.getAssets().open("watermark.png")));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    GLES20.glViewport(0, 0, width, height);
    //设置相机位置
}

@Override
public void onDrawFrame(GL10 gl) {
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, watermark);

    // 用 glDrawElements 来绘制,mVertexIndexBuffer 指定了顶点绘制顺序
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, position.length,
            GLES20.GL_UNSIGNED_SHORT, shortBuffer);
}}

下面是createTexture方法

public static int createTexture(Bitmap bitmap) {
    int[] texture = new int[1];
    if (bitmap != null && !bitmap.isRecycled()) {
        // 生成纹理
        GLES20.glGenTextures(1, texture, 0);
        // 生成纹理
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
        return texture[0];
    }

    return 0;
}

顶点着色器

attribute vec3 aPos;
attribute vec2 v_texCoord;
varying vec2 outTexCoord;
void main() {
    gl_Position =  vec4(aPos, 1.0);
    outTexCoord = v_texCoord;
}

片段着色器

precision mediump float;
varying vec2 outTexCoord;
uniform sampler2D u_samplerTexture;
uniform sampler2D watermark;
void main(){
 gl_FragColor = mix(texture2D(u_samplerTexture, outTexCoord) * vec4(0, 1, 0, 1),           texture2D(watermark, vec2(1.0 - outTexCoord.x, outTexCoord.y)), 0.2);
}