Android Open Source - AndroidVideoSamples Texture Renderer






From Project

Back to project page AndroidVideoSamples.

License

The source code is released under:

Apache License

If you think the Android project AndroidVideoSamples listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 The Android Open Source Project
 */*from ww w . j  a va  2s. c  o  m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.roryhool.commonvideolibrary;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.util.Log;

/**
 * Code for rendering a texture onto a surface using OpenGL ES 2.0.
 */
class TextureRender {
   private static final String TAG = "TextureRender";
   private static final int FLOAT_SIZE_BYTES = 4;
   private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
   private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
   private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
   private final float[] mTriangleVerticesData = {
         // X, Y, Z, U, V
         -1.0f, -1.0f, 0, 0.f, 0.f, 1.0f, -1.0f, 0, 1.f, 0.f, -1.0f, 1.0f, 0, 0.f, 1.f, 1.0f, 1.0f, 0, 1.f, 1.f, };
   private FloatBuffer mTriangleVertices;
   private static final String VERTEX_SHADER = "uniform mat4 uMVPMatrix;\n" + "uniform mat4 uSTMatrix;\n" + "attribute vec4 aPosition;\n" + "attribute vec4 aTextureCoord;\n" + "varying vec2 vTextureCoord;\n" + "void main() {\n" + "  gl_Position = uMVPMatrix * aPosition;\n" + "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + "}\n";
   private static final String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + // highp here doesn't seem to matter
         "varying vec2 vTextureCoord;\n" + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + "}\n";
   private float[] mMVPMatrix = new float[16];
   private float[] mSTMatrix = new float[16];
   private int mProgram;
   private int mTextureID = -12345;
   private int muMVPMatrixHandle;
   private int muSTMatrixHandle;
   private int maPositionHandle;
   private int maTextureHandle;

   public TextureRender() {
      mTriangleVertices = ByteBuffer.allocateDirect( mTriangleVerticesData.length * FLOAT_SIZE_BYTES ).order( ByteOrder.nativeOrder() ).asFloatBuffer();
      mTriangleVertices.put( mTriangleVerticesData ).position( 0 );
      Matrix.setIdentityM( mSTMatrix, 0 );
   }

   public int getTextureId() {
      return mTextureID;
   }

   public void drawFrame( SurfaceTexture st ) {
      checkGlError( "onDrawFrame start" );
      st.getTransformMatrix( mSTMatrix );
      GLES20.glClearColor( 0.0f, 1.0f, 0.0f, 1.0f );
      GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT );
      GLES20.glUseProgram( mProgram );
      checkGlError( "glUseProgram" );
      GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );
      GLES20.glBindTexture( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID );
      mTriangleVertices.position( TRIANGLE_VERTICES_DATA_POS_OFFSET );
      GLES20.glVertexAttribPointer( maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices );
      checkGlError( "glVertexAttribPointer maPosition" );
      GLES20.glEnableVertexAttribArray( maPositionHandle );
      checkGlError( "glEnableVertexAttribArray maPositionHandle" );
      mTriangleVertices.position( TRIANGLE_VERTICES_DATA_UV_OFFSET );
      GLES20.glVertexAttribPointer( maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices );
      checkGlError( "glVertexAttribPointer maTextureHandle" );
      GLES20.glEnableVertexAttribArray( maTextureHandle );
      checkGlError( "glEnableVertexAttribArray maTextureHandle" );
      Matrix.setIdentityM( mMVPMatrix, 0 );
      GLES20.glUniformMatrix4fv( muMVPMatrixHandle, 1, false, mMVPMatrix, 0 );
      GLES20.glUniformMatrix4fv( muSTMatrixHandle, 1, false, mSTMatrix, 0 );
      GLES20.glDrawArrays( GLES20.GL_TRIANGLE_STRIP, 0, 4 );
      checkGlError( "glDrawArrays" );
      GLES20.glFinish();
   }

   /**
    * Initializes GL state. Call this after the EGL surface has been created and made current.
    */
   public void surfaceCreated() {
      mProgram = createProgram( VERTEX_SHADER, FRAGMENT_SHADER );
      if ( mProgram == 0 ) {
         throw new RuntimeException( "failed creating program" );
      }
      maPositionHandle = GLES20.glGetAttribLocation( mProgram, "aPosition" );
      checkGlError( "glGetAttribLocation aPosition" );
      if ( maPositionHandle == -1 ) {
         throw new RuntimeException( "Could not get attrib location for aPosition" );
      }
      maTextureHandle = GLES20.glGetAttribLocation( mProgram, "aTextureCoord" );
      checkGlError( "glGetAttribLocation aTextureCoord" );
      if ( maTextureHandle == -1 ) {
         throw new RuntimeException( "Could not get attrib location for aTextureCoord" );
      }
      muMVPMatrixHandle = GLES20.glGetUniformLocation( mProgram, "uMVPMatrix" );
      checkGlError( "glGetUniformLocation uMVPMatrix" );
      if ( muMVPMatrixHandle == -1 ) {
         throw new RuntimeException( "Could not get attrib location for uMVPMatrix" );
      }
      muSTMatrixHandle = GLES20.glGetUniformLocation( mProgram, "uSTMatrix" );
      checkGlError( "glGetUniformLocation uSTMatrix" );
      if ( muSTMatrixHandle == -1 ) {
         throw new RuntimeException( "Could not get attrib location for uSTMatrix" );
      }
      int[] textures = new int[1];
      GLES20.glGenTextures( 1, textures, 0 );
      mTextureID = textures[0];
      GLES20.glBindTexture( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID );
      checkGlError( "glBindTexture mTextureID" );
      GLES20.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
      GLES20.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
      GLES20.glTexParameteri( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
      GLES20.glTexParameteri( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );
      checkGlError( "glTexParameter" );
   }

   /**
    * Replaces the fragment shader.
    */
   public void changeFragmentShader( String fragmentShader ) {
      GLES20.glDeleteProgram( mProgram );
      mProgram = createProgram( VERTEX_SHADER, fragmentShader );
      if ( mProgram == 0 ) {
         throw new RuntimeException( "failed creating program" );
      }
   }

   private int loadShader( int shaderType, String source ) {
      int shader = GLES20.glCreateShader( shaderType );
      checkGlError( "glCreateShader type=" + shaderType );
      GLES20.glShaderSource( shader, source );
      GLES20.glCompileShader( shader );
      int[] compiled = new int[1];
      GLES20.glGetShaderiv( shader, GLES20.GL_COMPILE_STATUS, compiled, 0 );
      if ( compiled[0] == 0 ) {
         Log.e( TAG, "Could not compile shader " + shaderType + ":" );
         Log.e( TAG, " " + GLES20.glGetShaderInfoLog( shader ) );
         GLES20.glDeleteShader( shader );
         shader = 0;
      }
      return shader;
   }

   private int createProgram( String vertexSource, String fragmentSource ) {
      int vertexShader = loadShader( GLES20.GL_VERTEX_SHADER, vertexSource );
      if ( vertexShader == 0 ) {
         return 0;
      }
      int pixelShader = loadShader( GLES20.GL_FRAGMENT_SHADER, fragmentSource );
      if ( pixelShader == 0 ) {
         return 0;
      }
      int program = GLES20.glCreateProgram();
      checkGlError( "glCreateProgram" );
      if ( program == 0 ) {
         Log.e( TAG, "Could not create program" );
      }
      GLES20.glAttachShader( program, vertexShader );
      checkGlError( "glAttachShader" );
      GLES20.glAttachShader( program, pixelShader );
      checkGlError( "glAttachShader" );
      GLES20.glLinkProgram( program );
      int[] linkStatus = new int[1];
      GLES20.glGetProgramiv( program, GLES20.GL_LINK_STATUS, linkStatus, 0 );
      if ( linkStatus[0] != GLES20.GL_TRUE ) {
         Log.e( TAG, "Could not link program: " );
         Log.e( TAG, GLES20.glGetProgramInfoLog( program ) );
         GLES20.glDeleteProgram( program );
         program = 0;
      }
      return program;
   }

   public void checkGlError( String op ) {
      int error;
      while ( ( error = GLES20.glGetError() ) != GLES20.GL_NO_ERROR ) {
         Log.e( TAG, op + ": glError " + error );
         throw new RuntimeException( op + ": glError " + error );
      }
   }
}




