Index: remoting/android/java/src/org/chromium/chromoting/cardboard/Photosphere.java |
diff --git a/remoting/android/java/src/org/chromium/chromoting/cardboard/Photosphere.java b/remoting/android/java/src/org/chromium/chromoting/cardboard/Photosphere.java |
deleted file mode 100644 |
index d94480cbac56d6476c3b3cbe12a471fa2d22dd87..0000000000000000000000000000000000000000 |
--- a/remoting/android/java/src/org/chromium/chromoting/cardboard/Photosphere.java |
+++ /dev/null |
@@ -1,313 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-package org.chromium.chromoting.cardboard; |
- |
-import static org.chromium.chromoting.cardboard.CardboardUtil.makeFloatBuffer; |
-import static org.chromium.chromoting.cardboard.CardboardUtil.makeShortBuffer; |
- |
-import android.app.Activity; |
-import android.graphics.Bitmap; |
-import android.graphics.BitmapFactory; |
-import android.opengl.GLES20; |
- |
-import com.google.vrtoolkit.cardboard.Eye; |
- |
-import org.chromium.base.Log; |
-import org.chromium.chromoting.ChromotingDownloadManager; |
- |
-import java.nio.FloatBuffer; |
-import java.nio.ShortBuffer; |
- |
-/** |
- * Cardboard Activity photosphere, which is used to draw the activity environment. |
- */ |
-public class Photosphere { |
- private static final String TAG = "Cardboard"; |
- |
- private static final String VERTEX_SHADER = |
- "uniform mat4 u_CombinedMatrix;" |
- + "attribute vec4 a_Position;" |
- + "attribute vec2 a_TexCoordinate;" |
- + "varying vec2 v_TexCoordinate;" |
- + "void main() {" |
- + " v_TexCoordinate = a_TexCoordinate;" |
- + " gl_Position = u_CombinedMatrix * a_Position;" |
- + "}"; |
- |
- private static final String FRAGMENT_SHADER = |
- "precision mediump float;" |
- + "uniform sampler2D u_Texture;" |
- + "varying vec2 v_TexCoordinate;" |
- + "void main() {" |
- + " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" |
- + "}"; |
- |
- private int mVertexShaderHandle; |
- private int mFragmentShaderHandle; |
- private int mProgramHandle; |
- private int mCombinedMatrixHandle; |
- private int mPositionHandle; |
- private int mLeftEyeTextureDataHandle; |
- private int mRightEyeTextureDataHandle; |
- private int mTextureCoordinateHandle; |
- private int mTextureUniformHandle; |
- |
- private static final float RADIUS = 100.0f; |
- |
- // Subdivision of the texture. |
- // Note: (COLUMS + 1) * (ROWS + 1), which is the number of vertices, should be within the |
- // range of short. |
- private static final int COLUMNS = 100; |
- private static final int ROWS = 50; |
- |
- private static final int POSITION_DATA_SIZE = 3; |
- private static final int TEXTURE_COORDINATE_DATA_SIZE = 2; |
- |
- // Number of drawing vertices needed to draw a rectangle surface. |
- private static final int NUM_DRAWING_VERTICES_PER_RECT = 6; |
- |
- private static final int NUM_VERTICES = (ROWS + 1) * (COLUMNS + 1); |
- |
- // Number of drawing vertices passed to glDrawElements(). |
- private static final int NUM_DRAWING_VERTICES = ROWS * COLUMNS * NUM_DRAWING_VERTICES_PER_RECT; |
- |
- // TODO(shichengfeng): Find a photosphere image and upload it. |
- private static final String IMAGE_URI = |
- "https://dl.google.com/chrome-remote-desktop/android-assets/photosphere.jpg"; |
- private static final String IMAGE_NAME = "photosphere"; |
- |
- private static final ShortBuffer INDICES_BUFFER = calculateIndicesBuffer(); |
- |
- // Maximum resolution for decoded image. |
- private static final int MAX_WIDTH = 4096; |
- private static final int MAX_HEIGHT = 4096; |
- |
- private FloatBuffer mPositionBuffer; |
- private FloatBuffer mTextureCoordinatesBuffer; |
- |
- private Activity mActivity; |
- |
- private String mDownloadDirectory; |
- |
- // Lock to allow multithreaded access to mDownloadDirectory. |
- private final Object mDownloadDirectoryLock = new Object(); |
- |
- // Flag to signal that the image is fully decoded and should be loaded |
- // into the OpenGL textures. |
- private boolean mLoadTexture; |
- |
- // Lock to allow multithreaded access to mLoadTexture. |
- private final Object mLoadTextureLock = new Object(); |
- |
- ChromotingDownloadManager mDownloadManager; |
- |
- public Photosphere(Activity activity) { |
- mActivity = activity; |
- |
- calculatePosition(); |
- calculateIndicesBuffer(); |
- |
- // Set handlers for eye point drawing. |
- mVertexShaderHandle = |
- ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER); |
- mFragmentShaderHandle = |
- ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER); |
- mProgramHandle = ShaderHelper.createAndLinkProgram(mVertexShaderHandle, |
- mFragmentShaderHandle, new String[] {"a_Position", "u_CombinedMatrix", |
- "a_TexCoordinate", "u_Texture"}); |
- mPositionHandle = |
- GLES20.glGetAttribLocation(mProgramHandle, "a_Position"); |
- mCombinedMatrixHandle = |
- GLES20.glGetUniformLocation(mProgramHandle, "u_CombinedMatrix"); |
- mTextureCoordinateHandle = |
- GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate"); |
- mTextureUniformHandle = |
- GLES20.glGetUniformLocation(mProgramHandle, "u_TextureUnit"); |
- mLeftEyeTextureDataHandle = TextureHelper.createTextureHandle(); |
- mRightEyeTextureDataHandle = TextureHelper.createTextureHandle(); |
- |
- mActivity.runOnUiThread(new Runnable() { |
- public void run() { |
- // Download the phtosphere image. |
- mDownloadManager = new ChromotingDownloadManager(mActivity, IMAGE_NAME, |
- IMAGE_URI, new ChromotingDownloadManager.Callback() { |
- @Override |
- public void onBatchDownloadComplete() { |
- synchronized (mLoadTextureLock) { |
- mLoadTexture = true; |
- } |
- } |
- }); |
- synchronized (mDownloadDirectoryLock) { |
- mDownloadDirectory = mDownloadManager.getDownloadDirectory(); |
- } |
- mDownloadManager.download(); |
- } |
- }); |
- } |
- |
- /** |
- * Set the texture for photosphere and clean temporary decoded image at the end. |
- * Only call this method when we have completely downloaded photosphere image. |
- */ |
- public void maybeLoadTextureAndCleanImage() { |
- synchronized (mLoadTextureLock) { |
- if (!mLoadTexture) { |
- return; |
- } |
- mLoadTexture = false; |
- } |
- |
- Bitmap image; |
- synchronized (mDownloadDirectoryLock) { |
- // This will only be executed when download finishes, which runs on main thread. |
- // On the main thread, we first initialize mDownloadDirectory and then start download, |
- // so it is safe to use mDownloadDirectory here. |
- // First decode with inJustDecodeBounds = true to check dimensions. |
- final BitmapFactory.Options options = new BitmapFactory.Options(); |
- options.inJustDecodeBounds = true; |
- BitmapFactory.decodeFile(mDownloadDirectory + "/" + IMAGE_NAME, options); |
- |
- calculateInSampleSize(options); |
- |
- // Decode bitmap with inSampleSize set |
- options.inJustDecodeBounds = false; |
- image = BitmapFactory.decodeFile(mDownloadDirectory + "/" + IMAGE_NAME, options); |
- } |
- |
- if (image == null) { |
- Log.i(TAG, "Failed to decode image files."); |
- return; |
- } |
- |
- Bitmap leftEyeImage = Bitmap.createBitmap(image, 0, 0, image.getWidth(), |
- image.getHeight() / 2); |
- TextureHelper.linkTexture(mLeftEyeTextureDataHandle, leftEyeImage); |
- leftEyeImage.recycle(); |
- Bitmap rightEyeImage = Bitmap.createBitmap(image, 0, image.getHeight() / 2, |
- image.getWidth(), image.getHeight() / 2); |
- TextureHelper.linkTexture(mRightEyeTextureDataHandle, rightEyeImage); |
- rightEyeImage.recycle(); |
- |
- image.recycle(); |
- } |
- |
- public void draw(float[] combinedMatrix, int eyeType) { |
- GLES20.glUseProgram(mProgramHandle); |
- |
- // Pass in model view project matrix. |
- GLES20.glUniformMatrix4fv(mCombinedMatrixHandle, 1, false, combinedMatrix, 0); |
- |
- GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, |
- false, 0, mPositionBuffer); |
- GLES20.glEnableVertexAttribArray(mPositionHandle); |
- |
- // Pass in texture coordinate. |
- GLES20.glVertexAttribPointer(mTextureCoordinateHandle, TEXTURE_COORDINATE_DATA_SIZE, |
- GLES20.GL_FLOAT, false, 0, mTextureCoordinatesBuffer); |
- GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); |
- |
- // Link texture data with texture unit. |
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0); |
- if (eyeType == Eye.Type.LEFT) { |
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLeftEyeTextureDataHandle); |
- } else if (eyeType == Eye.Type.RIGHT) { |
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRightEyeTextureDataHandle); |
- } |
- GLES20.glUniform1i(mTextureUniformHandle, 0); |
- |
- GLES20.glDrawElements(GLES20.GL_TRIANGLES, NUM_DRAWING_VERTICES, GLES20.GL_UNSIGNED_SHORT, |
- INDICES_BUFFER); |
- |
- GLES20.glDisableVertexAttribArray(mPositionHandle); |
- GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle); |
- } |
- |
- /** |
- * Calculate the sphere position coordinates and texture coordinates. |
- */ |
- private void calculatePosition() { |
- float[] vertexCoordinates = new float[NUM_VERTICES * POSITION_DATA_SIZE]; |
- float[] textureCoordinates = new float[NUM_VERTICES * TEXTURE_COORDINATE_DATA_SIZE]; |
- |
- int vertexIndex = 0; |
- int textureCoordinateIndex = 0; |
- for (int row = 0; row <= ROWS; row++) { |
- for (int column = 0; column <= COLUMNS; column++) { |
- double theta = (ROWS / 2.0 - row) / (ROWS / 2.0) * Math.PI / 2; |
- double phi = 2 * Math.PI * column / COLUMNS; |
- float x = (float) (RADIUS * Math.cos(theta) * Math.cos(phi)); |
- float y = (float) (RADIUS * Math.sin(theta)); |
- float z = (float) (RADIUS * Math.cos(theta) * Math.sin(phi)); |
- |
- vertexCoordinates[vertexIndex++] = x; |
- vertexCoordinates[vertexIndex++] = y; |
- vertexCoordinates[vertexIndex++] = z; |
- |
- textureCoordinates[textureCoordinateIndex++] = (float) column / COLUMNS; |
- textureCoordinates[textureCoordinateIndex++] = (float) row / ROWS; |
- } |
- } |
- |
- mPositionBuffer = makeFloatBuffer(vertexCoordinates); |
- mTextureCoordinatesBuffer = makeFloatBuffer(textureCoordinates); |
- } |
- |
- /** |
- * Calculate the drawing indices buffer. |
- */ |
- private static ShortBuffer calculateIndicesBuffer() { |
- short[] indices = new short[NUM_DRAWING_VERTICES]; |
- int currentIndex = 0; |
- for (int row = 0; row < ROWS; row++) { |
- for (int column = 0; column < COLUMNS; column++) { |
- int topLeft = row * (COLUMNS + 1) + column; |
- int topRight = topLeft + 1; |
- int bottomLeft = topLeft + (COLUMNS + 1); |
- int bottomRight = bottomLeft + 1; |
- indices[currentIndex++] = (short) topLeft; |
- indices[currentIndex++] = (short) bottomLeft; |
- indices[currentIndex++] = (short) topRight; |
- indices[currentIndex++] = (short) bottomLeft; |
- indices[currentIndex++] = (short) bottomRight; |
- indices[currentIndex++] = (short) topRight; |
- } |
- } |
- return makeShortBuffer(indices); |
- } |
- |
- /** |
- * Clean up opengl data. |
- */ |
- public void cleanup() { |
- GLES20.glDeleteShader(mVertexShaderHandle); |
- GLES20.glDeleteShader(mFragmentShaderHandle); |
- GLES20.glDeleteTextures(2, new int[] {mLeftEyeTextureDataHandle, |
- mRightEyeTextureDataHandle}, 0); |
- |
- mActivity.runOnUiThread(new Runnable() { |
- public void run() { |
- mDownloadManager.close(); |
- } |
- }); |
- } |
- |
- // Calculate InSampleSize, which is the number of pixels in either dimension that correspond |
- // to a single pixel in the decoded bitmap. |
- private static void calculateInSampleSize(BitmapFactory.Options options) { |
- // Raw height and width of image |
- int height = options.outHeight; |
- int width = options.outWidth; |
- int inSampleSize = 1; |
- |
- while (height > MAX_HEIGHT || width > MAX_WIDTH) { |
- inSampleSize *= 2; |
- height /= 2; |
- width /= 2; |
- } |
- |
- options.inSampleSize = inSampleSize; |
- } |
-} |