aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/fonts/Roboto-Bold.ttfbin0 -> 163448 bytes
-rw-r--r--res/drawable-nodpi/bg_cid_oops.pngbin0 -> 13522 bytes
-rw-r--r--res/raw/mix_fragment_shader.glsl27
-rw-r--r--res/raw/mix_vertex_shader.glsl27
-rw-r--r--res/values/strings.xml3
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/GLESUtil.java2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java70
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/TextureManager.java39
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java270
10 files changed, 409 insertions, 31 deletions
diff --git a/assets/fonts/Roboto-Bold.ttf b/assets/fonts/Roboto-Bold.ttf
new file mode 100644
index 0000000..91ec212
--- /dev/null
+++ b/assets/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/res/drawable-nodpi/bg_cid_oops.png b/res/drawable-nodpi/bg_cid_oops.png
new file mode 100644
index 0000000..b5373da
--- /dev/null
+++ b/res/drawable-nodpi/bg_cid_oops.png
Binary files differ
diff --git a/res/raw/mix_fragment_shader.glsl b/res/raw/mix_fragment_shader.glsl
new file mode 100644
index 0000000..df80f89
--- /dev/null
+++ b/res/raw/mix_fragment_shader.glsl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.
+ */
+
+precision mediump float;
+
+varying vec2 vTextureCoord;
+uniform sampler2D sTexture1;
+uniform sampler2D sTexture2;
+
+void main() {
+ vec4 color1 = texture2D(sTexture1, vTextureCoord);
+ vec4 color2 = texture2D(sTexture1, vTextureCoord);
+ gl_FragColor = color2 * color1;
+}
diff --git a/res/raw/mix_vertex_shader.glsl b/res/raw/mix_vertex_shader.glsl
new file mode 100644
index 0000000..dad4d5a
--- /dev/null
+++ b/res/raw/mix_vertex_shader.glsl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.
+ */
+
+uniform mat4 uMVPMatrix;
+
+attribute vec4 aPosition;
+attribute vec2 aTextureCoord;
+
+varying vec2 vTextureCoord;
+
+void main() {
+ gl_Position = uMVPMatrix * aPosition;
+ vTextureCoord = aTextureCoord;
+}
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7b7a071..e9708d3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -23,6 +23,9 @@
<!-- The app description -->
<string name="app_description">PhotoPhase Live Wallpaper</string>
+ <!-- No images message -->
+ <string name="no_pictures_oops_msg">Oops, no pictures.</string>
+
<!-- Menus -->
<string name="mnu_ok" translatable="false">@android:string/ok</string>
<string name="mnu_restore">Restore</string>
diff --git a/src/org/cyanogenmod/wallpapers/photophase/GLESUtil.java b/src/org/cyanogenmod/wallpapers/photophase/GLESUtil.java
index 3183ff4..17b6602 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/GLESUtil.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/GLESUtil.java
@@ -95,7 +95,7 @@ public final class GLESUtil {
/**
* Constructor of <code>GLColor</code> from ARGB.
*
- * @param argb An #AARRGGBB string
+ * @param argb An #AARRGGBB number
*/
public GLColor(int argb) {
this.a = Color.alpha(argb) / MAX_COLOR;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java b/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
index 11f9743..0c9ec0f 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
@@ -214,7 +214,7 @@ public class MediaPictureDiscoverer {
}
// Publish partial data
- if (i % 5 == 0 && partial.size() > 0){
+ if (i % 5 == 0 && partial.size() > 0) {
publishProgress(partial.toArray(new File[partial.size()]));
partial.clear();
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
index a4b1364..ffc4d22 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
@@ -41,6 +41,7 @@ import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider;
import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences;
import org.cyanogenmod.wallpapers.photophase.preferences.TouchAction;
import org.cyanogenmod.wallpapers.photophase.shapes.ColorShape;
+import org.cyanogenmod.wallpapers.photophase.shapes.OopsShape;
import org.cyanogenmod.wallpapers.photophase.transitions.Transition;
import javax.microedition.khronos.egl.EGLConfig;
@@ -66,6 +67,7 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
/*package*/ PhotoPhaseWallpaperWorld mWorld;
/*package*/ ColorShape mOverlay;
+ /*package*/ OopsShape mOopsShape;
/*package*/ long mLastRunningTransition;
@@ -381,9 +383,11 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
if (mWorld != null) mWorld.recycle();
if (mTextureManager != null) mTextureManager.recycle();
if (mOverlay != null) mOverlay.recycle();
+ if (mOopsShape != null) mOopsShape.recycle();
mWorld = null;
mTextureManager = null;
mOverlay = null;
+ mOopsShape = null;
}
}
@@ -469,7 +473,7 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
}
mWorld = new PhotoPhaseWallpaperWorld(mContext, mTextureManager);
- // Create all the other shapes
+ // Create the overlay shape
final float[] vertex = {
-1.0f, -1.0f,
1.0f, -1.0f,
@@ -478,7 +482,10 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
};
mOverlay = new ColorShape(mContext, vertex, Colors.getOverlay());
- // Set the viewport and the fustrum to use
+ // Create the Oops shape
+ mOopsShape = new OopsShape(mContext, R.string.no_pictures_oops_msg);
+
+ // Set the viewport and the fustrum
GLES20.glViewport(0, -statusBarHeight, width, height);
GLESUtil.glesCheckError("glViewport");
Matrix.frustumM(mProjMatrix, 0, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f);
@@ -497,32 +504,42 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
@Override
public void onDrawFrame(GL10 glUnused) {
synchronized (mDrawing) {
- // Draw the background
- drawBackground();
+ // Set the projection, view and model
+ Matrix.setLookAtM(mVMatrix, 0, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
+ Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+
+ if (mTextureManager != null) {
+ if (mTextureManager.getStatus() == 1 && mTextureManager.isEmpty()) {
+ // Advise the user and stop
+ drawOops();
+ mDispatcher.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- if (mWorld != null) {
- // Set the projection, view and model
- Matrix.setLookAtM(mVMatrix, 0, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
- Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+ } else {
+ // Draw the background
+ drawBackground();
- // Now draw the world (all the photo frames with effects)
- mWorld.draw(mMVPMatrix);
+ if (mWorld != null) {
+ // Now draw the world (all the photo frames with effects)
+ mWorld.draw(mMVPMatrix);
- // Check if we have some pending transition or transition has exceed its timeout
- if (!mWorld.hasRunningTransition() || isTransitionTimeout()) {
- mDispatcher.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+ // Check if we have some pending transition or transition has exceed its timeout
+ if (!mWorld.hasRunningTransition() || firedTransitionTimeout()) {
+ mDispatcher.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+
+ // Now start a delayed thread to generate the next effect
+ mHandler.removeCallbacks(mTransitionThread);
+ mWorld.deselectTransition(mMVPMatrix);
+ mLastRunningTransition = 0;
+ mHandler.postDelayed(mTransitionThread,
+ Preferences.General.Transitions.getTransitionInterval());
+ }
+ }
- // Now start a delayed thread to generate the next effect
- mHandler.removeCallbacks(mTransitionThread);
- mWorld.deselectTransition(mMVPMatrix);
- mLastRunningTransition = 0;
- mHandler.postDelayed(mTransitionThread,
- Preferences.General.Transitions.getTransitionInterval());
+ // Draw the overlay
+ drawOverlay();
}
}
- // Draw the overlay
- drawOverlay();
}
}
@@ -531,7 +548,7 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
*
* @return boolean if the transition has exceed the timeout
*/
- private boolean isTransitionTimeout() {
+ private boolean firedTransitionTimeout() {
long now = System.currentTimeMillis();
long diff = now - mLastRunningTransition;
return mLastRunningTransition != 0 && diff > Transition.MAX_TRANSTION_TIME;
@@ -558,4 +575,13 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
}
}
+ /**
+ * Method that draws the oops message
+ */
+ private void drawOops() {
+ if (mOopsShape != null) {
+ mOopsShape.draw(mMVPMatrix);
+ }
+ }
+
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
index 6e5b577..a4ce157 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
@@ -57,6 +57,12 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
final GLESSurfaceDispatcher mDispatcher;
+ // The status of the texture manager:
+ // 0 - Loading
+ // 1 - Loaded
+ // 2 - Error
+ private byte mStatus;
+
/**
* A private runnable that will run in the GLThread
*/
@@ -286,6 +292,7 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
@Override
public void onStartMediaDiscovered(boolean userRequest) {
// No images but thread should start here to received partial data
+ this.mStatus = 0; // Loading
if (mBackgroundTask != null) {
mBackgroundTask.setAvailableImages(new File[]{});
if (!mBackgroundTask.mRun) {
@@ -318,13 +325,10 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
// load pictures in background
if (mBackgroundTask != null) {
mBackgroundTask.setAvailableImages(images);
- if (!mBackgroundTask.mRun) {
- mBackgroundTask.start();
- } else {
- synchronized (mBackgroundTask.mLoadSync) {
- mBackgroundTask.mLoadSync.notify();
- }
+ synchronized (mBackgroundTask.mLoadSync) {
+ mBackgroundTask.mLoadSync.notify();
}
+ this.mStatus = 1; // Loaded
// Audit
int found = images == null ? 0 : images.length;
@@ -335,6 +339,8 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
R.plurals.msg_media_reload_complete, found).toString(), found);
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
+ } else {
+ this.mStatus = 2; // Error
}
}
@@ -359,6 +365,25 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
mBackgroundTask = null;
}
+
+ /**
+ * Returns the status of the texture manager
+ *
+ * @return byte The status
+ */
+ public byte getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Returns if the texture manager is empty
+ *
+ * @return boolean If the texture manager is empty
+ */
+ public boolean isEmpty() {
+ return mBackgroundTask != null && mBackgroundTask.mEmpty;
+ }
+
/**
* An internal thread to load pictures in background
*/
@@ -368,7 +393,7 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
boolean mRun;
boolean mTaskPaused;
- private boolean mEmpty;
+ /*package*/ boolean mEmpty;
private final List<File> mNewImages;
private final List<File> mUsedImages;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java b/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java
new file mode 100644
index 0000000..6d8ea1c
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/shapes/OopsShape.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.shapes;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.opengl.GLES20;
+
+import org.cyanogenmod.wallpapers.photophase.Colors;
+import org.cyanogenmod.wallpapers.photophase.GLESUtil;
+import org.cyanogenmod.wallpapers.photophase.GLESUtil.GLColor;
+import org.cyanogenmod.wallpapers.photophase.GLESUtil.GLESTextureInfo;
+import org.cyanogenmod.wallpapers.photophase.R;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+/**
+ * A shape to draw an oops message
+ */
+public class OopsShape implements DrawableShape {
+
+ private static final int VERTEX_SHADER = R.raw.default_vertex_shader;
+ private static final int FRAGMENT_SHADER = R.raw.default_fragment_shader;
+
+ // The texture coordinates
+ private static final float[] TEXTURE_COORDS = {
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f
+ };
+
+ // The vertex position coordinates
+ private static final float[] VERTEX_COORDS = {
+ -0.5f, -0.5f,
+ 0.5f, -0.5f,
+ -0.5f, 0.5f,
+ 0.5f, 0.5f
+ };
+
+ private FloatBuffer mPositionBuffer;
+ private FloatBuffer mTextureBuffer;
+
+ private int[] mProgramHandlers;
+ private int[] mTextureHandlers;
+ private int[] mPositionHandlers;
+ private int[] mTextureCoordHandlers;
+ private int[] mMVPMatrixHandlers;
+
+ private String mMessage;
+
+ private GLESTextureInfo mOopsImageTexture;
+ private GLESTextureInfo mOopsTextTexture;
+
+ /**
+ * Constructor of <code>OopsShape</code>
+ *
+ * @param ctx The current context
+ * @param resourceMessageId The resource identifier with the message
+ */
+ public OopsShape(Context ctx, int resourceMessageId) {
+ super();
+
+ // Load the buffers
+ ByteBuffer bb1 = ByteBuffer.allocateDirect(VERTEX_COORDS.length * 4); // (# of coordinate values * 4 bytes per float)
+ bb1.order(ByteOrder.nativeOrder());
+ mPositionBuffer = bb1.asFloatBuffer();
+ mPositionBuffer.put(VERTEX_COORDS);
+ mPositionBuffer.position(0);
+ // -
+ ByteBuffer bb2 = ByteBuffer.allocateDirect(TEXTURE_COORDS.length * 4); // (# of coordinate values * 4 bytes per float)
+ bb2.order(ByteOrder.nativeOrder());
+ mTextureBuffer = bb2.asFloatBuffer();
+ mTextureBuffer.put(TEXTURE_COORDS);
+ mTextureBuffer.position(0);
+
+ // Initialize the structures
+ mProgramHandlers = new int[2];
+ mTextureHandlers = new int[2];
+ mPositionHandlers = new int[2];
+ mTextureCoordHandlers = new int[2];
+ mMVPMatrixHandlers = new int[2];
+
+ // Create all the params
+ for (int i=0; i < 2; i++) {
+ mProgramHandlers[i] =
+ GLESUtil.createProgram(
+ ctx.getResources(), VERTEX_SHADER, FRAGMENT_SHADER);
+ mTextureHandlers[i] =
+ GLES20.glGetAttribLocation(mProgramHandlers[i], "sTexture");
+ mPositionHandlers[i] =
+ GLES20.glGetAttribLocation(mProgramHandlers[i], "aPosition");
+ GLESUtil.glesCheckError("glGetAttribLocation");
+ mTextureCoordHandlers[i] =
+ GLES20.glGetAttribLocation(mProgramHandlers[i], "aTextureCoord");
+ GLESUtil.glesCheckError("glGetAttribLocation");
+ mMVPMatrixHandlers[i] =
+ GLES20.glGetUniformLocation(mProgramHandlers[i], "uMVPMatrix");
+ GLESUtil.glesCheckError("glGetUniformLocation");
+ }
+
+ // Get the localized message
+ mMessage = ctx.getString(resourceMessageId);
+
+ // Load the textures
+ mOopsImageTexture = GLESUtil.loadTexture(ctx, R.drawable.bg_cid_oops, null, null, false);
+ mOopsTextTexture = GLESUtil.loadTexture(text2Bitmap(ctx, mMessage), null, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void draw(float[] matrix) {
+ // Bind default FBO
+ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
+ GLESUtil.glesCheckError("glBindFramebuffer");
+
+ // Clear background
+ GLColor bg = Colors.getBackground();
+ GLES20.glClearColor(bg.r, bg.g, bg.b, bg.a);
+ GLESUtil.glesCheckError("glClearColor");
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
+ GLESUtil.glesCheckError("glClear");
+
+ // Enable blend
+ GLES20.glEnable(GLES20.GL_BLEND);
+ GLESUtil.glesCheckError("glEnable");
+ GLES20.glBlendFunc(GLES20.GL_SRC_COLOR, GLES20.GL_ONE_MINUS_SRC_COLOR);
+ GLESUtil.glesCheckError("glBlendFunc");
+
+ // Draw the textures
+ drawTexture(matrix, 0, mOopsImageTexture.handle);
+ drawTexture(matrix, 1, mOopsTextTexture.handle);
+
+ // Disable blending
+ GLES20.glDisable(GLES20.GL_BLEND);
+ GLESUtil.glesCheckError("glDisable");
+ }
+
+ /**
+ * Method that draws a texture
+ *
+ * @param matrix The model-view-projection matrix
+ * @param index The index of the texture
+ * @param texture The texture handler
+ */
+ private void drawTexture(float[] matrix, int index, int texture) {
+ // Use our shader program
+ GLES20.glUseProgram(mProgramHandlers[index]);
+ GLESUtil.glesCheckError("glUseProgram()");
+
+ // Apply the projection and view transformation
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandlers[index], 1, false, matrix, 0);
+ GLESUtil.glesCheckError("glUniformMatrix4fv");
+
+ // Texture
+ GLES20.glVertexAttribPointer(mTextureCoordHandlers[index], 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mTextureCoordHandlers[index]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Position
+ GLES20.glVertexAttribPointer(mPositionHandlers[index], 2, GLES20.GL_FLOAT, false, 0, mPositionBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mPositionHandlers[index]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Set the input textures
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLESUtil.glesCheckError("glActiveTexture");
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
+ GLESUtil.glesCheckError("glBindTexture");
+ GLES20.glUniform1i(mTextureHandlers[index], 0);
+ GLESUtil.glesCheckError("glUniform1i");
+
+ // Draw
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+ GLESUtil.glesCheckError("glDrawElements");
+
+ // Disable attributes
+ GLES20.glDisableVertexAttribArray(mPositionHandlers[index]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ GLES20.glDisableVertexAttribArray(mTextureCoordHandlers[index]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ }
+
+ /**
+ * Method that requests to remove the internal references and resources.
+ */
+ public void recycle() {
+ // Remove textures
+ if (mOopsImageTexture != null && mOopsImageTexture.handle != 0) {
+ int[] textures = new int[]{mOopsImageTexture.handle};
+ GLES20.glDeleteTextures(1, textures, 0);
+ GLESUtil.glesCheckError("glDeleteTextures");
+ }
+ mOopsImageTexture = null;
+ if (mOopsTextTexture != null && mOopsTextTexture.handle != 0) {
+ int[] textures = new int[]{mOopsTextTexture.handle};
+ GLES20.glDeleteTextures(1, textures, 0);
+ GLESUtil.glesCheckError("glDeleteTextures");
+ }
+ mOopsTextTexture = null;
+
+ // Remove buffers
+ if (mPositionBuffer != null) {
+ mPositionBuffer.clear();
+ }
+ if (mTextureBuffer != null) {
+ mTextureBuffer.clear();
+ }
+ mPositionBuffer = null;
+ mTextureBuffer = null;
+
+ for (int i=0; i < 2; i++) {
+ if (GLES20.glIsProgram(mProgramHandlers[i])) {
+ GLES20.glDeleteProgram(mProgramHandlers[i]);
+ GLESUtil.glesCheckError("glDeleteProgram(" + i + ")");
+ }
+ mProgramHandlers[i] = 0;
+ mTextureHandlers[i] = 0;
+ mPositionHandlers[i] = 0;
+ mTextureCoordHandlers[i] = 0;
+ mMVPMatrixHandlers[i] = 0;
+ }
+ }
+
+ /**
+ * Method that converts a text to a bitmap
+ *
+ * @param ctx The current context
+ * @param text The text to draw to the bitmap
+ * @return Bitmap The bitmap with the text
+ */
+ public Bitmap text2Bitmap(Context ctx, String text) {
+ Paint paint = new Paint();
+ Typeface font = Typeface.createFromAsset(ctx.getAssets(), "fonts/Roboto-Bold.ttf");
+ paint.setTypeface(font);
+ paint.setColor(Color.WHITE);
+ paint.setTextSize(48.0f);
+ paint.setAntiAlias(true);
+ paint.setTextAlign(Paint.Align.CENTER);
+ Bitmap src = mOopsImageTexture.bitmap;
+ Bitmap image = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(image);
+ canvas.drawText(text, src.getWidth()/2, src.getHeight() - (src.getHeight() * 0.33f), paint);
+ return image;
+ }
+}