Java Source Code List

com.roryhool.commonvideolibrary.CursorHelper.java
com.roryhool.commonvideolibrary.InputSurface.java
com.roryhool.commonvideolibrary.Intents.java
com.roryhool.commonvideolibrary.MediaHelper.java
com.roryhool.commonvideolibrary.OutputSurface.java
com.roryhool.commonvideolibrary.Resolution.java
com.roryhool.commonvideolibrary.SamplerClip.java
com.roryhool.commonvideolibrary.TextureRenderer.java
com.roryhool.commonvideolibrary.UriHelper.java
com.roryhool.commonvideolibrary.VideoResampler.java
com.roryhool.videocreation.JoinActivity.java
com.roryhool.videocreation.MainActivity.java
com.roryhool.videocreation.RenderFromSurfaceActivity.java
com.roryhool.videocreation.SurfaceEncoder.java
com.roryhool.videomanipulation.MainActivity.java
com.roryhool.videomanipulation.ResampleActivity.java
com.roryhool.videomanipulation.RotationActivity.java
com.roryhool.videomanipulation.TrimActivity.java
com.roryhool.videoplayback.ControllerBase.java
com.roryhool.videoplayback.DecodeWithMediaCodecActivity.java
com.roryhool.videoplayback.MainActivity.java
com.roryhool.videoplayback.MediaCodecDecodeController.java
com.roryhool.videoplayback.MediaPlayerController.java
com.roryhool.videoplayback.PlayWithMediaPlayerActivity.java
com.roryhool.videoplayback.PlaybackTimer.java
com.roryhool.videoplayback.ResizeAnimation.java
com.roryhool.videoplayback.ScaledTextureView.java
com.roryhool.videoplayback.VideoPlayerView.java