com.kunato.imagestitching.SphereObject.java Source code

Java tutorial

Introduction

Here is the source code for com.kunato.imagestitching.SphereObject.java

Source

/*
 * Copyright (C) 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.
 */
package com.kunato.imagestitching;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

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

public class SphereObject {

    private final String vertexShaderCode = "uniform mat4 uViewMatrix;" + "uniform mat4 uProjectionMatrix;"
            + "attribute vec4 vPosition;" + "attribute vec4 vColor;" + "attribute vec2 a_TexCoordinate;"
            + "varying vec4 vPosition2;" + "varying vec4 fragmentColor;" + "varying vec2 v_TexCoordinate;"
            + "void main() {" + "  vPosition2 = vec4 ( vPosition.x, vPosition.y, vPosition.z, 1 );"
            + "  gl_Position = uProjectionMatrix * uViewMatrix * vPosition2;" + "  fragmentColor = vColor;"
            + "  v_TexCoordinate = a_TexCoordinate;" + "}";

    private final String fragmentShaderCode = "precision highp float;" + "uniform sampler2D sTexture;"
            + "varying vec2 v_TexCoordinate;" + "varying vec4 fragmentColor;" + "float width_ratio = 9242.0;"
            + "float height_ratio = 4620.0;" + "uniform float img_x;" + "uniform float img_y;"
            + "uniform float img_width;" + "uniform float img_height;" + "void main() {"
            + "if(img_x == 0.0 && img_y == 0.0 && img_width == 0.0 && img_height == 0.0){"
            + "   gl_FragColor = vec4(0,0,0,0);" + "   return;" + "}"
            + "if(v_TexCoordinate.x*width_ratio <= img_x || v_TexCoordinate.x*width_ratio >= (img_x+img_width) || "
            + "   v_TexCoordinate.y*height_ratio <= img_y || v_TexCoordinate.y*height_ratio >= (img_y+img_height)){"
            + "   gl_FragColor = vec4(0,0,0,0);" + "}" + "else{"
            + "   float diff_x = (((v_TexCoordinate.x*width_ratio) - (img_x))/(img_width));"
            + "   float diff_y = (((v_TexCoordinate.y*height_ratio) - (img_y))/(img_height));"
            + "   gl_FragColor = texture2D(sTexture,vec2(diff_x,diff_y));" + "}" + "}";

    private final int mProgram;
    private int mPositionHandle;
    private int mTextureHandle;
    private int mViewMatrixHandle;
    private int mProjectionMatrixHandle;
    private SphereShape mSphereShape;
    private FloatBuffer mSphereBuffer;
    private ShortBuffer mIndexBuffer;
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f };
    //Only one texture
    private int[] mTextures = new int[1];
    private int mTextureCoordinateHandle;
    private boolean mTexRequireUpdate = false;
    private Bitmap mQueueBitmap;
    public boolean readPixel = false;
    private ByteBuffer mScreenBuffer;
    private GLRenderer glRenderer;
    public float[] mArea = { 0, 0, 0, 0 };

    public SphereObject(GLRenderer renderer) {
        glRenderer = renderer;
        Context context = renderer.mView.getActivity();
        mSphereShape = new SphereShape(20, 210, 1);
        mSphereBuffer = mSphereShape.getVertices();
        mSphereBuffer.position(0);
        mIndexBuffer = mSphereShape.getIndices()[0];
        mIndexBuffer.position(0);

        mProgram = Util.loadShader(vertexShaderCode, fragmentShaderCode);

        loadGLTexture(context, R.drawable.pano);

    }

    public void loadGLTexture(final Context context, final int texture) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), texture, options);

        GLES20.glGenTextures(1, this.mTextures, 0);
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.mTextures[0]);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        //        mockTexImage2D(bitmap);
    }

    public void mockTexImage2D(Bitmap bitmap) {
        mArea[0] = mArea[1] = 0;
        mArea[2] = 9242;
        mArea[3] = 4620;
        GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
        bitmap.recycle();
    }

    public void updateBitmap(Bitmap bitmap, float[] area) {
        this.mArea = area;
        mTexRequireUpdate = true;
        mQueueBitmap = bitmap;
        Log.i("GLSphere", "Bitmap waiting for updated");
    }

    public void draw(float[] viewMatrix, float[] projectionMatrix) {
        int xh = GLES20.glGetUniformLocation(mProgram, "img_x");
        int yh = GLES20.glGetUniformLocation(mProgram, "img_y");
        int widthh = GLES20.glGetUniformLocation(mProgram, "img_width");
        int heighth = GLES20.glGetUniformLocation(mProgram, "img_height");

        if (mTexRequireUpdate) {
            Log.i("GLSphere", "Bitmap updated,Return to normal activity.");
            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.mTextures[0]);
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mQueueBitmap, 0);
            GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
            mQueueBitmap.recycle();
            mTexRequireUpdate = false;
        }
        GLES20.glUseProgram(mProgram);
        //Attrib
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
        mSphereBuffer.position(0);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, mSphereShape.getVeticesStride(),
                mSphereBuffer);

        mSphereBuffer.position(3);
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false,
                mSphereShape.getVeticesStride(), mSphereBuffer);
        //Uniform
        mTextureHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
        GLES20.glUniform1i(mTextureHandle, 0);
        //Area
        GLES20.glUniform1f(xh, mArea[0]);
        GLES20.glUniform1f(yh, mArea[1]);
        GLES20.glUniform1f(widthh, mArea[2]);
        GLES20.glUniform1f(heighth, mArea[3]);

        mViewMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uViewMatrix");
        mProjectionMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uProjectionMatrix");
        GLES20.glUniformMatrix4fv(mViewMatrixHandle, 1, false, viewMatrix, 0);
        GLES20.glUniformMatrix4fv(mProjectionMatrixHandle, 1, false, projectionMatrix, 0);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, mSphereShape.getNumIndices()[0], GLES20.GL_UNSIGNED_SHORT,
                mIndexBuffer);
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle);

        if (readPixel) {
            Log.d("GL", "ReadPixel");
            mScreenBuffer = ByteBuffer.allocateDirect(glRenderer.mHeight * glRenderer.mWidth * 4);
            mScreenBuffer.order(ByteOrder.nativeOrder());
            GLES20.glReadPixels(0, 0, glRenderer.mWidth, glRenderer.mHeight, GLES20.GL_RGBA,
                    GLES20.GL_UNSIGNED_BYTE, mScreenBuffer);
            Log.d("mScreenBuffer", "Remaining " + mScreenBuffer.remaining());
            mScreenBuffer.rewind();
            byte pixelsBuffer[] = new byte[4 * glRenderer.mHeight * glRenderer.mWidth];
            mScreenBuffer.get(pixelsBuffer);
            Mat mat = new Mat(glRenderer.mHeight, glRenderer.mWidth, CvType.CV_8UC4);
            mat.put(0, 0, pixelsBuffer);
            Mat m = new Mat();
            Imgproc.cvtColor(mat, m, Imgproc.COLOR_RGBA2BGR);
            Core.flip(m, mat, 0);
            Highgui.imwrite("/sdcard/stitch/readpixel.jpg", mat);

        }
    }

}