Index: remoting/android/java/src/org/chromium/chromoting/CardboardActivityDesktop.java |
diff --git a/remoting/android/java/src/org/chromium/chromoting/CardboardActivityDesktop.java b/remoting/android/java/src/org/chromium/chromoting/CardboardActivityDesktop.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c1c0c31f090f2939dec58aa02a09df7cb58f7d3e |
--- /dev/null |
+++ b/remoting/android/java/src/org/chromium/chromoting/CardboardActivityDesktop.java |
@@ -0,0 +1,179 @@ |
+// 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; |
+ |
+import static org.chromium.chromoting.CardboardDesktopRenderer.makeFloatBuffer; |
Lambros
2015/08/20 19:07:27
You could move makeFloatBuffer to a separate Cardb
shichengfeng
2015/08/20 20:02:59
Will do that in separate CL.
|
+ |
+import android.graphics.Bitmap; |
+import android.opengl.GLES20; |
+ |
+import java.nio.FloatBuffer; |
+ |
+/** |
+ * Chromoting Cardboard activity desktop, which is used to display host desktop. |
+ */ |
+public class CardboardActivityDesktop { |
+ 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 static final FloatBuffer TEXTURE_COORDINATES = makeFloatBuffer(new float[] { |
+ // Texture coordinate data. |
+ 0.0f, 0.0f, |
+ 0.0f, 1.0f, |
+ 1.0f, 0.0f, |
+ 0.0f, 1.0f, |
+ 1.0f, 1.0f, |
+ 1.0f, 0.0f |
+ }); |
+ |
+ private static final int POSITION_DATA_SIZE = 3; |
+ private static final int TEXTURE_COORDINATE_DATA_SIZE = 2; |
+ |
+ // Fix the desktop height and adjust width accordingly. |
+ private static final float HALF_HEIGHT = 1.0f; |
+ |
+ // Number of vertices passed to glDrawArrays(). |
+ private static final int VERTICES_NUMBER = 6; |
+ |
+ private int mVertexShaderHandle; |
+ private int mFragmentShaderHandle; |
+ private int mProgramHandle; |
+ private int mCombinedMatrixHandle; |
+ private int mTextureUniformHandle; |
+ private int mPositionHandle; |
+ private int mTextureDataHandle; |
+ private int mTextureCoordinateHandle; |
+ private FloatBuffer mPosition; |
+ private float[] mCombinedMatrix; |
+ private float mHalfWidth; |
+ private int mHeightPixels; |
Lambros
2015/08/20 19:07:27
What is this for? mHeightPixels and mWidthPixels a
shichengfeng
2015/08/20 20:02:59
Done.
|
+ private int mWidthPixels; |
+ |
+ public CardboardActivityDesktop() { |
+ 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", "a_TexCoordinate", |
+ "u_CombinedMatrix", "u_Texture"}); |
+ mCombinedMatrixHandle = |
+ GLES20.glGetUniformLocation(mProgramHandle, "u_CombinedMatrix"); |
+ mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture"); |
+ mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position"); |
+ mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate"); |
+ mTextureDataHandle = TextureHelper.createTextureHandle(); |
+ } |
+ |
+ /** |
+ * Draw the desktop. Make sure texture, position, and model view projection matrix |
+ * are passed in before calling this method. |
+ */ |
+ public void draw() { |
+ GLES20.glUseProgram(mProgramHandle); |
+ |
+ // Pass in model view project matrix. |
+ GLES20.glUniformMatrix4fv(mCombinedMatrixHandle, 1, false, mCombinedMatrix, 0); |
+ |
+ // Pass in texture coordinate. |
+ GLES20.glVertexAttribPointer(mTextureCoordinateHandle, TEXTURE_COORDINATE_DATA_SIZE, |
+ GLES20.GL_FLOAT, false, 0, TEXTURE_COORDINATES); |
+ GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); |
+ |
+ GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, |
+ 0, mPosition); |
+ GLES20.glEnableVertexAttribArray(mPositionHandle); |
+ |
+ // Link texture data with texture unit. |
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); |
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle); |
+ GLES20.glUniform1i(mTextureUniformHandle, 0); |
+ |
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, VERTICES_NUMBER); |
+ } |
+ |
+ /** |
+ * Update the desktop frame data based on the new bitmap. Note here we fix the |
+ * height of the desktop and vary width accordingly. |
+ */ |
+ public void updateFrameData(Bitmap bitmap) { |
+ float newHalfDesktopWidth = bitmap.getWidth() * HALF_HEIGHT / bitmap.getHeight(); |
+ if (Math.abs(mHalfWidth - newHalfDesktopWidth) > 0.0001) { |
+ mHalfWidth = newHalfDesktopWidth; |
+ mPosition = makeFloatBuffer(new float[] { |
+ // Desktop model coordinates. |
+ -mHalfWidth, HALF_HEIGHT, 0.0f, |
+ -mHalfWidth, -HALF_HEIGHT, 0.0f, |
+ mHalfWidth, HALF_HEIGHT, 0.0f, |
+ -mHalfWidth, -HALF_HEIGHT, 0.0f, |
+ mHalfWidth, -HALF_HEIGHT, 0.0f, |
+ mHalfWidth, HALF_HEIGHT, 0.0f |
+ }); |
+ } |
+ } |
+ |
+ /** |
+ * Clean up opengl data. |
+ */ |
+ public void cleanup() { |
+ GLES20.glDeleteShader(mVertexShaderHandle); |
+ GLES20.glDeleteShader(mFragmentShaderHandle); |
+ GLES20.glDeleteTextures(1, new int[] {mTextureDataHandle}, 0); |
+ } |
+ |
+ public void setTexture(Bitmap texture) { |
Lambros
2015/08/20 19:07:27
Why is setTexture() a separate method from updateF
shichengfeng
2015/08/20 20:02:59
Done.
|
+ TextureHelper.linkTexture(mTextureDataHandle, texture); |
+ } |
+ |
+ public void setCombinedMatrix(float[] combinedMatrix) { |
+ mCombinedMatrix = combinedMatrix.clone(); |
+ } |
+ |
+ /** |
+ * Return true if image frame data are already loaded in. |
+ */ |
+ public boolean hasImageFrame() { |
+ return mPosition != null; |
+ } |
+ |
+ public float getHalfHeight() { |
+ return HALF_HEIGHT; |
+ } |
+ |
+ public float getHalfWidth() { |
+ return mHalfWidth; |
+ } |
+ |
+ public void setHeightPixels(int heightPixels) { |
+ mHeightPixels = heightPixels; |
+ } |
+ |
+ public void setWidthPixels(int widthPixels) { |
+ mWidthPixels = widthPixels; |
+ } |
+ |
+ public int getHeightPixels() { |
+ return mHeightPixels; |
+ } |
+ |
+ public int getWidthPixels() { |
+ return mWidthPixels; |
+ } |
+} |