如何制作水印渲染器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何制作水印渲染器?相关的知识,希望对你有一定的参考价值。

我想在android上制作自定义水印渲染器。

我将在当前相机预览屏幕上方的右下角添加水印。

这是我做的源代码。这段代码不起作用。

请帮我。谢谢。

函数调用顺序是:

-setWatermarkTexture

-createBuffers

-configureOpenGL

-画

public class WatermarkRenderer implements Renderer {

    private int[] textureHandles = new int[1];

    float vertices[] = {
            -1, 0.5f,
            -0.5f, -0.5f,
            -1, 1,
            -0.5f, 1,

    };

    float texCoords[] = {
            0, 0,
            1, 0,
            0, 1,
            1, 1,
    };

    private Bitmap      watermark;
    private int[] buffers = new int[2];
    private float[] projectionMatrix = new float[16];


    private FloatBuffer vertexBuffer;
    private FloatBuffer textureBuffer;

    @Override
    public void configureOpenGL() {

        GLES20.glGenTextures(textureHandles.length, textureHandles, 0);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandles[0]);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        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.glGenBuffers(buffers.length, buffers, 0);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 8, vertexBuffer, GLES20.GL_STATIC_DRAW );

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 8, textureBuffer, GLES20.GL_STATIC_DRAW );

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    @Override
    public void createBuffers() {
        vertexBuffer = FloatBuffer.allocate(8);
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        textureBuffer = FloatBuffer.allocate(8);
        textureBuffer.put(texCoords);
        textureBuffer.position(0);
    }

    @Override
    public void draw() {

        GLES20.glEnable(GLES20.GL_DEPTH_TEST);

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

        if (watermark != null) {
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, watermark, 0);
            watermark.recycle();
            watermark = null;
        }
/*
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
        GLES20.glEnableVertexAttribArray(AttributeLocations.POSITION);
        GLES20.glVertexAttribPointer(AttributeLocations.POSITION, 2, GLES20.GL_FLOAT, false, 0, 0);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]);
        GLES20.glEnableVertexAttribArray(AttributeLocations.TEXTURE_COORDINATES );
        GLES20.glVertexAttribPointer(AttributeLocations.TEXTURE_COORDINATES, 2, GLES20.GL_FLOAT, false, 0, 0);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4 );

        GLES20.glDisableVertexAttribArray(AttributeLocations.POSITION);
        GLES20.glDisableVertexAttribArray(AttributeLocations.TEXTURE_COORDINATES);
*/
        GLES20.glDisable(GLES20.GL_BLEND);
        GLES20.glDisable(GLES20.GL_DEPTH_TEST);
    }

    @Override
    public void setProjectionMatrix(float[] projectionMatrix) {
        this.projectionMatrix = projectionMatrix;
    }

    public void setWatermarkTexture(Bitmap bitmap) {
        watermark = bitmap;
    }
}
答案

我解决了我的问题。

这是源代码。

public class WatermarkRenderer implements Renderer {

    private final float[] TEX_VERTICES = {
            0.0f, 1.0f,
            1.0f, 1.0f,
            0.0f, 0.0f,
            1.0f, 0.0f
    };
    private final float[] POS_VERTICES = {
            0.2f, -1.0f,
            1.0f, -1.0f,
            0.2f, -0.9f,
            1.0f, -0.9f
    };

    private static final String VERTEX_SHADER =
                    "attribute vec4 a_position;
" +
                    "attribute vec2 a_texcoord;
" +
                    "varying vec2 v_texcoord;
" +
                    "void main() {
" +
                    "  gl_Position = a_position;
" +
                    "  v_texcoord = a_texcoord;
" +
                    "}
";
    private static final String FRAGMENT_SHADER =
                    "precision mediump float;
" +
                    "uniform sampler2D tex_sampler;
" +
                    "varying vec2 v_texcoord;
" +
                    "void main() {
" +
                    "  gl_FragColor = texture2D(tex_sampler, v_texcoord);
" +
                    "}
";

    private final int FLOAT_SIZE_BYTES = 4;

    private Bitmap  watermark;

    private int shaderProgram;
    private int texSamplerHandle;
    private int texCoordHandle;
    private int posCoordHandle;
    private FloatBuffer texVertices;
    private FloatBuffer posVertices;

    private int[] textureHandles = new int[1];

    @Override
    public void configureOpenGL() {

        shaderProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(shaderProgram, OpenGLUtils.loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER));
        GLES20.glAttachShader(shaderProgram, OpenGLUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER));
        GLES20.glLinkProgram(shaderProgram);

        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(shaderProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(shaderProgram);
            GLES20.glDeleteProgram(shaderProgram);
            shaderProgram = 0;
            throw new RuntimeException("Could not link program: " + info);
        }

        texSamplerHandle = GLES20.glGetUniformLocation(shaderProgram, "tex_sampler");
        texCoordHandle = GLES20.glGetAttribLocation(shaderProgram, "a_texcoord");
        posCoordHandle = GLES20.glGetAttribLocation(shaderProgram, "a_position");
    }

    @Override
    public void createBuffers() {
        ByteBuffer byteBuffer;

        byteBuffer = ByteBuffer.allocateDirect(TEX_VERTICES.length * FLOAT_SIZE_BYTES);
        byteBuffer.order(ByteOrder.nativeOrder());
        texVertices = byteBuffer.asFloatBuffer();
        texVertices.put(TEX_VERTICES);
        texVertices.position(0);

        byteBuffer = ByteBuffer.allocateDirect(POS_VERTICES.length * FLOAT_SIZE_BYTES);
        byteBuffer.order(ByteOrder.nativeOrder());
        posVertices = byteBuffer.asFloatBuffer();
        posVertices.put(POS_VERTICES);
        posVertices.position(0);
    }

    @Override
    public void draw() {

        // Select the program.
        GLES20.glUseProgram(shaderProgram);

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

        // Set the vertex attributes
        GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, texVertices);
        GLES20.glEnableVertexAttribArray(texCoordHandle);
        GLES20.glVertexAttribPointer(posCoordHandle, 2, GLES20.GL_FLOAT, false, 0, posVertices);
        GLES20.glEnableVertexAttribArray(posCoordHandle);

        // Set the input texture
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandles[0]);
        GLES20.glUniform1i(texSamplerHandle, 0);

        GLES20.glGenTextures(textureHandles.length, textureHandles, 0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandles[0]);

        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, watermark, 0);

        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

        GLES20.glDisableVertexAttribArray(texCoordHandle);
        GLES20.glDisableVertexAttribArray(posCoordHandle);

        GLES20.glDisable(GLES20.GL_BLEND);

        GLES20.glUseProgram(0);
    }

    @Override
    public void setProjectionMatrix(float[] projectionMatrix) {
    }

    public void setWatermarkTexture(Bitmap bitmap) {
        watermark = bitmap;
    }
}

以上是关于如何制作水印渲染器?的主要内容,如果未能解决你的问题,请参考以下文章

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

GLSL:无法从 FBO 读取纹理并使用片段着色器渲染到另一个 FBO

为啥片段着色器比渲染纹理更快?

Java itext为pdf 文件添加水印核心功能代码片段

有没有办法在片段着色器中使用先前渲染的结果?

如何制作虚线渲染器并通过强制更改颜色