am 018c9eeb: Merge "adding media effects sample to sdk" into ics-mr1

* commit '018c9eeb8e05e4dd6965655d9f120b595efcd758':
  adding media effects sample to sdk
This commit is contained in:
Robert Ly
2012-04-23 10:41:00 -07:00
committed by Android Git Automerger
15 changed files with 797 additions and 0 deletions

View File

@@ -167,6 +167,7 @@ development/samples/BluetoothHDP samples/${PLATFORM_NAME}/Bluetoot
development/samples/ContactManager samples/${PLATFORM_NAME}/ContactManager development/samples/ContactManager samples/${PLATFORM_NAME}/ContactManager
development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility
development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper
development/samples/HelloEffects samples/${PLATFORM_NAME}/HelloEffects
development/samples/Home samples/${PLATFORM_NAME}/Home development/samples/Home samples/${PLATFORM_NAME}/Home
development/samples/HoneycombGallery samples/${PLATFORM_NAME}/HoneycombGallery development/samples/HoneycombGallery samples/${PLATFORM_NAME}/HoneycombGallery
development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy

View File

@@ -0,0 +1,12 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := samples
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := HelloEffects
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" package="com.example.android.mediafx">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="15"/>
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:debuggable="true"
android:hardwareAccelerated="true">
<activity android:name="com.example.android.mediafx.HelloEffects"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,23 @@
<!--
Copyright 2011 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.
-->
<p>This sample shows how to use the <a href="http://developer.android.com/reference/android/media/effect/package-summary.html">Media
Effects APIs</a> that were introduced in Android 4.0. These APIs let you apply
effects to image frames represented as OpenGL ES 2.0 textures. Image frames can
be images loaded from disk, frames from the device's camera, or other video
streams.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.opengl.GLSurfaceView
android:id="@+id/effectsview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.93" />
</LinearLayout>

View File

@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/none"
android:title="@string/none"
android:showAsAction="never" />
<item android:id="@+id/autofix"
android:title="@string/autofix"
android:showAsAction="never" />
<item android:id="@+id/bw"
android:title="@string/bw"
android:showAsAction="never" />
<item android:id="@+id/brightness"
android:title="@string/brightness"
android:showAsAction="never" />
<item android:id="@+id/contrast"
android:title="@string/contrast"
android:showAsAction="never" />
<item android:id="@+id/crossprocess"
android:title="@string/crossprocess"
android:showAsAction="never" />
<item android:id="@+id/documentary"
android:title="@string/documentary"
android:showAsAction="never" />
<item android:id="@+id/duotone"
android:title="@string/duotone"
android:showAsAction="never" />
<item android:id="@+id/filllight"
android:title="@string/filllight"
android:showAsAction="never" />
<item android:id="@+id/fisheye"
android:title="@string/fisheye"
android:showAsAction="never" />
<item android:id="@+id/flipvert"
android:title="@string/flipvert"
android:showAsAction="never" />
<item android:id="@+id/fliphor"
android:title="@string/fliphor"
android:showAsAction="never" />
<item android:id="@+id/grain"
android:title="@string/grain"
android:showAsAction="never" />
<item android:id="@+id/grayscale"
android:title="@string/grayscale"
android:showAsAction="never" />
<item android:id="@+id/lomoish"
android:title="@string/lomoish"
android:showAsAction="never" />
<item android:id="@+id/negative"
android:title="@string/negative"
android:showAsAction="never" />
<item android:id="@+id/posterize"
android:title="@string/posterize"
android:showAsAction="never" />
<item android:id="@+id/rotate"
android:title="@string/rotate"
android:showAsAction="never" />
<item android:id="@+id/saturate"
android:title="@string/saturate"
android:showAsAction="never" />
<item android:id="@+id/sepia"
android:title="@string/sepia"
android:showAsAction="never" />
<item android:id="@+id/sharpen"
android:title="@string/sharpen"
android:showAsAction="never" />
<item android:id="@+id/temperature"
android:title="@string/temperature"
android:showAsAction="never" />
<item android:id="@+id/tint"
android:title="@string/tint"
android:showAsAction="never" />
<item android:id="@+id/vignette"
android:title="@string/vignette"
android:showAsAction="never" />
</menu>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<resources>
<string name="app_name">HelloEffects</string>
<string name="none">None</string>
<string name="autofix">Autofix</string>
<string name="bw">Min/Max Color Intensity</string>
<string name="brightness">Brightness</string>
<string name="contrast">Contrast</string>
<string name="crossprocess">Cross Process</string>
<string name="documentary">Documentary</string>
<string name="duotone">Duo Tone</string>
<string name="filllight">Fill Light</string>
<string name="fisheye">Fish Eye</string>
<string name="flipvert">Flip Vertical</string>
<string name="fliphor">Flip Horizontal</string>
<string name="grain">Grain</string>
<string name="grayscale">Grayscale</string>
<string name="lomoish">Lomoish</string>
<string name="negative">Negative</string>
<string name="posterize">Posterize</string>
<string name="rotate">Rotate</string>
<string name="saturate">Saturate</string>
<string name="sepia">Sepia</string>
<string name="sharpen">Sharpen</string>
<string name="temperature">Temperature</string>
<string name="tint">Tint</string>
<string name="vignette">Vignette</string>
</resources>

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2012 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.mediafx;
import android.opengl.GLES20;
public class GLToolbox {
public static int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
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) {
String info = GLES20.glGetShaderInfoLog(shader);
GLES20.glDeleteShader(shader);
shader = 0;
throw new RuntimeException("Could not compile shader " +
shaderType + ":" + info);
}
}
return shader;
}
public static 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();
if (program != 0) {
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) {
String info = GLES20.glGetProgramInfoLog(program);
GLES20.glDeleteProgram(program);
program = 0;
throw new RuntimeException("Could not link program: " + info);
}
}
return program;
}
public static void checkGlError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
throw new RuntimeException(op + ": glError " + error);
}
}
public static void initTexParams() {
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);
}
}

