summaryrefslogtreecommitdiffstats
path: root/samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java
diff options
context:
space:
mode:
Diffstat (limited to 'samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java')
-rw-r--r--samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java164
1 files changed, 164 insertions, 0 deletions
diff --git a/samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java b/samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java
new file mode 100644
index 000000000..9c77927d2
--- /dev/null
+++ b/samples/browseable/MediaEffects/src/com.example.android.mediaeffects/TextureRenderer.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.example.android.mediaeffects;
+
+import android.opengl.GLES20;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+public class TextureRenderer {
+
+ private int mProgram;
+ private int mTexSamplerHandle;
+ private int mTexCoordHandle;
+ private int mPosCoordHandle;
+
+ private FloatBuffer mTexVertices;
+ private FloatBuffer mPosVertices;
+
+ private int mViewWidth;
+ private int mViewHeight;
+
+ private int mTexWidth;
+ private int mTexHeight;
+
+ 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 static final float[] TEX_VERTICES = {
+ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
+ };
+
+ private static final float[] POS_VERTICES = {
+ -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f
+ };
+
+ private static final int FLOAT_SIZE_BYTES = 4;
+
+ public void init() {
+ // Create program
+ mProgram = GLToolbox.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+
+ // Bind attributes and uniforms
+ mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram,
+ "tex_sampler");
+ mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord");
+ mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position");
+
+ // Setup coordinate buffers
+ mTexVertices = ByteBuffer.allocateDirect(
+ TEX_VERTICES.length * FLOAT_SIZE_BYTES)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mTexVertices.put(TEX_VERTICES).position(0);
+ mPosVertices = ByteBuffer.allocateDirect(
+ POS_VERTICES.length * FLOAT_SIZE_BYTES)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mPosVertices.put(POS_VERTICES).position(0);
+ }
+
+ public void tearDown() {
+ GLES20.glDeleteProgram(mProgram);
+ }
+
+ public void updateTextureSize(int texWidth, int texHeight) {
+ mTexWidth = texWidth;
+ mTexHeight = texHeight;
+ computeOutputVertices();
+ }
+
+ public void updateViewSize(int viewWidth, int viewHeight) {
+ mViewWidth = viewWidth;
+ mViewHeight = viewHeight;
+ computeOutputVertices();
+ }
+
+ public void renderTexture(int texId) {
+ // Bind default FBO
+ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
+
+ // Use our shader program
+ GLES20.glUseProgram(mProgram);
+ GLToolbox.checkGlError("glUseProgram");
+
+ // Set viewport
+ GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
+ GLToolbox.checkGlError("glViewport");
+
+ // Disable blending
+ GLES20.glDisable(GLES20.GL_BLEND);
+
+ // Set the vertex attributes
+ GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false,
+ 0, mTexVertices);
+ GLES20.glEnableVertexAttribArray(mTexCoordHandle);
+ GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false,
+ 0, mPosVertices);
+ GLES20.glEnableVertexAttribArray(mPosCoordHandle);
+ GLToolbox.checkGlError("vertex attribute setup");
+
+ // Set the input texture
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLToolbox.checkGlError("glActiveTexture");
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
+ GLToolbox.checkGlError("glBindTexture");
+ GLES20.glUniform1i(mTexSamplerHandle, 0);
+
+ // Draw
+ GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+ }
+
+ private void computeOutputVertices() {
+ if (mPosVertices != null) {
+ float imgAspectRatio = mTexWidth / (float)mTexHeight;
+ float viewAspectRatio = mViewWidth / (float)mViewHeight;
+ float relativeAspectRatio = viewAspectRatio / imgAspectRatio;
+ float x0, y0, x1, y1;
+ if (relativeAspectRatio > 1.0f) {
+ x0 = -1.0f / relativeAspectRatio;
+ y0 = -1.0f;
+ x1 = 1.0f / relativeAspectRatio;
+ y1 = 1.0f;
+ } else {
+ x0 = -1.0f;
+ y0 = -relativeAspectRatio;
+ x1 = 1.0f;
+ y1 = relativeAspectRatio;
+ }
+ float[] coords = new float[] { x0, y0, x1, y0, x0, y1, x1, y1 };
+ mPosVertices.put(coords).position(0);
+ }
+ }
+
+}