Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(564)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/CardboardDesktopRenderer.java

Issue 1305633002: Refactor drawing desktop. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Store desktop bitmap reference in CardboardActivityDesktop. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting; 5 package org.chromium.chromoting;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.graphics.BitmapFactory; 9 import android.graphics.BitmapFactory;
10 import android.graphics.PointF; 10 import android.graphics.PointF;
(...skipping 29 matching lines...) Expand all
40 private static final float DESKTOP_POSITION_Y = 0.0f; 40 private static final float DESKTOP_POSITION_Y = 0.0f;
41 private static final float DESKTOP_POSITION_Z = -2.0f; 41 private static final float DESKTOP_POSITION_Z = -2.0f;
42 private static final float HALF_SKYBOX_SIZE = 100.0f; 42 private static final float HALF_SKYBOX_SIZE = 100.0f;
43 private static final float VIEW_POSITION_MIN = -1.0f; 43 private static final float VIEW_POSITION_MIN = -1.0f;
44 private static final float VIEW_POSITION_MAX = 3.0f; 44 private static final float VIEW_POSITION_MAX = 3.0f;
45 45
46 // Allows user to click even when looking outside the desktop 46 // Allows user to click even when looking outside the desktop
47 // but within edge margin. 47 // but within edge margin.
48 private static final float EDGE_MARGIN = 0.1f; 48 private static final float EDGE_MARGIN = 0.1f;
49 49
50 // Fix the desktop height and adjust width accordingly.
51 private static final float HALF_DESKTOP_HEIGHT = 1.0f;
52
53 // Distance to move camera each time. 50 // Distance to move camera each time.
54 private static final float CAMERA_MOTION_STEP = 0.5f; 51 private static final float CAMERA_MOTION_STEP = 0.5f;
55 52
56 private static final FloatBuffer DESKTOP_TEXTURE_COORDINATES = makeFloatBuff er(new float[] {
57 // Texture coordinate data.
58 0.0f, 0.0f,
59 0.0f, 1.0f,
60 1.0f, 0.0f,
61 0.0f, 1.0f,
62 1.0f, 1.0f,
63 1.0f, 0.0f
64 });
65
66 private static final FloatBuffer SKYBOX_POSITION_COORDINATES = makeFloatBuff er(new float[] { 53 private static final FloatBuffer SKYBOX_POSITION_COORDINATES = makeFloatBuff er(new float[] {
67 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (0) Top -left near 54 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (0) Top -left near
68 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (1) Top- right near 55 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (1) Top- right near
69 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (2) Bot tom-left near 56 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (2) Bot tom-left near
70 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (3) Bott om-right near 57 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (3) Bott om-right near
71 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (4) Top -left far 58 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (4) Top -left far
72 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (5) Top- right far 59 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (5) Top- right far
73 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (6) Bot tom-left far 60 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (6) Bot tom-left far
74 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE // (7) Botto m-right far 61 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE // (7) Botto m-right far
75 }); 62 });
(...skipping 17 matching lines...) Expand all
93 80
94 // Top 81 // Top
95 5, 1, 4, 82 5, 1, 4,
96 4, 1, 0, 83 4, 1, 0,
97 84
98 // Bottom 85 // Bottom
99 6, 2, 7, 86 6, 2, 7,
100 7, 2, 3 87 7, 2, 3
101 }); 88 });
102 89
103 private static final String DESKTOP_VERTEX_SHADER =
104 "uniform mat4 u_CombinedMatrix;"
105 + "attribute vec4 a_Position;"
106 + "attribute vec2 a_TexCoordinate;"
107 + "varying vec2 v_TexCoordinate;"
108 + "void main() {"
109 + " v_TexCoordinate = a_TexCoordinate;"
110 + " gl_Position = u_CombinedMatrix * a_Position;"
111 + "}";
112
113 private static final String DESKTOP_FRAGMENT_SHADER =
114 "precision highp float;"
115 + "uniform sampler2D u_Texture;"
116 + "varying vec2 v_TexCoordinate;"
117 + "const float borderWidth = 0.002;"
118 + "void main() {"
119 + " if (v_TexCoordinate.x > (1.0 - borderWidth) || v_TexCoordinate. x < borderWidth"
120 + " || v_TexCoordinate.y > (1.0 - borderWidth)"
121 + " || v_TexCoordinate.y < borderWidth) {"
122 + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);"
123 + " } else {"
124 + " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);"
125 + " }"
126 + "}";
127
128 private static final String SKYBOX_VERTEX_SHADER = 90 private static final String SKYBOX_VERTEX_SHADER =
129 "uniform mat4 u_CombinedMatrix;" 91 "uniform mat4 u_CombinedMatrix;"
130 + "attribute vec3 a_Position;" 92 + "attribute vec3 a_Position;"
131 + "varying vec3 v_Position;" 93 + "varying vec3 v_Position;"
132 + "void main() {" 94 + "void main() {"
133 + " v_Position = a_Position;" 95 + " v_Position = a_Position;"
134 // Make sure to convert from the right-handed coordinate system of t he 96 // Make sure to convert from the right-handed coordinate system of t he
135 // world to the left-handed coordinate system of the cube map, other wise, 97 // world to the left-handed coordinate system of the cube map, other wise,
136 // our cube map will still work but everything will be flipped. 98 // our cube map will still work but everything will be flipped.
137 + " v_Position.z = -v_Position.z;" 99 + " v_Position.z = -v_Position.z;"
(...skipping 20 matching lines...) Expand all
158 "https://dl.google.com/chrome-remote-desktop/android-assets/room_back.pn g", 120 "https://dl.google.com/chrome-remote-desktop/android-assets/room_back.pn g",
159 "https://dl.google.com/chrome-remote-desktop/android-assets/room_front.p ng" 121 "https://dl.google.com/chrome-remote-desktop/android-assets/room_front.p ng"
160 }; 122 };
161 123
162 private static final String[] SKYBOX_IMAGE_NAMES = new String[] { 124 private static final String[] SKYBOX_IMAGE_NAMES = new String[] {
163 "skybox_left", "skybox_right", "skybox_bottom", "skybox_top", "skybox_ba ck", "skybox_front" 125 "skybox_left", "skybox_right", "skybox_bottom", "skybox_top", "skybox_ba ck", "skybox_front"
164 }; 126 };
165 127
166 private final Activity mActivity; 128 private final Activity mActivity;
167 129
168 private float mHalfDesktopWidth;
169 private float mCameraPosition; 130 private float mCameraPosition;
170 131
171 // Lock to allow multithreaded access to mCameraPosition. 132 // Lock to allow multithreaded access to mCameraPosition.
172 private Object mCameraPositionLock = new Object(); 133 private Object mCameraPositionLock = new Object();
173 134
174 private float[] mCameraMatrix; 135 private float[] mCameraMatrix;
175 private float[] mViewMatrix; 136 private float[] mViewMatrix;
176 private float[] mProjectionMatrix; 137 private float[] mProjectionMatrix;
177 138
178 // Make matrix member variable to avoid unnecessary initialization. 139 // Make matrix member variable to avoid unnecessary initialization.
179 private float[] mDesktopModelMatrix; 140 private float[] mDesktopModelMatrix;
180 private float[] mDesktopCombinedMatrix; 141 private float[] mDesktopCombinedMatrix;
181 private float[] mEyePointModelMatrix; 142 private float[] mEyePointModelMatrix;
182 private float[] mEyePointCombinedMatrix; 143 private float[] mEyePointCombinedMatrix;
183 private float[] mSkyboxModelMatrix; 144 private float[] mSkyboxModelMatrix;
184 private float[] mSkyboxCombinedMatrix; 145 private float[] mSkyboxCombinedMatrix;
185 146
186 // Direction that user is looking towards. 147 // Direction that user is looking towards.
187 private float[] mForwardVector; 148 private float[] mForwardVector;
188 149
189 // Eye position in desktop. 150 // Eye position in desktop.
190 private float[] mEyePositionVector; 151 private float[] mEyePositionVector;
191 152
192 private int mDesktopCombinedMatrixHandle;
193 private int mPositionHandle;
194 private int mTextureDataHandle;
195 private int mTextureUniformHandle;
196 private int mTextureCoordinateHandle;
197 private int mProgramHandle;
198 private int mDesktopVertexShaderHandle;
199 private int mDesktopFragmentShaderHandle;
200 private int mSkyboxVertexShaderHandle; 153 private int mSkyboxVertexShaderHandle;
201 private int mSkyboxFragmentShaderHandle; 154 private int mSkyboxFragmentShaderHandle;
202 private int mSkyboxProgramHandle; 155 private int mSkyboxProgramHandle;
203 private int mSkyboxPositionHandle; 156 private int mSkyboxPositionHandle;
204 private int mSkyboxCombinedMatrixHandle; 157 private int mSkyboxCombinedMatrixHandle;
205 private int mSkyboxTextureUnitHandle; 158 private int mSkyboxTextureUnitHandle;
206 private int mSkyboxTextureDataHandle; 159 private int mSkyboxTextureDataHandle;
160 private CardboardActivityDesktop mDesktop;
207 private CardboardActivityEyePoint mEyePoint; 161 private CardboardActivityEyePoint mEyePoint;
208 162
209 // Flag to indicate whether reload the desktop texture or not. 163 // Flag to indicate whether reload the desktop texture or not.
210 private boolean mReloadTexture; 164 private boolean mReloadTexture;
211 165
212 /** Lock to allow multithreaded access to mReloadTexture. */ 166 /** Lock to allow multithreaded access to mReloadTexture. */
213 private Object mReloadTextureLock = new Object(); 167 private Object mReloadTextureLock = new Object();
214 168
215 // Lock for eye position related operations. 169 // Lock for eye position related operations.
216 // This protects access to mEyePositionVector as well as mDesktop{Height/Wid th}Pixels. 170 // This protects access to mEyePositionVector as well as mImageFrame in mDes ktop.
217 private Object mEyePositionLock = new Object(); 171 private Object mEyePositionLock = new Object();
218 172
219 private int mDesktopHeightPixels;
220 private int mDesktopWidthPixels;
221
222 private FloatBuffer mDesktopCoordinates;
223
224 // Flag to signal that the skybox images are fully decoded and should be loa ded 173 // Flag to signal that the skybox images are fully decoded and should be loa ded
225 // into the OpenGL textures. 174 // into the OpenGL textures.
226 private boolean mLoadSkyboxImagesTexture; 175 private boolean mLoadSkyboxImagesTexture;
227 176
228 // Lock to allow multithreaded access to mLoadSkyboxImagesTexture. 177 // Lock to allow multithreaded access to mLoadSkyboxImagesTexture.
229 private Object mLoadSkyboxImagesTextureLock = new Object(); 178 private Object mLoadSkyboxImagesTextureLock = new Object();
230 179
231 private ChromotingDownloadManager mDownloadManager; 180 private ChromotingDownloadManager mDownloadManager;
232 181
233 public CardboardDesktopRenderer(Activity activity) { 182 public CardboardDesktopRenderer(Activity activity) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 public void onSurfaceCreated(EGLConfig config) { 227 public void onSurfaceCreated(EGLConfig config) {
279 // Set the background clear color to black. 228 // Set the background clear color to black.
280 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 229 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
281 230
282 // Use culling to remove back faces. 231 // Use culling to remove back faces.
283 GLES20.glEnable(GLES20.GL_CULL_FACE); 232 GLES20.glEnable(GLES20.GL_CULL_FACE);
284 233
285 // Enable depth testing. 234 // Enable depth testing.
286 GLES20.glEnable(GLES20.GL_DEPTH_TEST); 235 GLES20.glEnable(GLES20.GL_DEPTH_TEST);
287 236
288 // Set handles for desktop drawing.
289 mDesktopVertexShaderHandle =
290 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, DESKTOP_VERT EX_SHADER);
291 mDesktopFragmentShaderHandle =
292 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, DESKTOP_FR AGMENT_SHADER);
293 mProgramHandle = ShaderHelper.createAndLinkProgram(mDesktopVertexShaderH andle,
294 mDesktopFragmentShaderHandle, new String[] {"a_Position", "a_Tex Coordinate"});
295 mDesktopCombinedMatrixHandle =
296 GLES20.glGetUniformLocation(mProgramHandle, "u_CombinedMatrix");
297 mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_T exture");
298 mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position ");
299 mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a _TexCoordinate");
300 mTextureDataHandle = TextureHelper.createTextureHandle();
301
302 // Set handlers for skybox drawing. 237 // Set handlers for skybox drawing.
303 GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP); 238 GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP);
304 mSkyboxVertexShaderHandle = 239 mSkyboxVertexShaderHandle =
305 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, SKYBOX_VERTE X_SHADER); 240 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, SKYBOX_VERTE X_SHADER);
306 mSkyboxFragmentShaderHandle = 241 mSkyboxFragmentShaderHandle =
307 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, SKYBOX_FRA GMENT_SHADER); 242 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, SKYBOX_FRA GMENT_SHADER);
308 mSkyboxProgramHandle = ShaderHelper.createAndLinkProgram(mSkyboxVertexSh aderHandle, 243 mSkyboxProgramHandle = ShaderHelper.createAndLinkProgram(mSkyboxVertexSh aderHandle,
309 mSkyboxFragmentShaderHandle, 244 mSkyboxFragmentShaderHandle,
310 new String[] {"a_Position", "u_CombinedMatrix", "u_TextureUnit"} ); 245 new String[] {"a_Position", "u_CombinedMatrix", "u_TextureUnit"} );
311 mSkyboxPositionHandle = 246 mSkyboxPositionHandle =
312 GLES20.glGetAttribLocation(mSkyboxProgramHandle, "a_Position"); 247 GLES20.glGetAttribLocation(mSkyboxProgramHandle, "a_Position");
313 mSkyboxCombinedMatrixHandle = 248 mSkyboxCombinedMatrixHandle =
314 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_CombinedMat rix"); 249 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_CombinedMat rix");
315 mSkyboxTextureUnitHandle = 250 mSkyboxTextureUnitHandle =
316 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_TextureUnit "); 251 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_TextureUnit ");
317 mSkyboxTextureDataHandle = TextureHelper.createTextureHandle(); 252 mSkyboxTextureDataHandle = TextureHelper.createTextureHandle();
318 253
254 mDesktop = new CardboardActivityDesktop();
319 mEyePoint = new CardboardActivityEyePoint(); 255 mEyePoint = new CardboardActivityEyePoint();
320 } 256 }
321 257
322 @Override 258 @Override
323 public void onSurfaceChanged(int width, int height) { 259 public void onSurfaceChanged(int width, int height) {
324 } 260 }
325 261
326 @Override 262 @Override
327 public void onNewFrame(HeadTransform headTransform) { 263 public void onNewFrame(HeadTransform headTransform) {
328 // Position the eye at the origin. 264 // Position the eye at the origin.
(...skipping 11 matching lines...) Expand all
340 276
341 // Set our up vector. This is where our head would be pointing were we h olding the camera. 277 // Set our up vector. This is where our head would be pointing were we h olding the camera.
342 float upX = 0.0f; 278 float upX = 0.0f;
343 float upY = 1.0f; 279 float upY = 1.0f;
344 float upZ = 0.0f; 280 float upZ = 0.0f;
345 281
346 Matrix.setLookAtM(mCameraMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, look Z, upX, upY, upZ); 282 Matrix.setLookAtM(mCameraMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, look Z, upX, upY, upZ);
347 283
348 headTransform.getForwardVector(mForwardVector, 0); 284 headTransform.getForwardVector(mForwardVector, 0);
349 getLookingPosition(); 285 getLookingPosition();
350 maybeLoadTexture(mTextureDataHandle); 286 maybeLoadDesktopTexture();
351 maybeLoadCubeMapAndCleanImages(mSkyboxTextureDataHandle); 287 maybeLoadCubeMapAndCleanImages(mSkyboxTextureDataHandle);
352 } 288 }
353 289
354 @Override 290 @Override
355 public void onDrawEye(Eye eye) { 291 public void onDrawEye(Eye eye) {
356 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 292 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
357 293
358 // Apply the eye transformation to the camera. 294 // Apply the eye transformation to the camera.
359 Matrix.multiplyMM(mViewMatrix, 0, eye.getEyeView(), 0, mCameraMatrix, 0) ; 295 Matrix.multiplyMM(mViewMatrix, 0, eye.getEyeView(), 0, mCameraMatrix, 0) ;
360 296
361 mProjectionMatrix = eye.getPerspective(Z_NEAR, Z_FAR); 297 mProjectionMatrix = eye.getPerspective(Z_NEAR, Z_FAR);
362 298
363 drawSkybox(); 299 drawSkybox();
364 drawDesktop(); 300 drawDesktop();
365 drawEyePoint(); 301 drawEyePoint();
366 } 302 }
367 303
368 @Override 304 @Override
369 public void onRendererShutdown() { 305 public void onRendererShutdown() {
370 GLES20.glDeleteShader(mDesktopVertexShaderHandle); 306 mDesktop.cleanup();
371 GLES20.glDeleteShader(mDesktopFragmentShaderHandle);
372 mEyePoint.cleanup(); 307 mEyePoint.cleanup();
373 GLES20.glDeleteShader(mSkyboxVertexShaderHandle); 308 GLES20.glDeleteShader(mSkyboxVertexShaderHandle);
374 GLES20.glDeleteShader(mSkyboxFragmentShaderHandle); 309 GLES20.glDeleteShader(mSkyboxFragmentShaderHandle);
375 GLES20.glDeleteTextures(1, new int[] {mTextureDataHandle}, 0);
376 GLES20.glDeleteTextures(1, new int[] {mSkyboxTextureDataHandle}, 0); 310 GLES20.glDeleteTextures(1, new int[] {mSkyboxTextureDataHandle}, 0);
377 mActivity.runOnUiThread(new Runnable() { 311 mActivity.runOnUiThread(new Runnable() {
378 public void run() { 312 public void run() {
379 mDownloadManager.close(); 313 mDownloadManager.close();
380 } 314 }
381 }); 315 });
382 } 316 }
383 317
384 @Override 318 @Override
385 public void onFinishFrame(Viewport viewport) { 319 public void onFinishFrame(Viewport viewport) {
386 } 320 }
387 321
388 private void drawDesktop() { 322 private void drawDesktop() {
389 GLES20.glUseProgram(mProgramHandle); 323 synchronized (mEyePositionLock) {
324 if (!mDesktop.hasImageFrame()) {
325 // This can happen if the client is connected, but a complete
326 // video frame has not yet been decoded.
327 return;
328 }
329 }
390 330
391 // Translate the desktop model. 331
392 Matrix.setIdentityM(mDesktopModelMatrix, 0); 332 Matrix.setIdentityM(mDesktopModelMatrix, 0);
393 Matrix.translateM(mDesktopModelMatrix, 0, DESKTOP_POSITION_X, 333 Matrix.translateM(mDesktopModelMatrix, 0, DESKTOP_POSITION_X,
394 DESKTOP_POSITION_Y, DESKTOP_POSITION_Z); 334 DESKTOP_POSITION_Y, DESKTOP_POSITION_Z);
395 335
396 // Pass in Model View Matrix and Model View Project Matrix. 336 // Pass in Model View Matrix and Model View Project Matrix.
397 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mViewMatrix, 0, mDesktopMod elMatrix, 0); 337 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mViewMatrix, 0, mDesktopMod elMatrix, 0);
398 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mProjectionMatrix, 338 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mProjectionMatrix,
399 0, mDesktopCombinedMatrix, 0); 339 0, mDesktopCombinedMatrix, 0);
340 mDesktop.setCombinedMatrix(mDesktopCombinedMatrix);
400 341
401 // Pass in model view project matrix. 342 mDesktop.draw();
402 GLES20.glUniformMatrix4fv(mDesktopCombinedMatrixHandle, 1, false,
403 mDesktopCombinedMatrix, 0);
404
405 if (mDesktopCoordinates == null) {
406 // This can happen if the client is connected, but a complete video frame has not yet
407 // been decoded.
408 return;
409 }
410 // Pass in the desktop position.
411 GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20 .GL_FLOAT, false,
412 0, mDesktopCoordinates);
413 GLES20.glEnableVertexAttribArray(mPositionHandle);
414
415 // Pass in texture coordinate.
416 GLES20.glVertexAttribPointer(mTextureCoordinateHandle, TEXTURE_COORDINAT E_DATA_SIZE,
417 GLES20.GL_FLOAT, false, 0, DESKTOP_TEXTURE_COORDINATES);
418 GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
419
420 // Pass in texture data.
421 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
422 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
423 GLES20.glUniform1i(mTextureUniformHandle, 0);
424
425 // Draw the desktop.
426 int totalPointNumber = 6;
427 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, totalPointNumber);
428 } 343 }
429 344
430 private void drawEyePoint() { 345 private void drawEyePoint() {
431 if (!isLookingAtDesktop()) { 346 if (!isLookingAtDesktop()) {
432 return; 347 return;
433 } 348 }
434 349
435 float eyePointX = clamp(mEyePositionVector[0], -mHalfDesktopWidth, 350 float eyePointX = clamp(mEyePositionVector[0], -mDesktop.getHalfWidth(),
436 mHalfDesktopWidth); 351 mDesktop.getHalfWidth());
437 float eyePointY = clamp(mEyePositionVector[1], -HALF_DESKTOP_HEIGHT, 352 float eyePointY = clamp(mEyePositionVector[1], -mDesktop.getHalfHeight() ,
438 HALF_DESKTOP_HEIGHT); 353 mDesktop.getHalfHeight());
439 Matrix.setIdentityM(mEyePointModelMatrix, 0); 354 Matrix.setIdentityM(mEyePointModelMatrix, 0);
440 Matrix.translateM(mEyePointModelMatrix, 0, -eyePointX, -eyePointY, 355 Matrix.translateM(mEyePointModelMatrix, 0, -eyePointX, -eyePointY,
441 DESKTOP_POSITION_Z); 356 DESKTOP_POSITION_Z);
442 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mViewMatrix, 0, mEyePointM odelMatrix, 0); 357 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mViewMatrix, 0, mEyePointM odelMatrix, 0);
443 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mProjectionMatrix, 358 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mProjectionMatrix,
444 0, mEyePointCombinedMatrix, 0); 359 0, mEyePointCombinedMatrix, 0);
445 360
446 mEyePoint.setCombinedMatrix(mEyePointCombinedMatrix); 361 mEyePoint.setCombinedMatrix(mEyePointCombinedMatrix);
447 mEyePoint.draw(); 362 mEyePoint.draw();
448 } 363 }
(...skipping 21 matching lines...) Expand all
470 } 385 }
471 386
472 /** 387 /**
473 * Returns coordinates in units of pixels in the desktop bitmap. 388 * Returns coordinates in units of pixels in the desktop bitmap.
474 * This can be called on any thread. 389 * This can be called on any thread.
475 */ 390 */
476 public PointF getMouseCoordinates() { 391 public PointF getMouseCoordinates() {
477 PointF result = new PointF(); 392 PointF result = new PointF();
478 synchronized (mEyePositionLock) { 393 synchronized (mEyePositionLock) {
479 // Due to the coordinate direction, we only have to inverse x. 394 // Due to the coordinate direction, we only have to inverse x.
480 result.x = (-mEyePositionVector[0] + mHalfDesktopWidth) 395 result.x = (-mEyePositionVector[0] + mDesktop.getHalfWidth())
481 / (2 * mHalfDesktopWidth) * mDesktopWidthPixels; 396 / (2 * mDesktop.getHalfWidth()) * mDesktop.getWidthPixels();
482 result.y = (mEyePositionVector[1] + HALF_DESKTOP_HEIGHT) 397 result.y = (mEyePositionVector[1] + mDesktop.getHalfHeight())
483 / (2 * HALF_DESKTOP_HEIGHT) * mDesktopHeightPixels; 398 / (2 * mDesktop.getHalfHeight()) * mDesktop.getHeightPixels( );
484 result.x = clamp(result.x, 0, mDesktopWidthPixels); 399 result.x = clamp(result.x, 0, mDesktop.getWidthPixels());
485 result.y = clamp(result.y, 0, mDesktopHeightPixels); 400 result.y = clamp(result.y, 0, mDesktop.getHeightPixels());
486 } 401 }
487 return result; 402 return result;
488 } 403 }
489 404
490 /** 405 /**
491 * Returns the passed in value if it resides within the specified range (inc lusive). If not, 406 * Returns the passed in value if it resides within the specified range (inc lusive). If not,
492 * it will return the closest boundary from the range. The ordering of the boundary values 407 * it will return the closest boundary from the range. The ordering of the boundary values
493 * does not matter. 408 * does not matter.
494 * 409 *
495 * @param value The value to be compared against the range. 410 * @param value The value to be compared against the range.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 448 }
534 } 449 }
535 } 450 }
536 451
537 /** 452 /**
538 * Return true if user is looking at the desktop. 453 * Return true if user is looking at the desktop.
539 * This method can be called on any thread. 454 * This method can be called on any thread.
540 */ 455 */
541 public boolean isLookingAtDesktop() { 456 public boolean isLookingAtDesktop() {
542 synchronized (mEyePositionLock) { 457 synchronized (mEyePositionLock) {
543 return Math.abs(mEyePositionVector[0]) <= (mHalfDesktopWidth + EDGE_ MARGIN) 458 return Math.abs(mEyePositionVector[0]) <= (mDesktop.getHalfWidth() + EDGE_MARGIN)
544 && Math.abs(mEyePositionVector[1]) <= (HALF_DESKTOP_HEIGHT + EDG E_MARGIN); 459 && Math.abs(mEyePositionVector[1]) <= (mDesktop.getHalfHeight() + EDGE_MARGIN);
545 } 460 }
546 } 461 }
547 462
548 /** 463 /**
549 * Return true if user is looking at the space to the left of the desktop. 464 * Return true if user is looking at the space to the left of the desktop.
550 * This method can be called on any thread. 465 * This method can be called on any thread.
551 */ 466 */
552 public boolean isLookingLeftOfDesktop() { 467 public boolean isLookingLeftOfDesktop() {
553 synchronized (mEyePositionLock) { 468 synchronized (mEyePositionLock) {
554 return mEyePositionVector[0] >= (mHalfDesktopWidth + EDGE_MARGIN); 469 return mEyePositionVector[0] >= (mDesktop.getHalfWidth() + EDGE_MARG IN);
555 } 470 }
556 } 471 }
557 472
558 /** 473 /**
559 * Return true if user is looking at the space to the right of the desktop. 474 * Return true if user is looking at the space to the right of the desktop.
560 * This method can be called on any thread. 475 * This method can be called on any thread.
561 */ 476 */
562 public boolean isLookingRightOfDesktop() { 477 public boolean isLookingRightOfDesktop() {
563 synchronized (mEyePositionLock) { 478 synchronized (mEyePositionLock) {
564 return mEyePositionVector[0] <= -(mHalfDesktopWidth + EDGE_MARGIN); 479 return mEyePositionVector[0] <= -(mDesktop.getHalfWidth() + EDGE_MAR GIN);
565 } 480 }
566 } 481 }
567 482
568 /** 483 /**
569 * Return true if user is looking at the space above the desktop. 484 * Return true if user is looking at the space above the desktop.
570 * This method can be called on any thread. 485 * This method can be called on any thread.
571 */ 486 */
572 public boolean isLookingAboveDesktop() { 487 public boolean isLookingAboveDesktop() {
573 synchronized (mEyePositionLock) { 488 synchronized (mEyePositionLock) {
574 return mEyePositionVector[1] <= -(HALF_DESKTOP_HEIGHT + EDGE_MARGIN) ; 489 return mEyePositionVector[1] <= -(mDesktop.getHalfHeight() + EDGE_MA RGIN);
575 } 490 }
576 } 491 }
577 492
578 /** 493 /**
579 * Return true if user is looking at the space below the desktop. 494 * Return true if user is looking at the space below the desktop.
580 * This method can be called on any thread. 495 * This method can be called on any thread.
581 */ 496 */
582 public boolean isLookingBelowDesktop() { 497 public boolean isLookingBelowDesktop() {
583 synchronized (mEyePositionLock) { 498 synchronized (mEyePositionLock) {
584 return mEyePositionVector[1] >= (HALF_DESKTOP_HEIGHT + EDGE_MARGIN); 499 return mEyePositionVector[1] >= (mDesktop.getHalfHeight() + EDGE_MAR GIN);
585 } 500 }
586 } 501 }
587 502
588 /** 503 /**
589 * Get position on desktop where user is looking at. 504 * Get position on desktop where user is looking at.
590 */ 505 */
591 private void getLookingPosition() { 506 private void getLookingPosition() {
592 synchronized (mEyePositionLock) { 507 synchronized (mEyePositionLock) {
593 if (Math.abs(mForwardVector[2]) < 0.00001f) { 508 if (Math.abs(mForwardVector[2]) < 0.00001f) {
594 mEyePositionVector[0] = Math.signum(mForwardVector[0]) * Float.M AX_VALUE; 509 mEyePositionVector[0] = Math.signum(mForwardVector[0]) * Float.M AX_VALUE;
595 mEyePositionVector[1] = Math.signum(mForwardVector[1]) * Float.M AX_VALUE; 510 mEyePositionVector[1] = Math.signum(mForwardVector[1]) * Float.M AX_VALUE;
596 } else { 511 } else {
597 mEyePositionVector[0] = mForwardVector[0] * DESKTOP_POSITION_Z / mForwardVector[2]; 512 mEyePositionVector[0] = mForwardVector[0] * DESKTOP_POSITION_Z / mForwardVector[2];
598 mEyePositionVector[1] = mForwardVector[1] * DESKTOP_POSITION_Z / mForwardVector[2]; 513 mEyePositionVector[1] = mForwardVector[1] * DESKTOP_POSITION_Z / mForwardVector[2];
599 } 514 }
600 mEyePositionVector[2] = DESKTOP_POSITION_Z; 515 mEyePositionVector[2] = DESKTOP_POSITION_Z;
601 } 516 }
602 } 517 }
603 518
604 /** 519 /**
605 * Link desktop texture with textureDataHandle if {@link mReloadTexture} is true. 520 * Link desktop texture with {@link CardboardActivityDesktop} if {@link mRel oadTexture} is true.
606 * @param textureDataHandle the handle we want attach texture to 521 * @param textureDataHandle the handle we want attach texture to
607 */ 522 */
608 private void maybeLoadTexture(int textureDataHandle) { 523 private void maybeLoadDesktopTexture() {
609 synchronized (mReloadTextureLock) { 524 synchronized (mReloadTextureLock) {
610 if (!mReloadTexture) { 525 if (!mReloadTexture) {
611 return; 526 return;
612 } 527 }
613 } 528 }
614 529
615 // TODO(shichengfeng): Record the time desktop drawing takes. 530 // TODO(shichengfeng): Record the time desktop drawing takes.
616 Bitmap bitmap = JniInterface.getVideoFrame(); 531 Bitmap bitmap = JniInterface.getVideoFrame();
617 532
618 if (bitmap == null) { 533 if (bitmap == null) {
619 // This can happen if the client is connected, but a complete video frame has not yet 534 // This can happen if the client is connected, but a complete video frame has not yet
620 // been decoded. 535 // been decoded.
621 return; 536 return;
622 } 537 }
623 538
624 synchronized (mEyePositionLock) { 539 synchronized (mEyePositionLock) {
625 mDesktopHeightPixels = bitmap.getHeight(); 540 mDesktop.setImageFrame(bitmap);
626 mDesktopWidthPixels = bitmap.getWidth(); 541 mDesktop.updateFrameData();
627 } 542 }
628 543
629 updateDesktopCoordinatesBuffer(bitmap);
630 TextureHelper.linkTexture(textureDataHandle, bitmap);
631
632 synchronized (mReloadTextureLock) { 544 synchronized (mReloadTextureLock) {
633 mReloadTexture = false; 545 mReloadTexture = false;
634 } 546 }
635 } 547 }
636 548
637 /** 549 /**
638 * Convert float array to a FloatBuffer for use in OpenGL calls. 550 * Convert float array to a FloatBuffer for use in OpenGL calls.
639 */ 551 */
640 private static FloatBuffer makeFloatBuffer(float[] data) { 552 public static FloatBuffer makeFloatBuffer(float[] data) {
641 FloatBuffer result = ByteBuffer 553 FloatBuffer result = ByteBuffer
642 .allocateDirect(data.length * BYTE_PER_FLOAT) 554 .allocateDirect(data.length * BYTE_PER_FLOAT)
643 .order(ByteOrder.nativeOrder()).asFloatBuffer(); 555 .order(ByteOrder.nativeOrder()).asFloatBuffer();
644 result.put(data).position(0); 556 result.put(data).position(0);
645 return result; 557 return result;
646 } 558 }
647 559
648 /** 560 /**
649 * Update the desktop coordinates based on the new bitmap. Note here we fix the
650 * height of the desktop and vary width accordingly.
651 */
652 private void updateDesktopCoordinatesBuffer(Bitmap bitmap) {
653 int width = bitmap.getWidth();
654 int height = bitmap.getHeight();
655 float newHalfDesktopWidth = width * HALF_DESKTOP_HEIGHT / height;
656 if (Math.abs(mHalfDesktopWidth - newHalfDesktopWidth) > 0.0001) {
657 mHalfDesktopWidth = newHalfDesktopWidth;
658 mDesktopCoordinates = makeFloatBuffer(new float[] {
659 // Desktop model coordinates.
660 -mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f,
661 -mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
662 mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f,
663 -mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
664 mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
665 mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f
666 });
667 }
668 }
669
670 /**
671 * Decode all skybox images to Bitmap files and return them. 561 * Decode all skybox images to Bitmap files and return them.
672 * Only call this method when we have complete skybox images. 562 * Only call this method when we have complete skybox images.
673 * @throws DecodeFileException if BitmapFactory fails to decode file. 563 * @throws DecodeFileException if BitmapFactory fails to decode file.
674 */ 564 */
675 private Bitmap[] decodeSkyboxImages() throws DecodeFileException { 565 private Bitmap[] decodeSkyboxImages() throws DecodeFileException {
676 Bitmap[] result = new Bitmap[SKYBOX_IMAGE_NAMES.length]; 566 Bitmap[] result = new Bitmap[SKYBOX_IMAGE_NAMES.length];
677 String fileDirectory = mDownloadManager.getDownloadDirectory(); 567 String fileDirectory = mDownloadManager.getDownloadDirectory();
678 for (int i = 0; i < SKYBOX_IMAGE_NAMES.length; i++) { 568 for (int i = 0; i < SKYBOX_IMAGE_NAMES.length; i++) {
679 result[i] = BitmapFactory.decodeFile(fileDirectory + "/" + SKYBOX_IM AGE_NAMES[i]); 569 result[i] = BitmapFactory.decodeFile(fileDirectory + "/" + SKYBOX_IM AGE_NAMES[i]);
680 if (result[i] == null) { 570 if (result[i] == null) {
(...skipping 28 matching lines...) Expand all
709 image.recycle(); 599 image.recycle();
710 } 600 }
711 } 601 }
712 602
713 /** 603 /**
714 * Exception when BitmapFactory fails to decode file. 604 * Exception when BitmapFactory fails to decode file.
715 */ 605 */
716 private static class DecodeFileException extends Exception { 606 private static class DecodeFileException extends Exception {
717 } 607 }
718 } 608 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698