View File

@@ -0,0 +1,296 @@
/*
* Copyright (C) 2012 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.mediafx;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.media.effect.Effect;
import android.media.effect.EffectContext;
import android.media.effect.EffectFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class HelloEffects extends Activity implements GLSurfaceView.Renderer {
private GLSurfaceView mEffectView;
private int[] mTextures = new int[2];
private EffectContext mEffectContext;
private Effect mEffect;
private TextureRenderer mTexRenderer = new TextureRenderer();
private int mImageWidth;
private int mImageHeight;
private boolean mInitialized = false;
int mCurrentEffect;
public void setCurrentEffect(int effect) {
mCurrentEffect = effect;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**
* Initialize the renderer and tell it to only render when
* explicity requested with the RENDERMODE_WHEN_DIRTY option
*/
mEffectView = (GLSurfaceView) findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = R.id.none;
}
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.puppy);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
}
private void initEffect() {
EffectFactory effectFactory = mEffectContext.getFactory();
if (mEffect != null) {
mEffect.release();
}
/**
* Initialize the correct effect based on the selected menu/action item
*/
switch (mCurrentEffect) {
case R.id.none:
break;
case R.id.autofix:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_AUTOFIX);
mEffect.setParameter("scale", 0.5f);
break;
case R.id.bw:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_BLACKWHITE);
mEffect.setParameter("black", .1f);
mEffect.setParameter("white", .7f);
break;
case R.id.brightness:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_BRIGHTNESS);
mEffect.setParameter("brightness", 2.0f);
break;
case R.id.contrast:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_CONTRAST);
mEffect.setParameter("contrast", 1.4f);
break;
case R.id.crossprocess:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_CROSSPROCESS);
break;
case R.id.documentary:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DOCUMENTARY);
break;
case R.id.duotone:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DUOTONE);
mEffect.setParameter("first_color", Color.YELLOW);
mEffect.setParameter("second_color", Color.DKGRAY);
break;
case R.id.filllight:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FILLLIGHT);
mEffect.setParameter("strength", .8f);
break;
case R.id.fisheye:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FISHEYE);
mEffect.setParameter("scale", .5f);
break;
case R.id.flipvert:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FLIP);
mEffect.setParameter("vertical", true);
break;
case R.id.fliphor:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FLIP);
mEffect.setParameter("horizontal", true);
break;
case R.id.grain:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_GRAIN);
mEffect.setParameter("strength", 1.0f);
break;
case R.id.grayscale:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_GRAYSCALE);
break;
case R.id.lomoish:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_LOMOISH);
break;
case R.id.negative:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_NEGATIVE);
break;
case R.id.posterize:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_POSTERIZE);
break;
case R.id.rotate:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_ROTATE);
mEffect.setParameter("angle", 180);
break;
case R.id.saturate:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_SATURATE);
mEffect.setParameter("scale", .5f);
break;
case R.id.sepia:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_SEPIA);
break;
case R.id.sharpen:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_SHARPEN);
break;
case R.id.temperature:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_TEMPERATURE);
mEffect.setParameter("scale", .9f);
break;
case R.id.tint:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_TINT);
mEffect.setParameter("tint", Color.MAGENTA);
break;
case R.id.vignette:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_VIGNETTE);
mEffect.setParameter("scale", .5f);
break;
default:
break;
}
}
private void applyEffect() {
mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
}
private void renderResult() {
if (mCurrentEffect != R.id.none) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
}
else {
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
@Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
//Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != R.id.none) {
//if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
setCurrentEffect(item.getItemId());
mEffectView.requestRender();
return true;
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2012 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.mediafx;
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);
}
}
}