/* * Copyright (C) 2015 Jorge Ruesga * * 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.ruesga.android.wallpapers.photophase.shapes; import android.content.Context; import android.opengl.GLES20; import android.util.Log; import com.ruesga.android.wallpapers.photophase.utils.GLESUtil; import com.ruesga.android.wallpapers.photophase.utils.GLESUtil.GLColor; import com.ruesga.android.wallpapers.photophase.R; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; /** * A shape plus color. */ public class ColorShape implements DrawableShape { private int mProgramHandler; private int mPositionHandler; private int mColorHandler; private int mMatrixHandler; private FloatBuffer mVertexBuffer; private final GLColor mColor; /** * Constructor of <code>ColorShape</code>. * * @param ctx The current context * @param vertex The vertext data * @param color The color */ public ColorShape(Context ctx, float[] vertex, GLColor color) { super(); mColor = color; mProgramHandler = GLESUtil.createProgram( ctx.getResources(), R.raw.color_vertex_shader, R.raw.color_fragment_shader); mPositionHandler = GLES20.glGetAttribLocation(mProgramHandler, "aPosition"); GLESUtil.glesCheckError("glGetAttribLocation"); mColorHandler = GLES20.glGetAttribLocation(mProgramHandler, "aColor"); GLESUtil.glesCheckError("glGetAttribLocation"); mMatrixHandler = GLES20.glGetUniformLocation(mProgramHandler, "uMVPMatrix"); GLESUtil.glesCheckError("glGetUniformLocation"); // Initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length * 4); // (# of coordinate values * 4 bytes per float) bb.order(ByteOrder.nativeOrder()); mVertexBuffer = bb.asFloatBuffer(); mVertexBuffer.put(vertex); mVertexBuffer.position(0); } /** * {@inheritDoc} */ @Override public void draw(float[] matrix) { // Bind default FBO GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLESUtil.glesCheckError("glBindFramebuffer"); if (mColor.a == 0f) { return; } // Enable properties GLES20.glEnable(GLES20.GL_BLEND); GLESUtil.glesCheckError("glEnable"); GLES20.glBlendFunc(GLES20.GL_SRC_COLOR, GLES20.GL_ONE_MINUS_SRC_ALPHA); GLESUtil.glesCheckError("glBlendFunc"); // Set the program and its attributes GLES20.glUseProgram(mProgramHandler); GLESUtil.glesCheckError("glUseProgram"); // Position mVertexBuffer.position(0); GLES20.glVertexAttribPointer(mPositionHandler, 2, GLES20.GL_FLOAT, false, 0, mVertexBuffer); GLESUtil.glesCheckError("glVertexAttribPointer"); GLES20.glEnableVertexAttribArray(mPositionHandler); GLESUtil.glesCheckError("glEnableVertexAttribArray"); // Color GLES20.glVertexAttrib4f(mColorHandler, mColor.r, mColor.g, mColor.b, mColor.a); GLESUtil.glesCheckError("glVertexAttrib4f"); // Apply the projection and view transformation GLES20.glUniformMatrix4fv(mMatrixHandler, 1, false, matrix, 0); GLESUtil.glesCheckError("glUniformMatrix4fv"); // Draw the photo frame GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLESUtil.glesCheckError("glDrawElements"); // Disable attributes GLES20.glDisableVertexAttribArray(mPositionHandler); GLESUtil.glesCheckError("glDisableVertexAttribArray"); GLES20.glDisableVertexAttribArray(mColorHandler); GLESUtil.glesCheckError("glDisableVertexAttribArray"); // Disable properties GLES20.glDisable(GLES20.GL_BLEND); GLESUtil.glesCheckError("glDisable"); } /** * Method that sets the alpha color of the shape * * @param value The new alpha color of the shape */ public void setAlpha(float value) { mColor.a = value; } /** * Method that destroy all the internal references */ public void recycle() { if (GLES20.glIsProgram(mProgramHandler)) { if (GLESUtil.DEBUG_GL_MEMOBJS) { Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteProgram: " + mProgramHandler); } GLES20.glDeleteProgram(mProgramHandler); GLESUtil.glesCheckError("glDeleteProgram"); } mProgramHandler = 0; mPositionHandler = 0; mColorHandler = 0; mMatrixHandler = 0; mVertexBuffer.clear(); mVertexBuffer = null; } }