2017-12-16 3 views
-1

Ich möchte einen benutzerdefinierten Watermark Renderer auf Android machen.Wie kann man Wasserzeichen-Renderer machen?

Ich werde Wasserzeichen in der unteren rechten Ecke über dem aktuellen Kamera-Vorschau-Bildschirm hinzufügen.

Hier ist der Quellcode, was ich gemacht habe. Dieser Code funktioniert nicht.

Bitte helfen Sie mir. Vielen Dank.

Funktion Aufrufsequenz ist:

-setWatermarkTexture

-createBuffers

-configureOpenGL

-draw

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; 
    } 
} 
+2

"es funktioniert nicht" ist keine Frage. Was erwartest du zu passieren? Was passiert eigentlich? Was ist der Unterschied? Stürzt es ab oder zeigt es eine falsche Ausgabe? Wenn das abstürzt, was ist das Protokoll? Yu muss die Dinge gründlicher erklären –

+0

Ich sah gerade, dass meine benutzerdefinierte Renderer-Klasse struct, und wenn ich über die Klasse verwenden, passiert nichts. also möchte ich einfach texture renderer machen, der png watermark über video preview zeigen kann. FYI-Kamera-Renderer funktioniert bereits. aber zeigt kein Wasserzeichen. –

+0

und ich habe meinen Quellcode aktualisiert, im Grunde möchte ich wissen, was in meiner Klasse fehlt? –

Antwort

0

ich mein Problem gelöst.

Hier ist der Quellcode.

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;\n" + 
        "attribute vec2 a_texcoord;\n" + 
        "varying vec2 v_texcoord;\n" + 
        "void main() {\n" + 
        " gl_Position = a_position;\n" + 
        " v_texcoord = a_texcoord;\n" + 
        "}\n"; 
    private static final String FRAGMENT_SHADER = 
        "precision mediump float;\n" + 
        "uniform sampler2D tex_sampler;\n" + 
        "varying vec2 v_texcoord;\n" + 
        "void main() {\n" + 
        " gl_FragColor = texture2D(tex_sampler, v_texcoord);\n" + 
        "}\n"; 

    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; 
    } 
} 
Verwandte Themen