Index: chrome/browser/android/vr_shell/vr_shell.cc |
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cbc58091fe6421241007f0f10fd073949453836f |
--- /dev/null |
+++ b/chrome/browser/android/vr_shell/vr_shell.cc |
@@ -0,0 +1,199 @@ |
+// Copyright 2016 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. |
+ |
+#include "chrome/browser/android/vr_shell/vr_shell.h" |
+ |
+#include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
+#include "chrome/browser/android/vr_shell/vr_util.h" |
+#include "jni/VrShell_jni.h" |
+#include "ui/gl/gl_bindings.h" |
+#include "ui/gl/init/gl_factory.h" |
+ |
+namespace vr_shell { |
+ |
+namespace { |
+// Constant taken from treasure_hunt demo. |
+const long kPredictionTimeWithoutVsyncNanos = 50000000; |
+ |
+const float kZNear = 0.1f; |
+const float kZFar = 1000.0f; |
+ |
+// Content rect in world coordinates. Height and width are currently supplied |
+// as DrawFrame arguments. |
+const gvr::Vec3f kContentRectPositionDefault = {0.0f, 0.0f, -1.0f}; |
+ |
+} // namespace |
+ |
+ContentRect::ContentRect() { |
+ SetIdentity(); |
+} |
+ |
+ContentRect::~ContentRect() {} |
+ |
+void ContentRect::SetIdentity() { |
+ transfrom_to_world.m[0][0] = 1; |
mthiesse1
2016/08/18 16:11:46
move this function to vr_util.h?
bshe
2016/08/18 17:15:43
I think we will need to replace these functions wi
|
+ transfrom_to_world.m[0][1] = 0; |
+ transfrom_to_world.m[0][2] = 0; |
+ transfrom_to_world.m[0][3] = 0; |
+ transfrom_to_world.m[1][0] = 0; |
+ transfrom_to_world.m[1][1] = 1; |
+ transfrom_to_world.m[1][2] = 0; |
+ transfrom_to_world.m[1][3] = 0; |
+ transfrom_to_world.m[2][0] = 0; |
+ transfrom_to_world.m[2][1] = 0; |
+ transfrom_to_world.m[2][2] = 1; |
+ transfrom_to_world.m[2][3] = 0; |
+ transfrom_to_world.m[3][0] = 0; |
+ transfrom_to_world.m[3][1] = 0; |
+ transfrom_to_world.m[3][2] = 0; |
+ transfrom_to_world.m[3][3] = 1; |
+} |
+ |
+void ContentRect::Translate(float x, float y, float z) { |
+ transfrom_to_world.m[0][3] += x; |
+ transfrom_to_world.m[1][3] += y; |
+ transfrom_to_world.m[2][3] += z; |
+} |
+ |
+VrShell::VrShell(JNIEnv* env, jobject obj) { |
+ j_vr_shell_.Reset(env, obj); |
+} |
+ |
+void VrShell::Destroy(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ delete this; |
+} |
+ |
+bool RegisterVrShell(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+VrShell::~VrShell() {} |
+ |
+void VrShell::GvrInit(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj, |
+ jlong native_gvr_api) { |
+ gvr_api_ = |
+ gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); |
+} |
+ |
+void VrShell::InitializeGl(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj, |
+ jint texture_data_handle) { |
+ gl::init::InitializeGLOneOff(); |
+ gvr_api_->InitializeGl(); |
+ std::vector<gvr::BufferSpec> specs; |
+ specs.push_back(gvr_api_->CreateBufferSpec()); |
+ render_size_ = specs[0].GetSize(); |
+ swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); |
+ content_rect_.reset(new ContentRect()); |
+ content_rect_->content_texture_handle = |
+ reinterpret_cast<int>(texture_data_handle); |
+ vr_shell_renderer_.reset(new VrShellRenderer()); |
+ buffer_viewport_list_.reset( |
+ new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
+ buffer_viewport_.reset( |
+ new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
+} |
+ |
+void VrShell::DrawFrame(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ buffer_viewport_list_->SetToRecommendedBufferViewports(); |
+ gvr::Frame frame = swap_chain_->AcquireFrame(); |
+ gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
+ target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
+ head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); |
+ |
+ // Content area positioning. |
+ content_rect_->SetIdentity(); |
+ content_rect_->Translate(kContentRectPositionDefault.x, |
+ kContentRectPositionDefault.y, |
+ kContentRectPositionDefault.z); |
+ |
+ gvr::Mat4f left_eye_view_matrix = |
+ MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE), head_pose_); |
+ gvr::Mat4f right_eye_view_matrix = |
+ MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE), head_pose_); |
+ |
+ // Bind back to the default framebuffer. |
+ frame.BindBuffer(0); |
+ |
+ // Use culling to remove back faces. |
+ glEnable(GL_CULL_FACE); |
+ |
+ // Enable depth testing. |
+ glEnable(GL_DEPTH_TEST); |
+ glEnable(GL_SCISSOR_TEST); |
+ |
+ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); |
+ |
+ // Enable transparency. |
+ glEnable(GL_BLEND); |
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
+ |
+ buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
+ buffer_viewport_.get()); |
+ DrawEye(left_eye_view_matrix, *buffer_viewport_); |
+ buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
+ buffer_viewport_.get()); |
+ DrawEye(right_eye_view_matrix, *buffer_viewport_); |
+ |
+ frame.Unbind(); |
+ frame.Submit(*buffer_viewport_list_, head_pose_); |
+} |
+ |
+void VrShell::DrawEye(const gvr::Mat4f& view_matrix, |
+ const gvr::BufferViewport& params) { |
+ gvr::Recti pixel_rect = |
+ CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); |
+ glViewport(pixel_rect.left, pixel_rect.bottom, |
+ pixel_rect.right - pixel_rect.left, |
+ pixel_rect.top - pixel_rect.bottom); |
+ glScissor(pixel_rect.left, pixel_rect.bottom, |
+ pixel_rect.right - pixel_rect.left, |
+ pixel_rect.top - pixel_rect.bottom); |
+ |
+ view_matrix_ = view_matrix; |
+ |
+ projection_matrix_ = |
+ PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar); |
+ |
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
+ DrawContentRect(); |
+} |
+ |
+void VrShell::DrawContentRect() { |
+ gvr::Mat4f content_rect_combined_matrix = |
+ MatrixMul(view_matrix_, content_rect_->transfrom_to_world); |
+ content_rect_combined_matrix = |
+ MatrixMul(projection_matrix_, content_rect_combined_matrix); |
+ vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( |
+ content_rect_->content_texture_handle, content_rect_combined_matrix); |
+} |
+ |
+void VrShell::OnPause(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ if (gvr_api_ == nullptr) |
+ return; |
+ gvr_api_->PauseTracking(); |
+} |
+ |
+void VrShell::OnResume(JNIEnv* env, |
+ const base::android::JavaParamRef<jobject>& obj) { |
+ if (gvr_api_ == nullptr) |
+ return; |
+ gvr_api_->RefreshViewerProfile(); |
+ gvr_api_->ResumeTracking(); |
+} |
+ |
+// ---------------------------------------------------------------------------- |
+// Native JNI methods |
+// ---------------------------------------------------------------------------- |
+ |
+jlong Init(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { |
+ VrShell* vrShell = new VrShell(env, obj); |
+ return reinterpret_cast<intptr_t>(vrShell); |
+} |
+ |
+} // namespace vr_shell |