从零开始学习开发虚拟现实 Android 应用程序
已发表: 2015-11-16本文将指导您如何从头开始开发虚拟现实 Android 应用程序,假设您已经了解 Android 应用程序开发的基础知识。
要求
- Android Studio 1.0 或更高版本
- Android SDK 第 19 版
- 运行 Android 16(Jelly Bean) 或更高版本的物理 Android 设备
清单文件
<清单... <uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.VIBRATE" /> ... <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19"/> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <应用程序 ... <活动 android:name=".MainActivity" 安卓:screenOrientation="风景"> ... <意图过滤器> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="com.google.intent.category.CARDBOARD" /> </intent-filter> </活动> </应用> </清单>
解释权限:
- <uses-sdk android:minSdkVersion=”16″/>表示设备必须运行 API Level 16 (Jellybean) 或更高版本。
- <uses-sdk android:targetSdkVersion=”19″/>表示我们的应用程序的目标是 API 级别 19 (KitKat)。
- <uses-feature android:glEsVersion=”0x00020000″ android:required=”true” />表示应用使用图形,因此必须支持OpenGL ES 2.0。
- android:screenOrientation=”landscape”表示activity需要的屏幕方向是“landscape”。 这是您必须为 VR 应用程序设置的方向。 Cardboard SDK 使用的视图 CardboardView 仅在全屏和横向(landscape、reverseLandscape、sensorLandscape)模式下呈现。
- 还建议设置 android:configChanges=”orientation|keyboardHidden” ,但不是强制性的。
- Cardboard SDK 需要android.permission.NFC权限才能访问 Cardboard 的 NFC 标签。
- android.permission.READ_EXTERNAL_STORAGE和android.permission.WRITE_EXTERNAL_STORAGE 。 Cardboard SDK 需要这些权限才能将用户的手机与其 VR 查看器配对。
- 我们的演示应用需要android.permission.VIBRATE权限,以使手机振动以通知用户发生了什么事。
- 意图过滤器,特别是com.google.intent.category.CARDBOARD声明此活动与类似 Cardboard 的查看器兼容。 Cardboard 应用程序使用此类别列出安装在用户手机上的兼容应用程序。
扩展纸板活动:
CardboardActivity 是编写纸板应用程序的起点。 CardboardActivity 是提供与 Cardboard 设备轻松集成的基础活动。 它公开事件以与 Cardboards 交互,并处理创建 VR 渲染活动时通常需要的许多细节。
注意 CardboardActivity 使用的是粘性沉浸模式,在这种模式下系统 UI 是隐藏的,内容占据了整个屏幕。 这是 VR 应用程序的要求,因为 CardboardView 只会在 Activity 处于全屏模式时呈现。
Android 4.4(API 级别 19)为 setSystemUiVisibility() 引入了一个新的 SYSTEM_UI_FLAG_IMMERSIVE 标志,让您的应用真正“全屏”运行。 此标志与 SYSTEM_UI_FLAG_HIDE_NAVIGATION 和 SYSTEM_UI_FLAG_FULLSCREEN 标志结合使用时,会隐藏导航栏和状态栏,并让您的应用程序捕获屏幕上的所有触摸事件。
定义一个 CardBoardView:
Android 应用程序中的所有用户界面元素都是使用视图构建的。 适用于 Android 的 Cardboard SDK 提供了自己的视图 CardboardView,它是 GLSurfaceView 的便捷扩展,可用于 VR 渲染。 CardboardView 以立体方式呈现内容。 您可以通过以下方式查看演示应用程序如何在其活动布局 xml 文件中定义 aCardboardView:
<com.google.vrtoolkit.cardboard.CardboardView 机器人:fill_parent” android:layout_height="fill_parent" />
然后在主活动类中,它在 onCreate() 方法中初始化 CardboardView:
** * 将视图设置为我们的 CardboardView 并初始化我们将使用的转换矩阵 * 渲染我们的场景。 * @param 已保存实例状态 */ @覆盖 公共无效 onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.common_ui); CardboardView cardboardView = (CardboardView) findViewById(R.id.cardboard_view); // 将 CardboardView.StereoRenderer 与 cardboardView 关联。 cardboardView.setRenderer(this); // 将 cardboardView 与此活动相关联。 设置纸板视图(纸板视图); // 这里初始化其他对象 …… }
渲染视图
获得 CardboardView 后,将其与渲染器相关联,然后将 CardboardView 与活动相关联。 Cardboard 支持两种渲染器,但最快的上手方式是使用演示应用程序使用的 CardboardView.StereoRenderer。
CardboardView.StereoRenderer 包括以下关键方法:
- onNewFrame(),每次应用呈现时调用。
- onDrawEye(),为每只眼睛调用不同的眼睛参数。
实现这些类似于您通常为 OpenGL 应用程序所做的。 这些方法将在以下部分中更详细地讨论。
实现 onNewFrame
在渲染单个眼睛之前,使用 onNewFrame() 方法对渲染逻辑进行编码。 任何不特定于单个视图的每帧操作都应该在这里发生。 这是更新模型的好地方。 在此代码段中,变量 mHeadView 包含头部的位置。 需要保存这个值以供以后使用,以判断用户是否在看宝藏:
/** * 在我们绘制帧之前准备好 OpenGL ES。 * @param headTransform 新帧中的头部变换。 */ @覆盖 公共无效onNewFrame(HeadTransform headTransform){ ... headTransform.getHeadView(mHeadView, 0); ... }
实现 onDrawEye
实现 onDrawEye() 来执行每只眼睛的配置。
这是渲染代码的核心,与构建常规 OpenGL ES2 应用程序非常相似。 以下片段显示了如何获取视图变换矩阵以及透视变换矩阵。 您需要确保以低延迟进行渲染。 Eye 对象包含眼睛的变换和投影矩阵。 这是事件的顺序:
- 宝物进入眼界。
- 我们应用投影矩阵。 这提供了为指定眼睛渲染的场景。
- Cardboard SDK 会自动应用失真来渲染最终场景。
/** *为眼睛画一个框架。 * * @param eye 要渲染的眼睛。 包括所有必需的转换。 */ @覆盖 公共无效onDrawEye(眼睛){ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); ... // 将眼睛变换应用于相机。 Matrix.multiplyMM(mView, 0, eye.getEyeView(), 0, mCamera, 0); // 设置灯光的位置 Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, LIGHT_POS_IN_WORLD_SPACE, 0); // 构建 ModelView 和 ModelViewProjection 矩阵 // 用于计算立方体位置和光照。 浮动[] 透视 = eye.getPerspective(Z_NEAR, Z_FAR); Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0); Matrix.multiplyMM(mModelViewProjection, 0, perspective, 0, mModelView, 0); 绘制立方体(); // 绘制场景的其余部分。 ... }
处理输入
Cardboard 查看器包括一个使用磁铁的按钮。 当您推动磁铁时,磁场会发生变化并被手机的磁力计检测到。 Cardboard SDK 会为您检测到这些磁铁事件。
要在用户拉动磁铁时提供自定义行为,请在应用的 Activity 中覆盖CardboardActivity.onCardboardTrigger()。 在寻宝应用中,如果你找到了宝藏并拉动磁铁,你就可以保留宝藏:
/** * 增加分数,隐藏对象,如果用户在拉动磁铁时给出反馈 * 看着物体。 否则,提醒用户做什么。 */ @覆盖 公共无效 onCardboardTrigger() { 如果(isLookingAtObject()){ 分数++; mOverlayView.show3DToast("找到了!四处寻找下一个。\nScore = " + mScore); ... } 别的 { mOverlayView.show3DToast("四处寻找对象!"); } // 总是给用户反馈 mVibrator.vibrate(50); }
开始你自己的项目
现在您已经对适用于 Android 的 Cardboard SDK 更加熟悉了,是时候创建自己的应用程序了。
无论是从头开始的新项目还是现有项目,这都是您应该做的。
1) 下载这两个 JAR 文件。 点击这里下载
2) 将其复制并粘贴到您的 app/libs 文件夹中(在 Android Studio 项目结构的项目视图中找到它)
3)右键单击库并选择“添加为库”
然后,确保项目的app/build.gradle文件中存在以下行:
依赖项 { ... 编译 fileTree(dir: 'libs', include: ['*.jar']) }
您已准备好开始虚拟现实应用程序开发!