在2014年Google I / O会议上,Google推出了Cardboard VR查看器,这是一种由纸板制成的廉价设备,它使用镜片和用户的手机来提供对虚拟现实应用程序的简单访问。 两年后,Google宣布了计划通过销售一种带有控制器的更耐用的查看器,即Daydream View,来扩展该平台,该控制器遵循与将手机用作主要VR提供商的相同概念而构建。 为了开发更多支持该平台的应用,Google发布了适用于Android(标准SDK和NDK),iOS,Unity游戏引擎和Unreal游戏引擎的Cardboard SDK。
本教程是有关Android Cardboard和Daydream SDK的简短系列的第一篇。 在本系列中,我将向您展示如何使用某些SDK工具和预制视图向您的应用添加简单功能。 您可以通过多种方式将Cardboard SDK集成到用于游戏和多媒体的应用程序中!
我将重点介绍三个示例,这些示例将带您入门VR开发领域:一个Photosphere Viewer,一个360 Video Viewer和一个Daydream控制器的输入阅读器。 在本教程中,我们将重点关注Photosphere Viewer,并在后续课程中重新讨论其他两个主题。
下载Cardboard SDK并运行示例项目
与Android中的大多数库不同,Android Cardboard SDK在可以通过Gradle作为依赖项导入的远程存储库中未正式提供。 为了使用它,您将需要通过Git从GitHub将Android Cardboard SDK克隆到您的计算机。
git clone https://github.com/googlevr/gvr-android-sdk.git
下载SDK后,让我们开始运行预包装的示例之一。 在Android Studio启动屏幕上,选择导入项目 。 接下来,选择刚克隆的SDK的根文件夹,然后按OK 。

此时,您将可以访问Android Cardboard SDK中的所有库组件和示例。 您可以从Android Studio窗口顶部的模块下拉菜单中选择要在您的设备上运行的示例之一。 为确保一切正常,请选择samples-sdk-simplepanowidget ,然后单击绿色的“运行”箭头。

编译并安装了示例之后,您应该会看到有关Machu Picchu的信息屏幕,并带有一个在移动Android设备时围绕光球旋转的视图。

现在,您可以在设备上运行示例应用程序,让我们开始研究创建支持Cardboard的新Android应用程序。
创建全景查看器
首先创建一个新的Android项目,最低SDK版本为19(KitKat)。 在完成选择和创建应用模板之一的标准步骤之后,您需要将项目所需的库从Cardboard SDK 库目录复制到项目的根文件夹中。 对于此示例,复制以下文件夹: common , commonwidget和panowidget 。

库文件放置在正确位置后,打开项目的settings.gradle文件。 您将需要通过该文件将这些库模块添加到项目中。
include ':app', ":common", "commonwidget", "panowidget"
接下来,您将需要参考这些库在你的build.gradle文件中的下dependencies
节点,允许您访问预先制成的部件的纸板。 您还需要添加Google的Protocol Buffers JavaNano库 ,该库是代码生成和运行时库,可帮助管理Android设备的有限资源。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.0.0'
compile project(':common')
compile project(':commonwidget')
compile project(':panowidget')
compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'
}
设置依赖项后,打开项目的AndroidManifest.xml 。 在manifest
节点的文件顶部,您需要为Cardboard SDK添加INTERNET
和READ_EXTERNAL_STORAGE
权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在MainActivity
类的activity
节点内,将category
添加到CARDBOARD
查看器的intent-filter
器中。
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="com.google.intent.category.CARDBOARD" />
</intent-filter>
</activity>
现在设置过程已经完成,我们可以深入研究有趣的部分:代码。 该项目将从app / src / main / assets中读取光球图像,并将其放入VrPanoramaView
。 您可以通过标准的Android相机应用程序拍摄Photosphere图像,并将其放置在此目录中。 在此示例中,我将使用名为openspace.jpg的图像。

在“ Activity
的布局文件中,添加将在应用程序中使用的VrPanoramaView
。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="@+id/pano_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
接下来,打开MainActivity
类。 您将需要首先在onCreate(Bundle)
获得对VrPanoramaView
的引用,然后可以通过我们稍后定义的loadPhotoSphere()
帮助器方法将Bitmap
加载到其中。
private VrPanoramaView mVrPanoramaView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mVrPanoramaView = (VrPanoramaView) findViewById(R.id.pano_view);
loadPhotoSphere();
}
loadPhotoSphere()
从assets文件夹中检索我们的图像, VrPanoramaView
使用VrPanoramaView.Options
对象将其加载到VrPanoramaView.Options
。 值得注意的是,这些图像可能相对较大,因此此操作通常在后台线程上进行,尽管本课将为简化起见将所有内容保留在UI线程上。
private void loadPhotoSphere() {
//This could take a while. Should do on a background thread, but fine for current example
VrPanoramaView.Options options = new VrPanoramaView.Options();
InputStream inputStream = null;
AssetManager assetManager = getAssets();
try {
inputStream = assetManager.open("openspace.jpg");
options.inputType = VrPanoramaView.Options.TYPE_MONO;
mVrPanoramaView.loadImageFromBitmap(BitmapFactory.decodeStream(inputStream), options);
inputStream.close();
} catch (IOException e) {
Log.e("Tuts+", "Exception in loadPhotoSphere: " + e.getMessage() );
}
}
注意,对于VrPanoramaView.Options.inputType
值,我们使用的是TYPE_MONO
。 这意味着VrPanoramaView
期望显示单个通道图像,而inputType
为TYPE_STEREO_OVER_UNDER
期望图像将分别由右眼和左眼垂直分割,分别看到该图像的上半部分和下半部分。

您需要做的最后一件事是暂停并继续在onPause()
和onResume()
呈现VrPanoramaView
,以及在onDestroy()
正确断开连接。
@Override
protected void onPause() {
mVrPanoramaView.pauseRendering();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mVrPanoramaView.resumeRendering();
}
@Override
protected void onDestroy() {
mVrPanoramaView.shutdown();
super.onDestroy();
}
现在我们已经完成了应用程序的设置,让我们继续运行它。 您的应用程序应该在屏幕上显示光球,并且您应该能够四处移动手机以查看图像的不同部分。

如果按一下View
右下角的硬纸板图标,它将把图像分割为两个略有偏移的图像,可以通过Cardboard或Daydream查看器看到该图像。

尽管在本教程中未使用,但也值得注意的是VrPanoramaView
可以接受VrPanoramaEventListener
对象,该对象将在成功加载或失败新图像时通知您的应用程序。
结论
恭喜,您已经创建了自己的第一个纸板应用程序,即用于全景照片和全景照片的图像查看器! 尽管这是一个简化的示例,但确实为您提供了如何创建自己的应用程序以使用Cardboard Viewer的基础知识。 有关使该概念更进一步的应用程序的惊人示例,我强烈推荐Google的Expeditions教育应用程序。
我希望您喜欢将脚趾伸入VR世界。 在下一个教程中,我将向您展示如何通过Cardboard SDK播放360度视频文件。