├── .gitignore
├── README.md
├── apk
├── app-debug.apk
├── app-malivr-debug.apk
├── app-rajawali-debug.apk
└── app-vrwidget-debug.apk
├── app-malivr
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── cube.fs
│ ├── cube.vs
│ ├── distort.fs
│ └── distort.vs
│ ├── java
│ └── org
│ │ └── babysource
│ │ └── vrdroid
│ │ ├── VRDroid.java
│ │ └── VRDroidView.java
│ ├── jni
│ ├── armvr.cpp
│ ├── armvr.h
│ ├── loader.cpp
│ ├── main.cpp
│ └── matrix.h
│ └── res
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── app-rajawali
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── org
│ │ └── babysource
│ │ └── vrdroid
│ │ ├── VRDroidLister.java
│ │ ├── VRDroidPlayer.java
│ │ └── render
│ │ └── VRDroidRender.java
│ └── res
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── app-vrwidget
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── org
│ │ └── babysource
│ │ └── vrdroid
│ │ ├── VRDroidLister.java
│ │ └── VRDroidPlayer.java
│ └── res
│ ├── layout
│ ├── droid_item.xml
│ ├── droid_lister.xml
│ └── droid_player.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── org
│ │ └── babysource
│ │ └── vrdroid
│ │ ├── VRDroidBuilder.java
│ │ ├── VRDroidCamera.java
│ │ └── VRDroidCamera2.java
│ └── res
│ ├── layout
│ └── droid_lister.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── libraries
├── audio
│ ├── audio.aar
│ └── build.gradle
├── base
│ ├── base.aar
│ └── build.gradle
├── common
│ ├── build.gradle
│ └── common.aar
├── commonwidget
│ ├── build.gradle
│ └── commonwidget.aar
├── controller
│ ├── build.gradle
│ └── controller.aar
├── panowidget
│ ├── build.gradle
│ └── panowidget.aar
└── videowidget
│ ├── build.gradle
│ └── videowidget.aar
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Thumbs.db
3 | /.idea
4 | /bin
5 | /build
6 | /captures
7 | /local.properties
8 | .gradle
9 | *.iml
10 | *.ipr
11 | *.iws
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VRDroid
2 | VR Player for android
3 |
4 | # 项目简介
5 |
6 | VR相关探索研究项目,长期关注VR前沿动态,及时跟进最新VR开发技术;
7 |
8 | # 模块简介
9 |
10 | [app]
11 |
12 | VR摄像头偷窥APP;(实现通过Camera api v1 and v2)
13 |
14 | [app-malivr]:
15 |
16 | Malivr Demo;(适用于:An ARM based development board with a Mali series GPU running Android.)
17 |
18 | [app-rajawali]:
19 |
20 | Rajawali3D引擎实现VR 360°全景视频播放;
21 |
22 | [app-vrwidget]:
23 |
24 | GvrView v1.0.3实现VR 360°全景视频播放;
--------------------------------------------------------------------------------
/apk/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/apk/app-debug.apk
--------------------------------------------------------------------------------
/apk/app-malivr-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/apk/app-malivr-debug.apk
--------------------------------------------------------------------------------
/apk/app-rajawali-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/apk/app-rajawali-debug.apk
--------------------------------------------------------------------------------
/apk/app-vrwidget-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/apk/app-vrwidget-debug.apk
--------------------------------------------------------------------------------
/app-malivr/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app-malivr/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.model.application'
2 |
3 | model {
4 | android {
5 | compileSdkVersion = 23
6 | buildToolsVersion = '23.0.3'
7 |
8 | defaultConfig.with {
9 | applicationId = 'com.babysource.vrdroid.malivr'
10 | minSdkVersion.apiLevel = 16
11 | targetSdkVersion.apiLevel = 23
12 | }
13 | }
14 |
15 | android.ndk {
16 | platformVersion = '19'
17 | moduleName = 'Native'
18 | stl = 'stlport_static'
19 | abiFilters.add('armeabi-v7a')
20 | CFlags.add('-Werror')
21 | ldLibs.addAll(['log', 'GLESv3', 'EGL', 'm'])
22 | }
23 |
24 | android.sources {
25 | main {
26 | jni {
27 | source {
28 | exclude 'armvr.cpp'
29 | exclude 'loader.cpp'
30 | }
31 | }
32 | }
33 | }
34 |
35 | android.buildTypes {
36 | debug {
37 | debuggable = true
38 | minifyEnabled = false
39 | multiDexEnabled = false
40 | shrinkResources = false
41 | zipAlignEnabled = true
42 | }
43 | release {
44 | debuggable = false
45 | minifyEnabled = false
46 | multiDexEnabled = false
47 | shrinkResources = true
48 | zipAlignEnabled = true
49 | proguardFiles.add(file('proguard-rules.pro'))
50 | }
51 | }
52 |
53 | android.packagingOptions {
54 | exclude 'META-INF/DEPENDENCIES'
55 | exclude 'META-INF/LICENSE.txt'
56 | exclude 'META-INF/LICENSE'
57 | exclude 'META-INF/NOTICE.txt'
58 | exclude 'META-INF/NOTICE'
59 | }
60 |
61 | android.lintOptions {
62 | abortOnError = false
63 | }
64 | }
65 |
66 | dependencies {
67 | compile 'com.android.support:appcompat-v7:23.2.1'
68 | }
69 |
--------------------------------------------------------------------------------
/app-malivr/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\adt-bundle-windows-x86_64-20131030\Android_Studio_sdk\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app-malivr/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
20 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app-malivr/src/main/assets/cube.fs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | // This proprietary software may be used only as
3 | // authorised by a licensing agreement from ARM Limited
4 | // (C) COPYRIGHT 2015 ARM Limited
5 | // ALL RIGHTS RESERVED
6 | // The entire notice above must be reproduced on all authorised
7 | // copies and copies may only be made to the extent permitted
8 | // by a licensing agreement from ARM Limited.
9 | precision highp float;
10 |
11 | in vec3 v_position;
12 | in vec3 v_normal;
13 | in float v_depth;
14 | out vec4 f_color;
15 |
16 | vec3 light(vec3 n, vec3 l, vec3 c)
17 | {
18 | float ndotl = max(dot(n, l), 0.0);
19 | return ndotl * c;
20 | }
21 |
22 | void main()
23 | {
24 | vec3 albedo = vec3(0.95, 0.84, 0.62);
25 | vec3 n = normalize(v_normal);
26 | f_color.rgb = vec3(0.0);
27 | f_color.rgb += light(n, normalize(vec3(1.0)), vec3(1.0));
28 | f_color.rgb += light(n, normalize(vec3(-1.0, -1.0, 0.0)), vec3(0.2, 0.23, 0.35));
29 |
30 | // Fog
31 | f_color.rgb *= 1.0 - smoothstep(0.9, 10.0, v_depth);
32 |
33 | // Gamma
34 | f_color.rgb = sqrt(f_color.rgb);
35 |
36 | f_color.a = 1.0;
37 | }
38 |
--------------------------------------------------------------------------------
/app-malivr/src/main/assets/cube.vs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | #extension GL_OVR_multiview2 : enable
3 | // This proprietary software may be used only as
4 | // authorised by a licensing agreement from ARM Limited
5 | // (C) COPYRIGHT 2015 ARM Limited
6 | // ALL RIGHTS RESERVED
7 | // The entire notice above must be reproduced on all authorised
8 | // copies and copies may only be made to the extent permitted
9 | // by a licensing agreement from ARM Limited.
10 |
11 | layout(num_views = 4) in;
12 |
13 | in vec3 position;
14 | in vec3 normal;
15 | uniform mat4 projection[4];
16 | uniform mat4 view[4];
17 | uniform mat4 model;
18 | out float v_depth;
19 | out vec3 v_position;
20 | out vec3 v_normal;
21 |
22 | void main()
23 | {
24 | vec4 view_pos = view[gl_ViewID_OVR] * model * vec4(position, 1.0);
25 | gl_Position = projection[gl_ViewID_OVR] * view_pos;
26 | v_normal = (view[gl_ViewID_OVR] * model * vec4(normal, 0.0)).xyz;
27 | v_depth = -view_pos.z;
28 | v_position = position;
29 | }
30 |
--------------------------------------------------------------------------------
/app-malivr/src/main/assets/distort.fs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | // This proprietary software may be used only as
3 | // authorised by a licensing agreement from ARM Limited
4 | // (C) COPYRIGHT 2015 ARM Limited
5 | // ALL RIGHTS RESERVED
6 | // The entire notice above must be reproduced on all authorised
7 | // copies and copies may only be made to the extent permitted
8 | // by a licensing agreement from ARM Limited.
9 | precision highp float;
10 | precision mediump int;
11 | precision mediump sampler2DArray;
12 |
13 | in vec2 texel_r_low_res;
14 | in vec2 texel_g_low_res;
15 | in vec2 texel_b_low_res;
16 | in vec2 texel_r_high_res;
17 | in vec2 texel_g_high_res;
18 | in vec2 texel_b_high_res;
19 | uniform sampler2DArray framebuffer;
20 | uniform int layer_index;
21 | out vec4 f_color;
22 |
23 | vec3 sample_per_channel(vec2 tex_coord_r, vec2 tex_coord_g, vec2 tex_coord_b, int layer)
24 | {
25 | vec3 sampled_color;
26 | sampled_color.r = texture(framebuffer, vec3(tex_coord_r, layer)).r;
27 | sampled_color.g = texture(framebuffer, vec3(tex_coord_g, layer)).g;
28 | sampled_color.b = texture(framebuffer, vec3(tex_coord_b, layer)).b;
29 |
30 | return sampled_color;
31 | }
32 |
33 | float interpolate_color(vec2 tex_coord, float low_res_color_val, float high_res_color_val)
34 | {
35 | // Using squared distance to middle of screen for interpolating.
36 | vec2 dist_vec = vec2(0.5) - tex_coord;
37 | float squared_dist = dot(dist_vec, dist_vec);
38 | // Using the high res texture when distance from center is less than 0.5 in texture coordinates (0.25 is 0.5 squared).
39 | // When the distance is less than 0.2 (0.04 is 0.2 squared), only the high res texture will be used.
40 | float lerp_val = smoothstep(-0.25, -0.4, -squared_dist);
41 | return mix(low_res_color_val, high_res_color_val, lerp_val);
42 | }
43 |
44 | void main()
45 | {
46 | vec3 low_res_color = sample_per_channel(texel_r_low_res, texel_g_low_res, texel_b_low_res, layer_index);
47 | vec3 high_res_color = sample_per_channel(texel_r_high_res, texel_g_high_res, texel_b_high_res, layer_index + 2);
48 |
49 | f_color.r = interpolate_color(texel_r_high_res, low_res_color.r, high_res_color.r);
50 | f_color.g = interpolate_color(texel_g_high_res, low_res_color.g, high_res_color.g);
51 | f_color.b = interpolate_color(texel_b_high_res, low_res_color.b, high_res_color.b);
52 | f_color.a = 1.0;
53 | }
54 |
--------------------------------------------------------------------------------
/app-malivr/src/main/assets/distort.vs:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | // This proprietary software may be used only as
3 | // authorised by a licensing agreement from ARM Limited
4 | // (C) COPYRIGHT 2015 ARM Limited
5 | // ALL RIGHTS RESERVED
6 | // The entire notice above must be reproduced on all authorised
7 | // copies and copies may only be made to the extent permitted
8 | // by a licensing agreement from ARM Limited.
9 |
10 | in vec2 position;
11 | in vec2 uv_red_low_res;
12 | in vec2 uv_green_low_res;
13 | in vec2 uv_blue_low_res;
14 | in vec2 uv_red_high_res;
15 | in vec2 uv_green_high_res;
16 | in vec2 uv_blue_high_res;
17 | out vec2 texel_r_low_res;
18 | out vec2 texel_g_low_res;
19 | out vec2 texel_b_low_res;
20 | out vec2 texel_r_high_res;
21 | out vec2 texel_g_high_res;
22 | out vec2 texel_b_high_res;
23 |
24 | void main()
25 | {
26 | gl_Position = vec4(position, 0.0, 1.0);
27 | texel_r_low_res = uv_red_low_res;
28 | texel_g_low_res = uv_green_low_res;
29 | texel_b_low_res = uv_blue_low_res;
30 | texel_r_high_res = uv_red_high_res;
31 | texel_g_high_res = uv_green_high_res;
32 | texel_b_high_res = uv_blue_high_res;
33 | }
34 |
--------------------------------------------------------------------------------
/app-malivr/src/main/java/org/babysource/vrdroid/VRDroid.java:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | package org.babysource.vrdroid;
9 |
10 | import android.content.res.AssetManager;
11 | import android.app.Activity;
12 | import android.os.Bundle;
13 | import android.util.Log;
14 |
15 | import java.io.File;
16 | import java.io.InputStream;
17 | import java.io.RandomAccessFile;
18 |
19 | public class VRDroid extends Activity {
20 |
21 | VRDroidView mView;
22 | private static android.content.Context applicationContext = null;
23 | private static String assetsDirectory = null;
24 | private static String LOGTAG = "VRDroid";
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | mView = new VRDroidView(getApplication());
30 | setContentView(mView);
31 |
32 | applicationContext = getApplicationContext();
33 | assetsDirectory = applicationContext.getFilesDir().getPath() + "/";
34 |
35 | extractAsset("distort.vs");
36 | extractAsset("distort.fs");
37 |
38 | extractAsset("cube.vs");
39 | extractAsset("cube.fs");
40 | }
41 |
42 | @Override
43 | protected void onPause() {
44 | super.onPause();
45 | mView.onPause();
46 | }
47 |
48 | @Override
49 | protected void onResume() {
50 | super.onResume();
51 | mView.onResume();
52 | }
53 |
54 | private void extractAsset(String assetName) {
55 | File file = new File(assetsDirectory + assetName);
56 |
57 | if (file.exists()) {
58 | Log.d(LOGTAG, assetName + " already exists. No extraction needed.\n");
59 | } else {
60 | Log.d(LOGTAG, assetName + " doesn't exist. Extraction needed. \n");
61 |
62 | try {
63 | RandomAccessFile randomAccessFile = new RandomAccessFile(assetsDirectory + assetName, "rw");
64 | AssetManager assetManager = applicationContext.getResources().getAssets();
65 | InputStream inputStream = assetManager.open(assetName);
66 |
67 | byte buffer[] = new byte[1024];
68 | int count = inputStream.read(buffer, 0, 1024);
69 |
70 | while (count > 0) {
71 | randomAccessFile.write(buffer, 0, count);
72 |
73 | count = inputStream.read(buffer, 0, 1024);
74 | }
75 |
76 | randomAccessFile.close();
77 | inputStream.close();
78 | } catch (Exception e) {
79 | Log.e(LOGTAG, "Failure in extractAssets(): " + e.toString() + " " + assetsDirectory + assetName);
80 | }
81 |
82 | if (file.exists()) {
83 | Log.d(LOGTAG, "File extracted successfully");
84 | }
85 | }
86 | }
87 |
88 | public static native void init();
89 |
90 | public static native void resize(int width, int height);
91 |
92 | public static native void step();
93 |
94 | static {
95 | System.loadLibrary("Native");
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/app-malivr/src/main/java/org/babysource/vrdroid/VRDroidView.java:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | package org.babysource.vrdroid;
9 |
10 | import android.content.Context;
11 | import android.opengl.GLSurfaceView;
12 |
13 | import javax.microedition.khronos.egl.EGLConfig;
14 | import javax.microedition.khronos.opengles.GL10;
15 |
16 | class VRDroidView extends GLSurfaceView {
17 |
18 | public VRDroidView(Context context) {
19 | super(context);
20 | setEGLConfigChooser(8, 8, 8, 0, 16, 0);
21 | setEGLContextClientVersion(2);
22 | setRenderer(new Renderer());
23 | }
24 |
25 | private static class Renderer implements GLSurfaceView.Renderer {
26 | public void onDrawFrame(GL10 gl) {
27 | VRDroid.step();
28 | }
29 |
30 | public void onSurfaceChanged(GL10 gl, int width, int height) {
31 | VRDroid.resize(width, height);
32 | }
33 |
34 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
35 | VRDroid.init();
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app-malivr/src/main/jni/armvr.cpp:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | #include "armvr.h"
9 |
10 | // These are the dimensions of the viewports (in pixels) used
11 | // when rendering each eye's framebuffer.
12 | #define View_Resolution_X (Screen_Resolution_X / 2)
13 | #define View_Resolution_Y Screen_Resolution_Y
14 |
15 | // These are used to ensure that the distortion appears
16 | // circular, even when the quad is stretched across a
17 | // non-square region of the device. Furthermore, we use
18 | // them to fit the resulting distorted image such that
19 | // the rendered scene fully fits into the viewport.
20 | #define View_Aspect_Ratio ((float)View_Resolution_X / (float)View_Resolution_Y)
21 | #define Eye_Fb_Aspect_Ratio ((float)Eye_Fb_Resolution_X / (float)Eye_Fb_Resolution_Y)
22 |
23 | // The near-clipping plane does not need to be equal to the
24 | // projection plane (the hmd). It can be set larger as long
25 | // as you can ensure that no geometry gets clipped (since
26 | // that is really jarring for users).
27 | #define Z_Near (Eye_Display_Distance)
28 | #define Z_Far Meter(12.0f)
29 |
30 | // Instead of recomputing the distortion per frame, we store
31 | // the distorted texel lookup coordinates in the attributes of
32 | // a tessellated quad. The coordinates are linearly interpolated
33 | // between each vertex. This gives acceptable results given a
34 | // high enough resolution of the mesh, even though the distortion
35 | // equations are nonlinear.
36 | #define Warp_Mesh_Resolution_X 64
37 | #define Warp_Mesh_Resolution_Y 64
38 |
39 | #include
40 | #include
41 |
42 | typedef void (GL_APIENTRY* PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);
43 | typedef void (GL_APIENTRY* PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR) (GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei);
44 |
45 | Framebuffer make_eye_framebuffer(int width, int height, int num_views)
46 | {
47 | Framebuffer result = {};
48 | result.width = width;
49 | result.height = height;
50 |
51 | PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR glFramebufferTextureMultiviewOVR =
52 | (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)eglGetProcAddress ("glFramebufferTextureMultiviewOVR");
53 | PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR glFramebufferTextureMultisampleMultiviewOVR =
54 | (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR)eglGetProcAddress ("glFramebufferTextureMultisampleMultiviewOVR");
55 |
56 | if (!glFramebufferTextureMultiviewOVR)
57 | {
58 | LOGE("Did not have glFramebufferTextureMultiviewOVR\n");
59 | exit(EXIT_FAILURE);
60 | }
61 | if (!glFramebufferTextureMultisampleMultiviewOVR)
62 | {
63 | LOGE("Did not have glFramebufferTextureMultisampleMultiviewOVR\n");
64 | }
65 |
66 | bool have_multisampled_ext = glFramebufferTextureMultisampleMultiviewOVR != 0;
67 |
68 | GL_CHECK(glGenFramebuffers(1, &result.framebuffer));
69 | GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, result.framebuffer));
70 |
71 | GL_CHECK(glGenTextures(1, &result.depthbuffer));
72 | GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, result.depthbuffer));
73 | GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, width, height, num_views));
74 |
75 | if (have_multisampled_ext)
76 | {
77 | GL_CHECK(glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, result.depthbuffer, 0, Multisample_Samples, 0, num_views));
78 | }
79 | else
80 | {
81 | GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, result.depthbuffer, 0, 0, num_views));
82 | }
83 |
84 | GL_CHECK(glGenTextures(1, &result.colorbuffer));
85 | GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, result.colorbuffer));
86 | GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, num_views));
87 | GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
88 | GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
89 | GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_EXT));
90 | GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_EXT));
91 | GLint border_color[4] = {0, 0, 0, 0};
92 | GL_CHECK(glTexParameteriv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR_EXT, border_color));
93 | GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, 0));
94 |
95 | if (have_multisampled_ext)
96 | {
97 | GL_CHECK(glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, result.colorbuffer, 0, Multisample_Samples, 0, num_views));
98 | }
99 | else
100 | {
101 | GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, result.colorbuffer, 0, 0, num_views));
102 | }
103 |
104 | GLenum status = GL_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER));
105 | if (status != GL_FRAMEBUFFER_COMPLETE)
106 | LOGE("Framebuffer not complete\n");
107 | GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
108 |
109 | return result;
110 | }
111 |
112 | GLuint make_cube()
113 | {
114 | float v[] = {
115 | // front
116 | -1.0f, -1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
117 | +1.0f, -1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
118 | +1.0f, +1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
119 | +1.0f, +1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
120 | -1.0f, +1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
121 | -1.0f, -1.0f, +1.0f, 0.0f, 0.0f, +1.0f,
122 |
123 | // back
124 | -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
125 | -1.0f, +1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
126 | +1.0f, +1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
127 | +1.0f, +1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
128 | +1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
129 | -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,
130 |
131 | // left
132 | -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
133 | -1.0f, -1.0f, +1.0f, -1.0f, 0.0f, 0.0f,
134 | -1.0f, +1.0f, +1.0f, -1.0f, 0.0f, 0.0f,
135 | -1.0f, +1.0f, +1.0f, -1.0f, 0.0f, 0.0f,
136 | -1.0f, +1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
137 | -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
138 |
139 | // right
140 | +1.0f, -1.0f, -1.0f, +1.0f, 0.0f, 0.0f,
141 | +1.0f, +1.0f, -1.0f, +1.0f, 0.0f, 0.0f,
142 | +1.0f, +1.0f, +1.0f, +1.0f, 0.0f, 0.0f,
143 | +1.0f, +1.0f, +1.0f, +1.0f, 0.0f, 0.0f,
144 | +1.0f, -1.0f, +1.0f, +1.0f, 0.0f, 0.0f,
145 | +1.0f, -1.0f, -1.0f, +1.0f, 0.0f, 0.0f,
146 |
147 | // up
148 | -1.0f, +1.0f, -1.0f, 0.0f, +1.0f, 0.0f,
149 | -1.0f, +1.0f, +1.0f, 0.0f, +1.0f, 0.0f,
150 | +1.0f, +1.0f, +1.0f, 0.0f, +1.0f, 0.0f,
151 | +1.0f, +1.0f, +1.0f, 0.0f, +1.0f, 0.0f,
152 | +1.0f, +1.0f, -1.0f, 0.0f, +1.0f, 0.0f,
153 | -1.0f, +1.0f, -1.0f, 0.0f, +1.0f, 0.0f,
154 |
155 | // down
156 | -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,
157 | +1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,
158 | +1.0f, -1.0f, +1.0f, 0.0f, -1.0f, 0.0f,
159 | +1.0f, -1.0f, +1.0f, 0.0f, -1.0f, 0.0f,
160 | -1.0f, -1.0f, +1.0f, 0.0f, -1.0f, 0.0f,
161 | -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f
162 | };
163 |
164 | GLuint result = 0;
165 | GL_CHECK(glGenBuffers(1, &result));
166 | GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, result));
167 | GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW));
168 | return result;
169 | }
170 |
171 | // Computes the distorted texel coordinate given the
172 | // position on the image plane.
173 | vec2 compute_distortion(float x, float y,
174 | vec2 distort_centre,
175 | DistortionCoefficients coefficients,
176 | float tex_coord_factor)
177 | {
178 | float k1 = coefficients.k1;
179 | float k2 = coefficients.k2;
180 | float k3 = coefficients.k3;
181 | float p1 = coefficients.p1;
182 | float p2 = coefficients.p2;
183 |
184 | // We need to correct for aspect ratio to ensure that
185 | // the distortion appears circular on the device.
186 | y /= View_Aspect_Ratio;
187 |
188 | float dx = x - distort_centre.x;
189 | float dy = y - distort_centre.y;
190 | float r2 = dx * dx + dy * dy;
191 | float r4 = r2 * r2;
192 | float r6 = r4 * r2;
193 |
194 | float radial_x = x * (k1 * r2 + k2 * r4 + k3 * r6);
195 | float radial_y = y * (k1 * r2 + k2 * r4 + k3 * r6);
196 |
197 | float tangential_x = p1 * (r2 + 2.0f*x*x) + 2.0f*p2*x*y;
198 | float tangential_y = p2 * (r2 + 2.0f*y*y) + 2.0f*p1*x*y;
199 |
200 | float distorted_x = x + radial_x + tangential_x;
201 | float distorted_y = y + radial_y + tangential_y;
202 |
203 | float result_x = 0.5f + tex_coord_factor * distorted_x;
204 | float result_y = 0.5f + tex_coord_factor * distorted_y * View_Aspect_Ratio;
205 |
206 | return vec2(result_x, result_y);
207 | }
208 |
209 | GLuint make_warp_mesh(LensConfig config)
210 | {
211 | struct Vertex
212 | {
213 | vec2 position;
214 | vec2 uv_red_low_res;
215 | vec2 uv_green_low_res;
216 | vec2 uv_blue_low_res;
217 | vec2 uv_red_high_res;
218 | vec2 uv_green_high_res;
219 | vec2 uv_blue_high_res;
220 | };
221 | static Vertex v[(Warp_Mesh_Resolution_X + 1) * (Warp_Mesh_Resolution_Y + 1)];
222 |
223 | // Compute vertices
224 | int vi = 0;
225 | for (int yi = 0; yi <= Warp_Mesh_Resolution_Y; yi++)
226 | for (int xi = 0; xi <= Warp_Mesh_Resolution_X; xi++)
227 | {
228 | float x = -1.0f + 2.0f * xi / Warp_Mesh_Resolution_X;
229 | float y = -1.0f + 2.0f * yi / Warp_Mesh_Resolution_Y;
230 | v[vi].position = vec2(x, y) * config.fill_scale + config.image_centre;
231 | v[vi].uv_red_low_res = compute_distortion(x, y, config.distort_centre, config.coefficients_red, 0.5f);
232 | v[vi].uv_green_low_res = compute_distortion(x, y, config.distort_centre, config.coefficients_green, 0.5f);
233 | v[vi].uv_blue_low_res = compute_distortion(x, y, config.distort_centre, config.coefficients_blue, 0.5f);
234 | // The texture coordinates for the higher resolution texture go from -0.5 to 1.5 so
235 | // that only the center of the screen samples the high resolution texture.
236 | v[vi].uv_red_high_res = compute_distortion(x, y, config.distort_centre, config.coefficients_red, 1.0f);
237 | v[vi].uv_green_high_res = compute_distortion(x, y, config.distort_centre, config.coefficients_green, 1.0f);
238 | v[vi].uv_blue_high_res = compute_distortion(x, y, config.distort_centre, config.coefficients_blue, 1.0f);
239 | vi++;
240 | }
241 |
242 | // Generate faces from vertices
243 | static Vertex f[Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6];
244 | int fi = 0;
245 | for (int yi = 0; yi < Warp_Mesh_Resolution_Y; yi++)
246 | for (int xi = 0; xi < Warp_Mesh_Resolution_X; xi++)
247 | {
248 | Vertex v0 = v[(yi ) * (Warp_Mesh_Resolution_X + 1) + xi ];
249 | Vertex v1 = v[(yi ) * (Warp_Mesh_Resolution_X + 1) + xi + 1];
250 | Vertex v2 = v[(yi + 1) * (Warp_Mesh_Resolution_X + 1) + xi + 1];
251 | Vertex v3 = v[(yi + 1) * (Warp_Mesh_Resolution_X + 1) + xi ];
252 | f[fi++] = v0;
253 | f[fi++] = v1;
254 | f[fi++] = v2;
255 | f[fi++] = v2;
256 | f[fi++] = v3;
257 | f[fi++] = v0;
258 | }
259 |
260 | GLuint result = 0;
261 | GL_CHECK(glGenBuffers(1, &result));
262 | GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, result));
263 | GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(f), f, GL_STATIC_DRAW));
264 | return result;
265 | }
266 |
267 | // This computes a general frustum given four field-of-view (FOV)
268 | // angles and the near and far clipping planes. The FOV angle is
269 | // defined as the angle between the optical axis (i.e. the eye's
270 | // forward direction) and the line from the eye to the respective
271 | // edge of the screen.
272 | mat4 make_frustum(float left_fov,
273 | float right_fov,
274 | float bottom_fov,
275 | float top_fov,
276 | float z_near,
277 | float z_far)
278 | {
279 | mat4 result(0.0f);
280 | float tt = tan(top_fov);
281 | float tb = tan(bottom_fov);
282 | float tl = tan(left_fov);
283 | float tr = tan(right_fov);
284 | result.x.x = 2.0f / (tl + tr);
285 | result.y.y = 2.0f / (tt + tb);
286 | result.z.x = (tl - tr) / (tl + tr);
287 | result.z.y = (tt - tb) / (tt + tb);
288 | result.z.z = (z_near + z_far) / (z_near - z_far);
289 | result.w.w = -1.0f;
290 | result.w.z = 2.0f * z_near * z_far / (z_near - z_far);
291 | return result;
292 | }
293 |
294 | // This computes a general frustum given the distance
295 | // from the viewer's eye to the display, and the corners
296 | // of that eye's screen half relative to the eye.
297 | // z_near and z_far decide the near and far clipping planes.
298 | mat4 make_frustum_screen_viewer(float eye_display_distance,
299 | float left,
300 | float right,
301 | float bottom,
302 | float top,
303 | float z_near,
304 | float z_far)
305 | {
306 | mat4 result(0.0f);
307 | result.x.x = 2.0f * eye_display_distance / (right - left);
308 | result.y.y = 2.0f * eye_display_distance / (top - bottom);
309 | result.z.x = (right + left) / (right - left);
310 | result.z.y = (top + bottom) / (top - bottom);
311 | result.z.z = (z_near + z_far) / (z_near - z_far);
312 | result.z.w = -1.0f;
313 | result.w.z = 2.0f * z_near * z_far / (z_near - z_far);
314 | return result;
315 | }
316 |
317 | void app_initialize(App *app)
318 | {
319 | // Make sure the required extensions are present.
320 | const GLubyte* extensions = glGetString(GL_EXTENSIONS);
321 | char * found_multiview2_extension = strstr ((const char*)extensions, "GL_OVR_multiview2");
322 | char * found_multisample_multiview_extension = strstr ((const char*)extensions, "GL_OVR_multiview_multisampled_render_to_texture");
323 | char * found_border_clamp_extension = strstr ((const char*)extensions, "GL_EXT_texture_border_clamp");
324 |
325 | if (found_multiview2_extension == NULL)
326 | {
327 | LOGI("OpenGL ES 3.0 implementation does not support GL_OVR_multiview2 extension.\n");
328 | exit(EXIT_FAILURE);
329 | }
330 |
331 | if (found_multisample_multiview_extension == NULL)
332 | {
333 | // If multisampled multiview is not supported, multisampling will not be used, so no need to exit here.
334 | LOGI("OpenGL ES 3.0 implementation does not support GL_OVR_multiview_multisampled_render_to_texture extension.\n");
335 | }
336 |
337 | if (found_border_clamp_extension == NULL)
338 | {
339 | LOGI("OpenGL ES 3.0 implementation does not support GL_EXT_texture_border_clamp extension.\n");
340 | exit(EXIT_FAILURE);
341 | }
342 |
343 | GL_CHECK(glGenVertexArrays(1, &app->vao));
344 | GL_CHECK(glBindVertexArray(app->vao));
345 | GL_CHECK(glViewport(0, 0, app->window_width, app->window_height));
346 |
347 | app->vbo_cube = make_cube();
348 |
349 | app->fb = make_eye_framebuffer(Eye_Fb_Resolution_X, Eye_Fb_Resolution_Y, Num_Views);
350 |
351 | // The coefficients below may be calibrated by photographing an
352 | // image containing straight lines, both vertical and horizontal,
353 | // through the lenses of the HMD, at the position where the viewer
354 | // would be looking through them.
355 |
356 | // Ideally, the user would be allowed to calibrate them for their
357 | // own eyes, through some calibration utility. The application should
358 | // then load a stored user-profile on runtime. For now, we hardcode
359 | // some values based on our calibration of the SM-R320 Gear VR
360 | // lenses.
361 |
362 | // Left lens
363 | app->hmd.left.coefficients_red.k1 = 0.19f;
364 | app->hmd.left.coefficients_red.k2 = 0.21f;
365 | app->hmd.left.coefficients_red.k3 = 0.0f;
366 | app->hmd.left.coefficients_red.p1 = 0.0f;
367 | app->hmd.left.coefficients_red.p2 = 0.0f;
368 | app->hmd.left.coefficients_green.k1 = 0.22f;
369 | app->hmd.left.coefficients_green.k2 = 0.24f;
370 | app->hmd.left.coefficients_green.k3 = 0.0f;
371 | app->hmd.left.coefficients_green.p1 = 0.0f;
372 | app->hmd.left.coefficients_green.p2 = 0.0f;
373 | app->hmd.left.coefficients_blue.k1 = 0.24f;
374 | app->hmd.left.coefficients_blue.k2 = 0.26f;
375 | app->hmd.left.coefficients_blue.k3 = 0.0f;
376 | app->hmd.left.coefficients_blue.p1 = 0.0f;
377 | app->hmd.left.coefficients_blue.p2 = 0.0f;
378 |
379 | // Right lens
380 | app->hmd.right.coefficients_red.k1 = 0.19f;
381 | app->hmd.right.coefficients_red.k2 = 0.21f;
382 | app->hmd.right.coefficients_red.k3 = 0.0f;
383 | app->hmd.right.coefficients_red.p1 = 0.0f;
384 | app->hmd.right.coefficients_red.p2 = 0.0f;
385 | app->hmd.right.coefficients_green.k1 = 0.22f;
386 | app->hmd.right.coefficients_green.k2 = 0.24f;
387 | app->hmd.right.coefficients_green.k3 = 0.0f;
388 | app->hmd.right.coefficients_green.p1 = 0.0f;
389 | app->hmd.right.coefficients_green.p2 = 0.0f;
390 | app->hmd.right.coefficients_blue.k1 = 0.24f;
391 | app->hmd.right.coefficients_blue.k2 = 0.26f;
392 | app->hmd.right.coefficients_blue.k3 = 0.0f;
393 | app->hmd.right.coefficients_blue.p1 = 0.0f;
394 | app->hmd.right.coefficients_blue.p2 = 0.0f;
395 |
396 | // These may be computed by measuring the distance between the top
397 | // of the unscaled distorted image and the top of the screen. Denote
398 | // this distance by Delta. The normalized view coordinate of the
399 | // distorted image top is
400 | // Y = 1 - 2 Delta / Screen_Size_Y
401 | // We want to scale this coordinate such that it maps to the top of
402 | // the view. That is,
403 | // Y * fill_scale = 1
404 | // Solving for fill_scale gives the equations below.
405 | float delta = Centimeter(0.7f);
406 | app->hmd.left.fill_scale = 1.0f / (1.0f - 2.0f * delta / Screen_Size_Y);
407 | app->hmd.right.fill_scale = 1.0f / (1.0f - 2.0f * delta / Screen_Size_Y);
408 |
409 | // These are computed such that the centers of the displayed framebuffers
410 | // on the device are seperated by the viewer's IPD.
411 | app->hmd.left.image_centre = vec2(+1.0f - Eye_IPD / (Screen_Size_X / 2.0f), 0.0f);
412 | app->hmd.right.image_centre = vec2(-1.0f + Eye_IPD / (Screen_Size_X / 2.0f), 0.0f);
413 |
414 | // These are computed such that the distortion takes place around
415 | // an offset determined by the difference between lens seperation
416 | // and the viewer's eye IPD. If the difference is zero, the distortion
417 | // takes place around the image centre.
418 | app->hmd.left.distort_centre = vec2((Lens_IPD - Eye_IPD) / (Screen_Size_X / 2.0f), 0.0f);
419 | app->hmd.right.distort_centre = vec2((Eye_IPD - Lens_IPD) / (Screen_Size_X / 2.0f), 0.0f);
420 |
421 | app->warp_mesh[0] = make_warp_mesh(app->hmd.left);
422 | app->warp_mesh[1] = make_warp_mesh(app->hmd.right);
423 |
424 | get_attrib_location( distort, position);
425 | get_attrib_location( distort, uv_red_low_res);
426 | get_attrib_location( distort, uv_green_low_res);
427 | get_attrib_location( distort, uv_blue_low_res);
428 | get_attrib_location( distort, uv_red_high_res);
429 | get_attrib_location( distort, uv_green_high_res);
430 | get_attrib_location( distort, uv_blue_high_res);
431 | get_uniform_location(distort, layer_index);
432 | get_uniform_location(distort, framebuffer);
433 |
434 | get_attrib_location (cube, position);
435 | get_attrib_location (cube, normal);
436 | get_uniform_location(cube, projection);
437 | get_uniform_location(cube, view);
438 | get_uniform_location(cube, model);
439 | }
440 |
441 | void draw_scene(App *app)
442 | {
443 | int n = 5;
444 | for (int zi = 0; zi <= n; zi++)
445 | for (int xi = 0; xi <= n; xi++)
446 | {
447 | float x = Centimeter(-100.0f) + 2.0f * Centimeter(100.0f * xi / n);
448 | float z = Centimeter(-100.0f * zi);
449 | int i = zi * n + xi;
450 | mat4 mat_model = translate(x, 0.0f, z) *
451 | scale(Centimeter(5.0f)) *
452 | rotateY(0.3f * app->elapsed_time + i * 1.57f) *
453 | rotateX(0.2f * app->elapsed_time + i * 3.2f);
454 | uniformm4(cube, model, mat_model);
455 | GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 36));
456 | }
457 |
458 | mat4 mat_model = translate(0.0f, Centimeter(70.0f), Centimeter(400.0f)) *
459 | scale(Centimeter(5.0f)) *
460 | rotateY(0.3f * app->elapsed_time) *
461 | rotateX(0.05f * app->elapsed_time);
462 | uniformm4(cube, model, mat_model);
463 | GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 36));
464 | }
465 |
466 | void app_update_and_render(App *app)
467 | {
468 | GL_CHECK(glEnable(GL_DEPTH_TEST));
469 | GL_CHECK(glDepthFunc(GL_LEQUAL));
470 | GL_CHECK(glDepthMask(GL_TRUE));
471 | GL_CHECK(glDepthRangef(0.0, 1.0));
472 |
473 | GL_CHECK(glClearDepthf(1.0f));
474 | GL_CHECK(glClearColor(0.15f, 0.17f, 0.2f, 1.0f));
475 |
476 | ////////////////////////////
477 | // Cube shader
478 |
479 | GL_CHECK(glUseProgram(app->program_cube));
480 | GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube));
481 | attribfv(cube, position, 3, 6, 0);
482 | attribfv(cube, normal, 3, 6, 3);
483 |
484 | float camera_z = Centimeter(500.0f);
485 | float camera_y = Centimeter(70.0f);
486 |
487 | mat4 mat_view[Num_Views];
488 | mat_view[0] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z);
489 | mat_view[1] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z);
490 | mat_view[2] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z);
491 | mat_view[3] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z);
492 |
493 | // The scene is rendered twice for each eye position, once with a wide field of view, and
494 | // once with a narrower field of view in order to render the midpoint of the screen with
495 | // a higher resolution than the rest.
496 | mat4 mat_projection[Num_Views];
497 | mat_projection[0] = make_frustum_screen_viewer(
498 | Eye_Display_Distance,
499 | -(Screen_Size_X - Eye_IPD) / 2.0f,
500 | +(Eye_IPD / 2.0f),
501 | -Screen_Size_Y / 2.0f,
502 | +Screen_Size_Y / 2.0f,
503 | Z_Near, Z_Far);
504 | mat_projection[1] = make_frustum_screen_viewer(
505 | Eye_Display_Distance,
506 | -(Eye_IPD / 2.0f),
507 | +(Screen_Size_X - Eye_IPD) / 2.0f,
508 | -Screen_Size_Y / 2.0f,
509 | +Screen_Size_Y / 2.0f,
510 | Z_Near, Z_Far);
511 |
512 | float right_midpoint = -((Screen_Size_X/4.0f) - (Eye_IPD / 2.0f));
513 | float left_midpoint = (Screen_Size_X/4.0f) - (Eye_IPD / 2.0f);
514 | mat_projection[2] = make_frustum_screen_viewer(
515 | Eye_Display_Distance,
516 | right_midpoint - (Screen_Size_X/8.0f),
517 | right_midpoint + (Screen_Size_X/8.0f),
518 | -Screen_Size_Y / 4.0f,
519 | +Screen_Size_Y / 4.0f,
520 | Z_Near, Z_Far);
521 | mat_projection[3] = make_frustum_screen_viewer(
522 | Eye_Display_Distance,
523 | left_midpoint - (Screen_Size_X/8.0f),
524 | left_midpoint + (Screen_Size_X/8.0f),
525 | -Screen_Size_Y / 4.0f,
526 | +Screen_Size_Y / 4.0f,
527 | Z_Near, Z_Far);
528 |
529 | GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, app->fb.framebuffer));
530 | GL_CHECK(glViewport(0, 0, app->fb.width, app->fb.height));
531 | GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
532 | uniformm4array(cube, projection, mat_projection[0], Num_Views);
533 | uniformm4array(cube, view, mat_view[0], Num_Views);
534 | draw_scene(app);
535 |
536 | ////////////////////////////
537 | // Distortion shader
538 |
539 | GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
540 |
541 | GL_CHECK(glDisable(GL_DEPTH_TEST));
542 | GL_CHECK(glDepthMask(GL_FALSE));
543 | GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
544 | GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
545 |
546 | GL_CHECK(glUseProgram(app->program_distort));
547 | GL_CHECK(glActiveTexture(GL_TEXTURE0));
548 | uniform1i(distort, framebuffer, 0);
549 |
550 | // Left eye
551 | GL_CHECK(glViewport(0, 0, View_Resolution_X, View_Resolution_Y));
552 | GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, app->fb.colorbuffer));
553 | uniform1i(distort, layer_index, 0);
554 | GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[0]));
555 | attribfv(distort, position, 2, 14, 0);
556 | attribfv(distort, uv_red_low_res, 2, 14, 2);
557 | attribfv(distort, uv_green_low_res, 2, 14, 4);
558 | attribfv(distort, uv_blue_low_res, 2, 14, 6);
559 | attribfv(distort, uv_red_high_res, 2, 14, 8);
560 | attribfv(distort, uv_green_high_res, 2, 14, 10);
561 | attribfv(distort, uv_blue_high_res, 2, 14, 12);
562 | GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6));
563 |
564 | // Right eye
565 | GL_CHECK(glViewport(View_Resolution_X, 0, View_Resolution_X, View_Resolution_Y));
566 | uniform1i(distort, layer_index, 1);
567 | GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[1]));
568 | attribfv(distort, position, 2, 14, 0);
569 | attribfv(distort, uv_red_low_res, 2, 14, 2);
570 | attribfv(distort, uv_green_low_res, 2, 14, 4);
571 | attribfv(distort, uv_blue_low_res, 2, 14, 6);
572 | attribfv(distort, uv_red_high_res, 2, 14, 8);
573 | attribfv(distort, uv_green_high_res, 2, 14, 10);
574 | attribfv(distort, uv_blue_high_res, 2, 14, 12);
575 | GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6));
576 | }
577 |
--------------------------------------------------------------------------------
/app-malivr/src/main/jni/armvr.h:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | #ifndef _armvr_h_
9 | #define _armvr_h_
10 | #include
11 | #include "matrix.h"
12 | #define Meter(x) (x)
13 | #define Centimeter(x) (Meter(x) / 100.0f)
14 | #define Millimeter(x) (Meter(x) / 1000.0f)
15 |
16 | // The following compile-time constants are used to calibrate the
17 | // VR experience for each device and each user. For the optimal
18 | // experience, you will need to perform measurements on your own
19 | // device, head-mounted-display and eyes. The default values are
20 | // calibrated for a Samsung Note 4 for a Gear VR SM-R320 HMD.
21 |
22 | #define Num_Eyes 2
23 | #define Num_Views Num_Eyes * 2
24 |
25 | // The dimensions of the device screen in pixels and meters.
26 | #define Screen_Resolution_X 2560
27 | #define Screen_Resolution_Y 1440
28 | #define Screen_Size_X Meter(0.125f)
29 | #define Screen_Size_Y Meter(0.072f)
30 |
31 | // The dimensions of the framebuffers used for both eyes when
32 | // rendering the scene. The values for these will balance visual
33 | // quality and performance. The framebuffers will be scaled down
34 | // or up to fit inside the viewports.
35 | #define Eye_Fb_Resolution_X 1280
36 | #define Eye_Fb_Resolution_Y 1440
37 |
38 | // If multisampling is available on the device the framebuffers
39 | // will be rendered to using multisampling.
40 | #define Multisample_Samples 4
41 |
42 | // The interpupillary distance (IPD) is the distance between
43 | // your pupils when looking straight ahead. The human average
44 | // is about 64mm, which is the same as the distance between the
45 | // lenses of the Gear VR headset. The user should set these to
46 | // their own measured IPD for the most comfortable experience.
47 | #define Eye_IPD Millimeter(61.0f)
48 |
49 | // This should be set equal to the distance between the lens
50 | // centres in the head-mounted display.
51 | #define Lens_IPD Millimeter(64.0f)
52 |
53 | // This should be set equal to the distance between the display
54 | // and the center point of the viewer's eye.
55 | #define Eye_Display_Distance Centimeter(8.0f)
56 |
57 | // Defining border color enums in case the headers are not up to date for using the android extension pack.
58 | #ifndef GL_TEXTURE_BORDER_COLOR_EXT
59 | #define GL_TEXTURE_BORDER_COLOR_EXT 0x1004
60 | #endif
61 |
62 | #ifndef GL_CLAMP_TO_BORDER_EXT
63 | #define GL_CLAMP_TO_BORDER_EXT 0x812D
64 | #endif
65 |
66 | struct Framebuffer
67 | {
68 | int width;
69 | int height;
70 | GLuint framebuffer;
71 | GLuint depthbuffer;
72 | GLuint colorbuffer;
73 | };
74 |
75 | // These coefficients control the degree of distortion that
76 | // is applied on the rendertargets, per channel. The notation
77 | // is the same as in the original Brown-Conray distortion
78 | // correction model.
79 | struct DistortionCoefficients
80 | {
81 | // Radial distortion coefficients
82 | float k1; // Central
83 | float k2; // Edge
84 | float k3; // Fine
85 |
86 | // Tangential distortion coefficients
87 | float p1; // Horizontal
88 | float p2; // Vertical
89 | };
90 |
91 | struct LensConfig
92 | {
93 | // One set for each channel, to handle chromatic aberration.
94 | DistortionCoefficients coefficients_red;
95 | DistortionCoefficients coefficients_green;
96 | DistortionCoefficients coefficients_blue;
97 |
98 | // The viewer may not look through the lens centre. This means
99 | // that we need to perform an asymmetrical barrel distortion,
100 | // centered at an offset given by the difference between the
101 | // viewer's eye seperation and the HMD lens seperation.
102 | vec2 distort_centre;
103 |
104 | // Each eye should be looking at the centre of each produced
105 | // framebuffer image. To do this we must shift the result of
106 | // each framebuffer by an appropriate amount, such that when
107 | // the viewer looks straight ahead, the left pupil is in the
108 | // centre of the left image and the right pupil vice versa.
109 | vec2 image_centre;
110 |
111 | // The distorted image will appear smaller on the screen,
112 | // depending on the values of the distortion coefficients.
113 | // We apply a shape-preserving upscale to make the distorted
114 | // image fit into the edges of the screen. The value of this
115 | // scale is somewhat arbitrarily chosen.
116 | float fill_scale;
117 | };
118 |
119 | struct HMDConfig
120 | {
121 | LensConfig left;
122 | LensConfig right;
123 | };
124 |
125 | struct WarpMesh
126 | {
127 | GLuint vbo;
128 | GLuint ibo;
129 | int index_count;
130 | };
131 |
132 | struct App
133 | {
134 | int window_width;
135 | int window_height;
136 | float frame_time;
137 | float elapsed_time;
138 |
139 | // Distortion shader
140 | GLuint program_distort;
141 | GLuint a_distort_position;
142 | GLuint a_distort_uv_red_low_res;
143 | GLuint a_distort_uv_green_low_res;
144 | GLuint a_distort_uv_blue_low_res;
145 | GLuint a_distort_uv_red_high_res;
146 | GLuint a_distort_uv_green_high_res;
147 | GLuint a_distort_uv_blue_high_res;
148 | GLuint u_distort_layer_index;
149 | GLuint u_distort_framebuffer;
150 |
151 | // Cube shader
152 | GLuint program_cube;
153 | GLuint a_cube_position;
154 | GLuint a_cube_normal;
155 | GLuint u_cube_projection;
156 | GLuint u_cube_view;
157 | GLuint u_cube_model;
158 |
159 | // Geometry
160 | GLuint vao;
161 | GLuint vbo_cube;
162 | GLuint warp_mesh[Num_Eyes];
163 |
164 | HMDConfig hmd;
165 | Framebuffer fb;
166 | };
167 |
168 | void gl_check(const char *msg);
169 | void app_initialize(App *app);
170 | void app_update_and_render(App *app);
171 |
172 | /////////////////////////////////////
173 | // Convenience macros
174 |
175 | #define GL_CHECK(x) \
176 | x; \
177 | { \
178 | GLenum glError = glGetError(); \
179 | if(glError != GL_NO_ERROR) { \
180 | LOGE("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
181 | exit(1); \
182 | } \
183 | }
184 |
185 | #define get_attrib_location(prog, name) \
186 | app->a_##prog##_##name = GL_CHECK(glGetAttribLocation(app->program_##prog, #name)); \
187 | if (app->a_##prog##_##name < 0) { \
188 | LOGE("Invalid or unused attribute %s\n", #name); \
189 | }
190 |
191 | #define get_uniform_location(prog, name) \
192 | app->u_##prog##_##name = GL_CHECK(glGetUniformLocation(app->program_##prog, #name)); \
193 | if (app->u_##prog##_##name < 0) { \
194 | LOGE("Invalid or unused uniform %s\n", #name); \
195 | }
196 |
197 | #define attribfv(prog, name, n, stride, offset) \
198 | GL_CHECK(glEnableVertexAttribArray(app->a_##prog##_##name)); \
199 | GL_CHECK(glVertexAttribPointer(app->a_##prog##_##name, n, GL_FLOAT, GL_FALSE, \
200 | stride * sizeof(GLfloat), (void*)(offset * sizeof(GLfloat))));
201 |
202 | #define attribiv(prog, name, n, stride, offset) \
203 | GL_CHECK(glEnableVertexAttribArray(app->a_##prog##_##name)); \
204 | GL_CHECK(glVertexAttribPointer(app->a_##prog##_##name, n, GL_INT, GL_FALSE, \
205 | stride * sizeof(GLint), (void*)(offset * sizeof(GLint)) ));
206 |
207 | #define uniform1f(prog, name, value) GL_CHECK(glUniform1f(app->u_##prog##_##name, value));
208 | #define uniform2f(prog, name, x, y) GL_CHECK(glUniform2f(app->u_##prog##_##name, x, y));
209 | #define uniform2fv(prog, name, value) GL_CHECK(glUniform2fv(app->u_##prog##_##name, 1, &value[0]));
210 | #define uniform3fv(prog, name, value) GL_CHECK(glUniform3fv(app->u_##prog##_##name, 1, &value[0]));
211 | #define uniform1i(prog, name, value) GL_CHECK(glUniform1i(app->u_##prog##_##name, value));
212 | #define uniformm4(prog, name, value) GL_CHECK(glUniformMatrix4fv(app->u_##prog##_##name, 1, GL_FALSE, value.value_ptr()));
213 | #define uniformm4array(prog, name, value, arraySize) GL_CHECK(glUniformMatrix4fv(app->u_##prog##_##name, arraySize, GL_FALSE, value.value_ptr()));
214 |
215 | #endif
216 |
--------------------------------------------------------------------------------
/app-malivr/src/main/jni/loader.cpp:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 |
9 | char *read_file(const char *filename)
10 | {
11 | FILE *file = fopen(filename, "rb");
12 | if (!file)
13 | {
14 | LOGE("Failed to open file %s\n", filename);
15 | exit (1);
16 | }
17 | fseek(file, 0, SEEK_END);
18 | long length = ftell(file);
19 | fseek(file, 0, SEEK_SET);
20 | char *data = (char *)calloc(length + 1, sizeof(char));
21 | if (!data)
22 | {
23 | LOGE("Failed to allocate memory for file data %s\n", filename);
24 | exit(1);
25 | }
26 | size_t read = fread(data, sizeof(char), length, file);
27 | if (read != length)
28 | {
29 | LOGE("Failed to read whole file %s\n", filename);
30 | exit(1);
31 | }
32 | data[length] = '\0';
33 | fclose(file);
34 | return data;
35 | }
36 |
37 | GLuint compile_shader(const char *source, GLenum type)
38 | {
39 | GLuint result = glCreateShader(type);
40 | glShaderSource(result, 1, (const GLchar**)&source, NULL);
41 | glCompileShader(result);
42 | GLint status;
43 | glGetShaderiv(result, GL_COMPILE_STATUS, &status);
44 | if (status == GL_FALSE) {
45 | GLint length;
46 | glGetShaderiv(result, GL_INFO_LOG_LENGTH, &length);
47 | GLchar *info = new GLchar[length];
48 | glGetShaderInfoLog(result, length, NULL, info);
49 | LOGE("[COMPILE] %s\n", info);
50 | delete[] info;
51 | exit(1);
52 | }
53 | return result;
54 | }
55 |
56 | GLuint link_program(GLuint *shaders, int count)
57 | {
58 | GLuint program = glCreateProgram();
59 | for (int i = 0; i < count; ++i)
60 | glAttachShader(program, shaders[i]);
61 |
62 | glLinkProgram(program);
63 |
64 | for (int i = 0; i < count; ++i)
65 | glDetachShader(program, shaders[i]);
66 |
67 | GLint status;
68 | glGetProgramiv(program, GL_LINK_STATUS, &status);
69 | if (status == GL_FALSE) {
70 | GLint length;
71 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
72 | GLchar *info = new GLchar[length];
73 | glGetProgramInfoLog(program, length, NULL, info);
74 | LOGE("[LINK] %s\n", info);
75 | delete[] info;
76 | exit(1);
77 | }
78 | return program;
79 | }
80 |
81 | void load_cube_shader(App *app)
82 | {
83 | char *vs_src = read_file(SHADER_PATH("cube.vs"));
84 | char *fs_src = read_file(SHADER_PATH("cube.fs"));
85 |
86 | GLuint shaders[2];
87 | shaders[0] = compile_shader(vs_src, GL_VERTEX_SHADER);
88 | shaders[1] = compile_shader(fs_src, GL_FRAGMENT_SHADER);
89 | app->program_cube = link_program(shaders, 2);
90 |
91 | free(vs_src);
92 | free(fs_src);
93 | }
94 |
95 | void load_distort_shader(App *app)
96 | {
97 | char *vs_src = read_file(SHADER_PATH("distort.vs"));
98 | char *fs_src = read_file(SHADER_PATH("distort.fs"));
99 |
100 | GLuint shaders[2];
101 | shaders[0] = compile_shader(vs_src, GL_VERTEX_SHADER);
102 | shaders[1] = compile_shader(fs_src, GL_FRAGMENT_SHADER);
103 | app->program_distort = link_program(shaders, 2);
104 |
105 | free(vs_src);
106 | free(fs_src);
107 | }
108 |
109 | void load_assets(App *app)
110 | {
111 | load_distort_shader(app);
112 | load_cube_shader(app);
113 | }
114 |
--------------------------------------------------------------------------------
/app-malivr/src/main/jni/main.cpp:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 | #define LOG_TAG "ARMVR"
14 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
15 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
16 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
17 |
18 | #include
19 | #include "armvr.cpp"
20 |
21 | #define BASE_ASSET_PATH "/data/data/com.arm.malideveloper.vrsdk.armvr/files/"
22 | #define SHADER_PATH(name) BASE_ASSET_PATH name
23 | #include "loader.cpp"
24 |
25 | #include
26 | static timeval start_time;
27 | static App app;
28 |
29 | const char *get_gl_error_msg(GLenum code)
30 | {
31 | switch (code)
32 | {
33 | case 0: return "NO_ERROR";
34 | case 0x0500: return "INVALID_ENUM";
35 | case 0x0501: return "INVALID_VALUE";
36 | case 0x0502: return "INVALID_OPERATION";
37 | case 0x0503: return "STACK_OVERFLOW";
38 | case 0x0504: return "STACK_UNDERFLOW";
39 | case 0x0505: return "OUT_OF_MEMORY";
40 | case 0x0506: return "INVALID_FRAMEBUFFER_OPERATION";
41 | default: return "UNKNOWN";
42 | }
43 | }
44 |
45 | void gl_check()
46 | {
47 | GLenum error = glGetError();
48 | if (error != GL_NO_ERROR)
49 | {
50 | LOGD("An OpenGL error occurred %s", get_gl_error_msg(error));
51 | exit(1);
52 | }
53 | }
54 |
55 | extern "C"
56 | {
57 | JNIEXPORT void JNICALL Java_org_babysource_vrdroid_VRDroid_init(JNIEnv* env, jobject obj)
58 | {
59 | LOGD("Init\n");
60 | start_time.tv_sec = 0;
61 | start_time.tv_usec = 0;
62 | gettimeofday(&start_time, NULL);
63 |
64 | LOGD("Load assets\n");
65 | load_assets(&app);
66 | app_initialize(&app);
67 | }
68 |
69 | JNIEXPORT void JNICALL Java_org_babysource_vrdroid_VRDroid_resize(JNIEnv* env, jobject obj, jint width, jint height)
70 | {
71 | app.window_width = width;
72 | app.window_height = height;
73 | app.elapsed_time = 0.0f;
74 | glViewport(0, 0, width, height);
75 | LOGD("Resizing %d %d\n", width, height);
76 | }
77 |
78 | JNIEXPORT void JNICALL Java_org_babysource_vrdroid_VRDroid_step(JNIEnv* env, jobject obj)
79 | {
80 | timeval now;
81 | gettimeofday(&now, NULL);
82 | float seconds = (now.tv_sec - start_time.tv_sec);
83 | float milliseconds = (float(now.tv_usec - start_time.tv_usec)) / 1000000.0f;
84 | float elapsed_time = seconds + milliseconds;
85 | app.frame_time = elapsed_time - app.elapsed_time;
86 | app.elapsed_time = elapsed_time;
87 |
88 | app_update_and_render(&app);
89 | gl_check();
90 | }
91 | };
92 |
--------------------------------------------------------------------------------
/app-malivr/src/main/jni/matrix.h:
--------------------------------------------------------------------------------
1 | // This proprietary software may be used only as
2 | // authorised by a licensing agreement from ARM Limited
3 | // (C) COPYRIGHT 2015 ARM Limited
4 | // ALL RIGHTS RESERVED
5 | // The entire notice above must be reproduced on all authorised
6 | // copies and copies may only be made to the extent permitted
7 | // by a licensing agreement from ARM Limited.
8 | #ifndef MATRIX_H
9 | #define MATRIX_H
10 | #ifndef PI
11 | #define PI 3.141592653f
12 | #endif
13 | #include
14 |
15 | struct vec2
16 | {
17 | float x;
18 | float y;
19 |
20 | vec2() : x(0.0f), y(0.0f) { }
21 | vec2(float X, float Y) : x(X), y(Y){ }
22 | explicit vec2(float S) : x(S), y(S) { }
23 | vec2 operator + (const vec2 &rhs) const { return vec2(x + rhs.x, y + rhs.y); }
24 | vec2 operator * (const vec2 &rhs) const { return vec2(x * rhs.x, y * rhs.y); }
25 | vec2 operator - (const vec2 &rhs) const { return vec2(x - rhs.x, y - rhs.y); }
26 | vec2 operator * (const float s) const { return vec2(x * s, y * s); }
27 | vec2 operator / (const float s) const { return vec2(x / s, y / s); }
28 |
29 | vec2 &operator *= (const float s) { *this = *this * s; return *this; }
30 | vec2 &operator += (const vec2 &rhs) { *this = *this + rhs; return *this; }
31 | vec2 &operator *= (const vec2 &rhs) { *this = *this * rhs; return *this; }
32 | vec2 &operator -= (const vec2 &rhs) { *this = *this - rhs; return *this; }
33 |
34 | float &operator [] (unsigned int i) { return (&x)[i]; }
35 | const float &operator [] (unsigned int i) const { return (&x)[i]; }
36 | };
37 |
38 | struct vec3
39 | {
40 | float x;
41 | float y;
42 | float z;
43 |
44 | vec3() : x(0.0f), y(0.0f), z(0.0f) { }
45 | vec3(float X, float Y, float Z) : x(X), y(Y), z(Z) { }
46 | explicit vec3(float S) : x(S), y(S), z(S) { }
47 | vec3 operator - () const { return vec3(-x, -y, -z); }
48 | vec3 operator + (const vec3 &rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
49 | vec3 operator * (const vec3 &rhs) const { return vec3(x * rhs.x, y * rhs.y, z * rhs.z); }
50 | vec3 operator - (const vec3 &rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
51 | vec3 operator * (const float s) const { return vec3(x * s, y * s, z * s); }
52 | vec3 operator / (const float s) const { return vec3(x / s, y / s, z / s); }
53 |
54 | vec3 &operator += (const vec3 &rhs) { *this = *this + rhs; return *this; }
55 | vec3 &operator *= (const vec3 &rhs) { *this = *this * rhs; return *this; }
56 | vec3 &operator -= (const vec3 &rhs) { *this = *this - rhs; return *this; }
57 |
58 | float &operator [] (unsigned int i) { return (&x)[i]; }
59 | const float &operator [] (unsigned int i) const { return (&x)[i]; }
60 | };
61 |
62 | struct vec4
63 | {
64 | float x;
65 | float y;
66 | float z;
67 | float w;
68 |
69 | vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
70 | vec4(vec3 V, float W) : x(V.x), y(V.y), z(V.z), w(W) { }
71 | vec4(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { }
72 | explicit vec4(float S) : x(S), y(S), z(S), w(S) { }
73 | vec4 operator - () const { return vec4(-x, -y, -z, -w); }
74 | vec4 operator + (const vec4 &rhs) const { return vec4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); }
75 | vec4 operator * (const vec4 &rhs) const { return vec4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w); }
76 | vec4 operator - (const vec4 &rhs) const { return vec4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); }
77 | vec4 operator * (const float s) const { return vec4(x * s, y * s, z * s, w * s); }
78 | vec4 operator / (const float s) const { return vec4(x / s, y / s, z / s, w / s); }
79 |
80 | vec4 &operator *= (const float s) { *this = *this * s; return *this; }
81 | vec4 &operator += (const vec4 &rhs) { *this = *this + rhs; return *this; }
82 | vec4 &operator *= (const vec4 &rhs) { *this = *this * rhs; return *this; }
83 | vec4 &operator -= (const vec4 &rhs) { *this = *this - rhs; return *this; }
84 |
85 | float &operator [] (unsigned int i) { return (&x)[i]; }
86 | const float &operator [] (unsigned int i) const { return (&x)[i]; }
87 |
88 | vec3 xyz() const { return vec3(x, y, z); }
89 | };
90 |
91 | struct mat4
92 | {
93 | vec4 x, y, z, w; // columns
94 |
95 | mat4() { }
96 | explicit mat4(float s) : x(0.0f), y(0.0f), z(0.0f), w(0.0f)
97 | {
98 | x.x = s;
99 | y.y = s;
100 | z.z = s;
101 | w.w = s;
102 | }
103 |
104 | mat4 operator * (const mat4 &rhs)
105 | {
106 | mat4 m;
107 | for (int lrow = 0; lrow < 4; ++lrow)
108 | {
109 | for (int rcol = 0; rcol < 4; ++rcol)
110 | {
111 | m[rcol][lrow] = 0.0f;
112 | for (int k = 0; k < 4; ++k)
113 | {
114 | m[rcol][lrow] += (*this)[k][lrow] * rhs[rcol][k];
115 | }
116 | }
117 | }
118 | return m;
119 | }
120 |
121 | mat4 operator * (const float s)
122 | {
123 | mat4 m = *this;
124 | m.x *= s;
125 | m.y *= s;
126 | m.z *= s;
127 | m.w *= s;
128 | return m;
129 | }
130 |
131 | vec4 operator * (const vec4 &rhs)
132 | {
133 | return x * rhs.x + y * rhs.y + z * rhs.z + w * rhs.w;
134 | }
135 |
136 | vec4 &operator [] (unsigned int i) { return (&x)[i]; }
137 | const vec4 &operator [] (unsigned int i) const { return (&x)[i]; }
138 | const float *value_ptr() const { return &(x[0]); }
139 | float *value_ptr() { return &(x[0]); }
140 | };
141 |
142 | static vec3 normalize(const vec3 &v)
143 | {
144 | return v / sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
145 | }
146 |
147 | static mat4 transpose(const mat4 &m)
148 | {
149 | vec4 a = m.x;
150 | vec4 b = m.y;
151 | vec4 c = m.z;
152 | vec4 d = m.w;
153 | mat4 result;
154 | result.x = vec4(a.x, b.x, c.x, d.x);
155 | result.y = vec4(a.y, b.y, c.y, d.y);
156 | result.z = vec4(a.z, b.z, c.z, d.z);
157 | result.w = vec4(a.w, b.w, c.w, d.w);
158 | return result;
159 | }
160 |
161 | static mat4 perspective(float fovy, float aspect, float z_near, float z_far)
162 | {
163 | mat4 m(1.0f);
164 | float invtf = 1.0f / tan(fovy * 0.5f);
165 | m[0].x = invtf / aspect;
166 | m[1].y = invtf;
167 | m[2].z = -(z_far + z_near) / (z_far - z_near);
168 | m[2].w = -1.0f;
169 | m[3].z = (-2.0f * z_far * z_near) / (z_far - z_near);
170 | m[3].w = 0.0f;
171 | return m;
172 | }
173 |
174 | static mat4 orthographic(float left, float right, float bottom, float top, float z_near, float z_far)
175 | {
176 | mat4 m(1.0f);
177 | m[0].x = 2.0f / (right - left);
178 | m[3].x = -(right + left) / (right - left);
179 | m[1].y = 2.0f / (top - bottom);
180 | m[3].y = -(top + bottom) / (top - bottom);
181 | m[2].z = -2.0f / (z_far - z_near);
182 | m[3].z = -(z_far + z_near) / (z_far - z_near);
183 | return m;
184 | }
185 |
186 | static mat4 rotateX(float rad)
187 | {
188 | float co = cosf(rad); float si = sinf(rad);
189 | mat4 m(1.0f);
190 | m[1][1] = co; m[1][2] = -si; m[2][1] = si; m[2][2] = co;
191 | return m;
192 | }
193 |
194 | static mat4 rotateY(float rad)
195 | {
196 | float co = cosf(rad); float si = sinf(rad);
197 | mat4 m(1.0f);
198 | m[0][0] = co; m[0][2] = si; m[2][0] = -si; m[2][2] = co;
199 | return m;
200 | }
201 |
202 | static mat4 rotateZ(float rad)
203 | {
204 | float co = cosf(rad); float si = sinf(rad);
205 | mat4 m(1.0f);
206 | m[0][0] = co; m[1][0] = -si; m[0][1] = si; m[1][1] = co;
207 | return m;
208 | }
209 |
210 | static mat4 translate(float x, float y, float z)
211 | {
212 | mat4 m(1.0f);
213 | m[3][0] = x; m[3][1] = y; m[3][2] = z; m[3][3] = 1.0f;
214 | return m;
215 | }
216 |
217 | static mat4 translate(const vec3 &v)
218 | {
219 | mat4 m(1.0f);
220 | m[3][0] = v.x; m[3][1] = v.y; m[3][2] = v.z;
221 | return m;
222 | }
223 |
224 | static mat4 scale(float x, float y, float z)
225 | {
226 | mat4 m(1.0f);
227 | m[0][0] = x; m[1][1] = y; m[2][2] = z;
228 | return m;
229 | }
230 |
231 | static mat4 scale(float s)
232 | {
233 | return scale(s, s, s);
234 | }
235 |
236 | #endif
237 |
--------------------------------------------------------------------------------
/app-malivr/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-malivr/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-malivr/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-malivr/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-malivr/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-malivr/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-malivr/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-malivr/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-malivr/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-malivr/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-malivr/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #DDDDDD
7 | #FFFFFF
8 |
9 |
--------------------------------------------------------------------------------
/app-malivr/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app-malivr/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VRDroid-Malivr
3 |
4 |
--------------------------------------------------------------------------------
/app-malivr/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app-rajawali/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app-rajawali/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.model.application'
2 |
3 | model {
4 | android {
5 | compileSdkVersion = 23
6 | buildToolsVersion = '23.0.3'
7 |
8 | defaultConfig {
9 | applicationId = 'com.babysource.vrdroid.rajawali'
10 | minSdkVersion.apiLevel = 16
11 | targetSdkVersion.apiLevel = 23
12 | }
13 | }
14 |
15 | android.buildTypes {
16 | debug {
17 | debuggable = true
18 | minifyEnabled = false
19 | multiDexEnabled = false
20 | shrinkResources = false
21 | zipAlignEnabled = true
22 | }
23 | release {
24 | debuggable = false
25 | minifyEnabled = false
26 | multiDexEnabled = false
27 | shrinkResources = true
28 | zipAlignEnabled = true
29 | proguardFiles.add(file('proguard-rules.pro'))
30 | }
31 | }
32 |
33 | android.packagingOptions {
34 | exclude 'META-INF/DEPENDENCIES'
35 | exclude 'META-INF/LICENSE.txt'
36 | exclude 'META-INF/LICENSE'
37 | exclude 'META-INF/NOTICE.txt'
38 | exclude 'META-INF/NOTICE'
39 | }
40 |
41 | android.lintOptions {
42 | abortOnError = false
43 | }
44 | }
45 |
46 | repositories {
47 | maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
48 | }
49 |
50 | dependencies {
51 | compile 'com.android.support:appcompat-v7:23.2.1'
52 | compile 'org.rajawali3d:rajawali:1.1.777'
53 | compile 'org.rajawali3d:vr:1.1.777'
54 | }
55 |
--------------------------------------------------------------------------------
/app-rajawali/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\adt-bundle-windows-x86_64-20131030\Android_Studio_sdk\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/java/org/babysource/vrdroid/VRDroidLister.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.os.Bundle;
7 | import android.support.v4.app.FragmentActivity;
8 |
9 | /**
10 | * VR资源列表
11 | *
12 | *
13 | * @author Wythe
14 | */
15 | public class VRDroidLister extends FragmentActivity {
16 |
17 | @Override
18 | protected void onCreate(final Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/java/org/babysource/vrdroid/VRDroidPlayer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.os.Bundle;
7 |
8 | import org.babysource.vrdroid.render.VRDroidRender;
9 | import org.rajawali3d.vr.VRActivity;
10 |
11 | /**
12 | * VR资源播放
13 | *
14 | *
15 | * @author Wythe
16 | */
17 | public class VRDroidPlayer extends VRActivity {
18 |
19 | private VRDroidRender mMediaRender;
20 |
21 | @Override
22 | public void onCreate(final Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | this.getSurfaceView().setSettingsButtonEnabled(false);
25 | this.getSurfaceView().setAlignmentMarkerEnabled(false);
26 | this.getSurfaceView().setRenderer(this.mMediaRender = new VRDroidRender(this));
27 | }
28 |
29 | @Override
30 | public void onPause() {
31 | super.onPause();
32 | if (this.mMediaRender != null) {
33 | this.mMediaRender.onPause();
34 | }
35 | }
36 |
37 | @Override
38 | public void onResume() {
39 | super.onResume();
40 | if (this.mMediaRender != null) {
41 | this.mMediaRender.onResume();
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/java/org/babysource/vrdroid/render/VRDroidRender.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid.render;
5 |
6 | import android.content.Context;
7 | import android.graphics.SurfaceTexture;
8 | import android.media.MediaPlayer;
9 | import android.net.Uri;
10 | import android.os.Environment;
11 | import android.view.MotionEvent;
12 |
13 | import org.rajawali3d.materials.Material;
14 | import org.rajawali3d.materials.textures.ATexture;
15 | import org.rajawali3d.materials.textures.StreamingTexture;
16 | import org.rajawali3d.primitives.Sphere;
17 | import org.rajawali3d.vr.renderer.VRRenderer;
18 |
19 | import java.io.File;
20 |
21 | /**
22 | * VR资源渲染
23 | *
24 | *
25 | * @author Wythe
26 | */
27 | public class VRDroidRender extends VRRenderer {
28 |
29 | private MediaPlayer mMediaPlayer;
30 |
31 | private StreamingTexture mMediaTexture;
32 |
33 | public VRDroidRender(Context context) {
34 | super(context);
35 | this.setFrameRate(60.0D);
36 | }
37 |
38 | @Override
39 | protected void initScene() {
40 | if (this.mMediaPlayer == null) {
41 | this.mMediaPlayer = MediaPlayer.create(getContext(), Uri.fromFile(
42 | new File(Environment.getExternalStorageDirectory() + File.separator + "360Videos/360.mp4")
43 | ));
44 | }
45 | if (this.mMediaTexture == null) {
46 | this.mMediaTexture = new StreamingTexture("video", this.mMediaPlayer);
47 | }
48 | final Material material = new Material();
49 | try {
50 | material.addTexture(this.mMediaTexture);
51 | } catch (ATexture.TextureException e) {
52 | e.printStackTrace();
53 | return;
54 | }
55 | final Sphere sphere = new Sphere(1, 24, 24);
56 | sphere.setMaterial(material);
57 | sphere.setPosition(0, 0, 0);
58 | sphere.setScaleX(100);
59 | sphere.setScaleY(100);
60 | sphere.setScaleZ(-100);
61 | material.setColorInfluence(0F);
62 | getCurrentScene().addChild(sphere);
63 | this.mMediaPlayer.setLooping(true);
64 | this.mMediaPlayer.start();
65 | }
66 |
67 | @Override
68 | public void onRenderSurfaceDestroyed(final SurfaceTexture surface) {
69 | super.onRenderSurfaceDestroyed(surface);
70 | if (this.mMediaTexture != null) {
71 | this.mMediaTexture = null;
72 | }
73 | if (this.mMediaPlayer != null) {
74 | try {
75 | this.mMediaPlayer.stop();
76 | } catch (Exception e) {
77 | e.printStackTrace();
78 | } finally {
79 | this.mMediaPlayer.release();
80 | }
81 | this.mMediaPlayer = null;
82 | }
83 | }
84 |
85 | @Override
86 | public void onPause() {
87 | super.onPause();
88 | if (this.mMediaPlayer != null) {
89 | this.mMediaPlayer.pause();
90 | }
91 | }
92 |
93 | @Override
94 | public void onResume() {
95 | super.onResume();
96 | if (this.mMediaPlayer != null) {
97 | this.mMediaPlayer.start();
98 | }
99 | }
100 |
101 | @Override
102 | protected void onRender(final long ellapsedRealtime, final double deltaTime) {
103 | super.onRender(ellapsedRealtime, deltaTime);
104 | if (this.mMediaTexture != null) {
105 | this.mMediaTexture.update();
106 | }
107 | }
108 |
109 | @Override
110 | public void onTouchEvent(final MotionEvent event) {
111 |
112 | }
113 |
114 | @Override
115 | public void onOffsetsChanged(final float xOffset, final float yOffset, final float xOffsetStep, final float yOffsetStep, final int xPixelOffset, final int yPixelOffset) {
116 |
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-rajawali/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-rajawali/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-rajawali/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-rajawali/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-rajawali/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VRDroid-Rajawali
3 |
4 |
--------------------------------------------------------------------------------
/app-rajawali/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app-vrwidget/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app-vrwidget/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.model.application'
2 |
3 | model {
4 | android {
5 | compileSdkVersion = 23
6 | buildToolsVersion = '23.0.3'
7 |
8 | defaultConfig {
9 | applicationId = 'com.babysource.vrdroid.vrview'
10 | minSdkVersion.apiLevel = 19
11 | targetSdkVersion.apiLevel = 23
12 | }
13 | }
14 |
15 | android.buildTypes {
16 | debug {
17 | debuggable = true
18 | minifyEnabled = false
19 | multiDexEnabled = false
20 | shrinkResources = false
21 | zipAlignEnabled = true
22 | }
23 | release {
24 | debuggable = false
25 | minifyEnabled = false
26 | multiDexEnabled = false
27 | shrinkResources = true
28 | zipAlignEnabled = true
29 | proguardFiles.add(file('proguard-rules.pro'))
30 | }
31 | }
32 |
33 | android.packagingOptions {
34 | exclude 'META-INF/DEPENDENCIES'
35 | exclude 'META-INF/LICENSE.txt'
36 | exclude 'META-INF/LICENSE'
37 | exclude 'META-INF/NOTICE.txt'
38 | exclude 'META-INF/NOTICE'
39 | }
40 |
41 | android.lintOptions {
42 | abortOnError = false
43 | }
44 | }
45 |
46 | dependencies {
47 | compile project(':libraries:common')
48 | compile project(':libraries:videowidget')
49 | compile project(':libraries:commonwidget')
50 | compile 'com.android.support:appcompat-v7:23.2.1'
51 | compile 'com.google.android.exoplayer:exoplayer:r1.5.12'
52 | compile 'com.google.protobuf.nano:protobuf-javanano:3.1.0'
53 | }
54 |
--------------------------------------------------------------------------------
/app-vrwidget/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\adt-bundle-windows-x86_64-20131030\Android_Studio_sdk\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/java/org/babysource/vrdroid/VRDroidLister.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.content.Intent;
7 | import android.graphics.Bitmap;
8 | import android.media.ThumbnailUtils;
9 | import android.os.AsyncTask;
10 | import android.os.Bundle;
11 | import android.os.Environment;
12 | import android.provider.MediaStore;
13 | import android.support.v4.app.FragmentActivity;
14 | import android.text.TextUtils;
15 | import android.view.LayoutInflater;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.widget.BaseAdapter;
19 | import android.widget.ImageView;
20 | import android.widget.ListView;
21 | import android.widget.TextView;
22 | import android.widget.Toast;
23 |
24 | import java.io.File;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * VR资源列表
30 | *
31 | *
32 | * @author Wythe
33 | */
34 | public class VRDroidLister extends FragmentActivity {
35 |
36 | private final static String VR_FOLDER = "360Videos";
37 |
38 | private List mVrVideoIcon = new ArrayList<>();
39 |
40 | private long mBackPressedTime;
41 |
42 | private ListView mVrVideoList;
43 |
44 | private VRDroidAdapter mVrAdapter;
45 |
46 | @Override
47 | protected void onCreate(final Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | this.setContentView(R.layout.droid_lister);
50 | this.mVrVideoList = (ListView) this.findViewById(R.id.vr_video_list);
51 | if (this.mVrVideoList != null) {
52 | this.mVrVideoList.setAdapter(
53 | this.mVrAdapter = new VRDroidAdapter()
54 | );
55 | }
56 | if (this.mVrAdapter != null) {
57 | final File folder = new File(Environment.getExternalStorageDirectory() + File.separator + VR_FOLDER);
58 | if (!folder.exists()) {
59 | folder.mkdirs();
60 | }
61 | final File[] files = folder.listFiles();
62 | if (files.length > 0) {
63 | final String[] paths = new String[files.length];
64 | for (int i = 0, l = files.length; i < l; i++) {
65 | paths[i] = files[i].getAbsolutePath();
66 | }
67 | new VRIconTask().execute(paths);
68 | this.mVrAdapter.setFiles(files);
69 | }
70 | }
71 | }
72 |
73 | @Override
74 | public void onBackPressed() {
75 | final long mCurrentTime = System.currentTimeMillis();
76 | if (mCurrentTime - this.mBackPressedTime > 1000) {
77 | Toast.makeText(this, R.string.app_logout, Toast.LENGTH_SHORT).show();
78 | this.mBackPressedTime = mCurrentTime;
79 | return;
80 | }
81 | super.onBackPressed();
82 | System.exit(0);
83 | }
84 |
85 | private final class VRDroidAdapter extends BaseAdapter {
86 |
87 | private File[] files;
88 |
89 | public void setFiles(final File[] files) {
90 | this.files = files;
91 | }
92 |
93 | @Override
94 | public int getCount() {
95 | return files != null ? files.length : 0;
96 | }
97 |
98 | @Override
99 | public Object getItem(int position) {
100 | return null;
101 | }
102 |
103 | @Override
104 | public long getItemId(int position) {
105 | return 0;
106 | }
107 |
108 | @Override
109 | public View getView(int position, View convertView, ViewGroup parent) {
110 | VRViewHolder holder = null;
111 | if (convertView != null) {
112 | holder = (VRViewHolder) convertView.getTag();
113 | } else {
114 | convertView = LayoutInflater.from(VRDroidLister.this).inflate(R.layout.droid_item, null);
115 | if (convertView != null) {
116 | convertView.setTag(
117 | holder = new VRViewHolder(convertView)
118 | );
119 | }
120 | }
121 | if (holder != null) {
122 | final File file = this.files[position];
123 | if (file != null) {
124 | final String path = file.getAbsolutePath();
125 | if (!TextUtils.isEmpty(path)) {
126 | final String name = this.getFileName(file);
127 | if (!TextUtils.isEmpty(name)) {
128 | holder.name.setText(name);
129 | }
130 | if (mVrVideoIcon.size() > position) {
131 | holder.icon.setImageBitmap(mVrVideoIcon.get(position));
132 | }
133 | convertView.setOnClickListener(new View.OnClickListener() {
134 | @Override
135 | public void onClick(final View v) {
136 | final Intent intent = new Intent();
137 | intent.putExtra(VRDroidPlayer.KEY_NAME, name);
138 | intent.putExtra(VRDroidPlayer.KEY_PATH, path);
139 | intent.setClass(VRDroidLister.this, VRDroidPlayer.class);
140 | startActivity(intent);
141 | }
142 | });
143 | }
144 | }
145 | }
146 | return convertView;
147 | }
148 |
149 | private String getFileName(final File file) {
150 | final String name = file.getName();
151 | if (!TextUtils.isEmpty(name)) {
152 | final int ext = name.lastIndexOf(".");
153 | if (ext > 0) {
154 | return name.substring(0, ext);
155 | }
156 | }
157 | return name;
158 | }
159 |
160 | }
161 |
162 | private final class VRViewHolder {
163 | final TextView name;
164 | final ImageView icon;
165 |
166 | public VRViewHolder(final View view) {
167 | this.name = (TextView) view.findViewById(R.id.vr_video_name);
168 | this.icon = (ImageView) view.findViewById(R.id.vr_video_icon);
169 | }
170 | }
171 |
172 | private final class VRIconTask extends AsyncTask {
173 |
174 | @Override
175 | protected Void doInBackground(final String... paths) {
176 | for (final String path : paths) {
177 | mVrVideoIcon.add(ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MICRO_KIND));
178 | }
179 | return null;
180 | }
181 |
182 | @Override
183 | protected void onPostExecute(final Void aVoid) {
184 | if (mVrAdapter != null) {
185 | mVrAdapter.notifyDataSetChanged();
186 | }
187 | }
188 | }
189 |
190 | }
191 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/java/org/babysource/vrdroid/VRDroidPlayer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.net.Uri;
7 | import android.os.Bundle;
8 | import android.support.v4.app.FragmentActivity;
9 | import android.text.TextUtils;
10 | import android.widget.TextView;
11 |
12 | import com.google.vr.sdk.widgets.common.VrWidgetView;
13 | import com.google.vr.sdk.widgets.video.VrVideoView;
14 |
15 | import java.io.File;
16 | import java.io.IOException;
17 |
18 | /**
19 | * VR资源播放
20 | *
21 | *
22 | * @author Wythe
23 | */
24 | public class VRDroidPlayer extends FragmentActivity {
25 |
26 | final static String KEY_NAME = "_$KEY_NAME";
27 | final static String KEY_PATH = "_$KEY_PATH";
28 |
29 | private TextView mVrVideoName;
30 |
31 | private VrVideoView mVrVideoView;
32 |
33 | @Override
34 | public void onBackPressed() {
35 | super.onBackPressed();
36 | this.finish();
37 | }
38 |
39 | @Override
40 | protected void onDestroy() {
41 | if (this.mVrVideoView != null) {
42 | this.mVrVideoView.pauseRendering();
43 | this.mVrVideoView.shutdown();
44 | }
45 | super.onDestroy();
46 | }
47 |
48 | @Override
49 | protected void onPause() {
50 | super.onPause();
51 | if (this.mVrVideoView != null) {
52 | this.mVrVideoView.pauseVideo();
53 | }
54 | }
55 |
56 | @Override
57 | protected void onResume() {
58 | super.onResume();
59 | if (this.mVrVideoView != null) {
60 | this.mVrVideoView.playVideo();
61 | }
62 | }
63 |
64 | @Override
65 | protected void onCreate(final Bundle savedInstanceState) {
66 | super.onCreate(savedInstanceState);
67 | this.setContentView(R.layout.droid_player);
68 | this.mVrVideoName = (TextView) this.findViewById(R.id.tv_video_name);
69 | if (this.mVrVideoName != null) {
70 | final String name = this.getIntent().getStringExtra(KEY_NAME);
71 | if (!TextUtils.isEmpty(name)) {
72 | this.mVrVideoName.setText(name);
73 | }
74 | }
75 | this.mVrVideoView = (VrVideoView) this.findViewById(R.id.vr_video_view);
76 | if (this.mVrVideoView != null) {
77 | final String path = this.getIntent().getStringExtra(KEY_PATH);
78 | if (!TextUtils.isEmpty(path)) {
79 | this.mVrVideoView.setDisplayMode(
80 | VrWidgetView.DisplayMode.FULLSCREEN_STEREO
81 | );
82 | this.mVrVideoView.setInfoButtonEnabled(false);
83 | try {
84 | this.mVrVideoView.loadVideo(
85 | Uri.fromFile(new File(path)), new VrVideoView.Options()
86 | );
87 | } catch (IOException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | }
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/layout/droid_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
18 |
19 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/layout/droid_lister.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
21 |
22 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/layout/droid_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-vrwidget/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-vrwidget/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-vrwidget/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-vrwidget/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app-vrwidget/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #DDDDDD
7 | #FFFFFF
8 |
9 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VRDroid-Vrview
3 | 本地资源
4 | 继续按返回键退出
5 |
6 |
--------------------------------------------------------------------------------
/app-vrwidget/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.model.application'
2 |
3 | model {
4 | android {
5 | compileSdkVersion = 23
6 | buildToolsVersion = '23.0.3'
7 |
8 | defaultConfig {
9 | applicationId = 'com.babysource.vrdroid.camera'
10 | minSdkVersion.apiLevel = 21
11 | targetSdkVersion.apiLevel = 23
12 | }
13 | }
14 |
15 | android.buildTypes {
16 | debug {
17 | debuggable = true
18 | minifyEnabled = false
19 | multiDexEnabled = false
20 | shrinkResources = false
21 | zipAlignEnabled = true
22 | }
23 | release {
24 | debuggable = false
25 | minifyEnabled = false
26 | multiDexEnabled = false
27 | shrinkResources = true
28 | zipAlignEnabled = true
29 | proguardFiles.add(file('proguard-rules.pro'))
30 | }
31 | }
32 |
33 | android.packagingOptions {
34 | exclude 'META-INF/DEPENDENCIES'
35 | exclude 'META-INF/LICENSE.txt'
36 | exclude 'META-INF/LICENSE'
37 | exclude 'META-INF/NOTICE.txt'
38 | exclude 'META-INF/NOTICE'
39 | }
40 |
41 | android.lintOptions {
42 | abortOnError = false
43 | }
44 | }
45 |
46 | dependencies {
47 | compile project(':libraries:base')
48 | compile project(':libraries:common')
49 | compile 'com.android.support:appcompat-v7:23.2.1'
50 | compile 'com.google.protobuf.nano:protobuf-javanano:3.1.0'
51 | }
52 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\adt-bundle-windows-x86_64-20131030\Android_Studio_sdk\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
18 |
19 |
22 |
23 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/java/org/babysource/vrdroid/VRDroidBuilder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/4/21
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.opengl.GLES20;
7 |
8 | import javax.microedition.khronos.opengles.GL10;
9 |
10 | /**
11 | *
12 | *
13 | * @author Wythe
14 | */
15 | public final class VRDroidBuilder {
16 |
17 | final static int GL_CAMERA_OES = 0x8D65;
18 |
19 | final static int MAX_PREVIEW_WIDE = 1920;
20 |
21 | final static int MAX_PREVIEW_HIGH = 1080;
22 |
23 | final static String ATTR_POSITION = "a_Position";
24 |
25 | final static String ATTR_TEXCOORD = "a_Texcoord";
26 |
27 | // 顶点坐标个数
28 | final static int COORDS_PER_VERTEX = 2;
29 |
30 | // 顶点绘制顺序
31 | final static short ORDER_VERTICES[] = {
32 | 0, 3, 2, 0, 2, 1
33 | };
34 |
35 | // 定义平面顶点
36 | final static float PLANE_VERTICES[] = {
37 | -1.0F, 1.0F, // 0:左上角
38 | 1.0F, 1.0F, // 1:右上角
39 | 1.0F, -1.0F, // 2:右下角
40 | -1.0F, -1.0F, // 3:左下角
41 | };
42 |
43 | // 定义纹理顶点
44 | final static float FRAME_VERTICES[] = {
45 | 0.0f, 0.0f, // 0:左上角
46 | 1.0f, 0.0f, // 1:右上角
47 | 1.0f, 1.0f, // 2:右下角
48 | 0.0f, 1.0f // 3:左下角
49 | };
50 |
51 | // 顶点绘制程序
52 | final static String VERTEX_SHADER_CODE =
53 | "attribute vec4 " + ATTR_POSITION + ";" +
54 | "attribute vec2 " + ATTR_TEXCOORD + ";" +
55 | "varying vec2 v_Texcoord;" +
56 | "void main() {" +
57 | " v_Texcoord = " + ATTR_TEXCOORD + ";" +
58 | " gl_Position = " + ATTR_POSITION + ";" +
59 | "}";
60 |
61 | // 外观绘制程序
62 | final static String FACADE_SHADER_CODE =
63 | "#extension GL_OES_EGL_image_external : require\n" +
64 | "precision mediump float;" +
65 | "varying vec2 v_Texcoord;" +
66 | "uniform samplerExternalOES s_Texture;" +
67 | "void main() {" +
68 | " gl_FragColor = texture2D(s_Texture, v_Texcoord);" +
69 | "}";
70 |
71 | final static int createTexture() {
72 | final int[] textures = new int[1];
73 | GLES20.glGenTextures(1, textures, 0);
74 | GLES20.glBindTexture(VRDroidBuilder.GL_CAMERA_OES, textures[0]);
75 | GLES20.glTexParameterf(VRDroidBuilder.GL_CAMERA_OES, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
76 | GLES20.glTexParameterf(VRDroidBuilder.GL_CAMERA_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
77 | GLES20.glTexParameteri(VRDroidBuilder.GL_CAMERA_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
78 | GLES20.glTexParameteri(VRDroidBuilder.GL_CAMERA_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
79 | return textures[0];
80 | }
81 |
82 | final static int fitPreviewWide(final int wide) {
83 | if (wide < 0) {
84 | return 0;
85 | }
86 | return wide > MAX_PREVIEW_WIDE ? MAX_PREVIEW_WIDE : wide;
87 | }
88 |
89 | final static int fitPreviewHigh(final int high) {
90 | if (high < 0) {
91 | return 0;
92 | }
93 | return high > MAX_PREVIEW_HIGH ? MAX_PREVIEW_HIGH : high;
94 | }
95 |
96 | final static int loadGLShader(final int type, final String code) {
97 | int shader = GLES20.glCreateShader(type);
98 | GLES20.glShaderSource(shader, code);
99 | GLES20.glCompileShader(shader);
100 | // 校验编译状态
101 | final int[] compileStatus = new int[1];
102 | GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
103 | if (compileStatus[0] == 0) {
104 | GLES20.glDeleteShader(shader);
105 | shader = 0;
106 | }
107 | if (shader == 0) {
108 | throw new RuntimeException("Creating shader error.");
109 | }
110 | return shader;
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/app/src/main/java/org/babysource/vrdroid/VRDroidCamera.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.Manifest;
7 | import android.content.pm.PackageManager;
8 | import android.graphics.SurfaceTexture;
9 | import android.hardware.Camera;
10 | import android.opengl.GLES20;
11 | import android.os.Bundle;
12 | import android.support.v4.app.ActivityCompat;
13 | import android.widget.Toast;
14 |
15 | import com.google.vr.sdk.base.Eye;
16 | import com.google.vr.sdk.base.GvrActivity;
17 | import com.google.vr.sdk.base.GvrView;
18 | import com.google.vr.sdk.base.HeadTransform;
19 | import com.google.vr.sdk.base.Viewport;
20 |
21 | import java.io.IOException;
22 | import java.nio.ByteBuffer;
23 | import java.nio.ByteOrder;
24 | import java.nio.FloatBuffer;
25 | import java.nio.ShortBuffer;
26 |
27 | import javax.microedition.khronos.egl.EGLConfig;
28 |
29 | /**
30 | * VR资源列表
31 | *
32 | *
33 | * @author Wythe
34 | */
35 | public class VRDroidCamera extends GvrActivity implements GvrView.StereoRenderer {
36 |
37 | private final float[] mRes = new float[16];
38 |
39 | private final float[] mRhs = new float[16];
40 |
41 | private long mBackPressedTime;
42 |
43 | private int mTarget;
44 |
45 | private int mProgram;
46 |
47 | private Camera mCamera;
48 |
49 | private ShortBuffer mOrderBuffer;
50 |
51 | private FloatBuffer mPlaneBuffer;
52 |
53 | private FloatBuffer mFrameBuffer;
54 |
55 | private GvrView mGvrView;
56 |
57 | private SurfaceTexture mCameraTexture;
58 |
59 | @Override
60 | protected void onCreate(final Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | this.setContentView(R.layout.droid_lister);
63 | this.mGvrView = (GvrView) this.findViewById(R.id.gvr_view);
64 | if (this.mGvrView != null) {
65 | this.setGvrView(this.mGvrView);
66 | // 设置视图
67 | this.mGvrView.setRenderer(this);
68 | this.mGvrView.setStereoModeEnabled(true);
69 | this.mGvrView.setTransitionViewEnabled(true);
70 | }
71 | }
72 |
73 | @Override
74 | protected void onPause() {
75 | super.onPause();
76 | if (this.mGvrView != null) {
77 | this.mGvrView.onPause();
78 | }
79 | }
80 |
81 | @Override
82 | protected void onResume() {
83 | super.onResume();
84 | if (this.mGvrView != null) {
85 | this.mGvrView.onResume();
86 | }
87 | }
88 |
89 | @Override
90 | protected void onDestroy() {
91 | this.shutCamera();
92 | super.onDestroy();
93 | }
94 |
95 | @Override
96 | public void onBackPressed() {
97 | final long mCurrentTime = System.currentTimeMillis();
98 | if (mCurrentTime - this.mBackPressedTime > 1000) {
99 | Toast.makeText(this, R.string.app_logout, Toast.LENGTH_SHORT).show();
100 | this.mBackPressedTime = mCurrentTime;
101 | return;
102 | }
103 | super.onBackPressed();
104 | System.exit(0);
105 | }
106 |
107 | @Override
108 | public void onRendererShutdown() {
109 | this.shutCamera();
110 | }
111 |
112 | @Override
113 | public void onDrawEye(final Eye eye) {
114 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
115 | // 初始绘制
116 | GLES20.glUseProgram(this.mProgram);
117 | GLES20.glActiveTexture(VRDroidBuilder.GL_CAMERA_OES);
118 | GLES20.glBindTexture(VRDroidBuilder.GL_CAMERA_OES, this.mTarget);
119 | // 绘制平面
120 | final int mPositionHandle = GLES20.glGetAttribLocation(this.mProgram, VRDroidBuilder.ATTR_POSITION);
121 | GLES20.glEnableVertexAttribArray(mPositionHandle);
122 | GLES20.glVertexAttribPointer(mPositionHandle, VRDroidBuilder.COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VRDroidBuilder.COORDS_PER_VERTEX * 4, this.mPlaneBuffer);
123 | // 绘制纹理
124 | final int mTexCoordHandle = GLES20.glGetAttribLocation(this.mProgram, VRDroidBuilder.ATTR_TEXCOORD);
125 | GLES20.glEnableVertexAttribArray(mTexCoordHandle);
126 | GLES20.glVertexAttribPointer(mTexCoordHandle, VRDroidBuilder.COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VRDroidBuilder.COORDS_PER_VERTEX * 4, this.mFrameBuffer);
127 | // 顺序绘制
128 | GLES20.glDrawElements(GLES20.GL_TRIANGLES, VRDroidBuilder.ORDER_VERTICES.length, GLES20.GL_UNSIGNED_SHORT, this.mOrderBuffer);
129 | GLES20.glDisableVertexAttribArray(mPositionHandle);
130 | GLES20.glDisableVertexAttribArray(mTexCoordHandle);
131 | android.opengl.Matrix.multiplyMM(this.mRes, 0, eye.getEyeView(), 0, this.mRhs, 0);
132 | }
133 |
134 | @Override
135 | public void onNewFrame(final HeadTransform headTransform) {
136 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
137 | if (this.mCameraTexture != null) {
138 | this.mCameraTexture.updateTexImage();
139 | }
140 | }
141 |
142 | @Override
143 | public void onFinishFrame(final Viewport viewport) {
144 | }
145 |
146 | @Override
147 | public void onSurfaceCreated(final EGLConfig eglConfig) {
148 | GLES20.glClearColor(0.1F, 0.1F, 0.1F, 0.5F);
149 | // 初始绘制顺序缓冲
150 | final ByteBuffer orderBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.ORDER_VERTICES.length * 2).order(ByteOrder.nativeOrder());
151 | this.mOrderBuffer = orderBuffer.asShortBuffer();
152 | this.mOrderBuffer.put(VRDroidBuilder.ORDER_VERTICES);
153 | this.mOrderBuffer.position(0);
154 | // 初始平面顶点缓冲
155 | final ByteBuffer planeBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.PLANE_VERTICES.length * 4).order(ByteOrder.nativeOrder());
156 | this.mPlaneBuffer = planeBuffer.asFloatBuffer();
157 | this.mPlaneBuffer.put(VRDroidBuilder.PLANE_VERTICES);
158 | this.mPlaneBuffer.position(0);
159 | // 初始纹理顶点缓冲
160 | final ByteBuffer frameBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.FRAME_VERTICES.length * 4).order(ByteOrder.nativeOrder());
161 | this.mFrameBuffer = frameBuffer.asFloatBuffer();
162 | this.mFrameBuffer.put(VRDroidBuilder.FRAME_VERTICES);
163 | this.mFrameBuffer.position(0);
164 | // 创建绘制应用程序
165 | this.mProgram = GLES20.glCreateProgram();
166 | GLES20.glAttachShader(this.mProgram, VRDroidBuilder.loadGLShader(GLES20.GL_VERTEX_SHADER, VRDroidBuilder.VERTEX_SHADER_CODE));
167 | GLES20.glAttachShader(this.mProgram, VRDroidBuilder.loadGLShader(GLES20.GL_FRAGMENT_SHADER, VRDroidBuilder.FACADE_SHADER_CODE));
168 | GLES20.glLinkProgram(this.mProgram);
169 | // 打开摄像头
170 | this.openCamera();
171 | }
172 |
173 | @Override
174 | public void onSurfaceChanged(final int i0, final int i1) {
175 | }
176 |
177 | private void openCamera() {
178 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
179 | this.mCamera = Camera.open();
180 | if (this.mCamera != null) {
181 | (this.mCameraTexture = new SurfaceTexture(
182 | this.mTarget = VRDroidBuilder.createTexture()
183 | )).setDefaultBufferSize(VRDroidBuilder.fitPreviewWide(mGvrView.getWidth()), VRDroidBuilder.fitPreviewHigh(mGvrView.getHeight()));
184 | try {
185 | this.mCamera.setPreviewTexture(this.mCameraTexture);
186 | } catch (IOException e) {
187 | e.printStackTrace();
188 | this.mCamera.release();
189 | return;
190 | }
191 | // 开始偷窥
192 | this.mCamera.startPreview();
193 | }
194 | }
195 | }
196 |
197 | private void shutCamera() {
198 | if (this.mCamera != null) {
199 | this.mCamera.release();
200 | this.mCamera = null;
201 | }
202 | }
203 |
204 | }
205 |
--------------------------------------------------------------------------------
/app/src/main/java/org/babysource/vrdroid/VRDroidCamera2.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created on 2016/3/31
3 | */
4 | package org.babysource.vrdroid;
5 |
6 | import android.Manifest;
7 | import android.content.Context;
8 | import android.content.pm.PackageManager;
9 | import android.graphics.SurfaceTexture;
10 | import android.hardware.camera2.CameraAccessException;
11 | import android.hardware.camera2.CameraCaptureSession;
12 | import android.hardware.camera2.CameraCharacteristics;
13 | import android.hardware.camera2.CameraDevice;
14 | import android.hardware.camera2.CameraManager;
15 | import android.hardware.camera2.CaptureRequest;
16 | import android.opengl.GLES20;
17 | import android.os.Bundle;
18 | import android.os.Handler;
19 | import android.os.HandlerThread;
20 | import android.support.v4.app.ActivityCompat;
21 | import android.view.Surface;
22 | import android.widget.Toast;
23 |
24 | import com.google.vr.sdk.base.Eye;
25 | import com.google.vr.sdk.base.GvrActivity;
26 | import com.google.vr.sdk.base.GvrView;
27 | import com.google.vr.sdk.base.HeadTransform;
28 | import com.google.vr.sdk.base.Viewport;
29 |
30 | import java.nio.ByteBuffer;
31 | import java.nio.ByteOrder;
32 | import java.nio.FloatBuffer;
33 | import java.nio.ShortBuffer;
34 | import java.util.Arrays;
35 | import java.util.concurrent.Semaphore;
36 |
37 | import javax.microedition.khronos.egl.EGLConfig;
38 |
39 | /**
40 | * VR资源列表
41 | *
42 | *
43 | * @author Wythe
44 | */
45 | public class VRDroidCamera2 extends GvrActivity implements GvrView.StereoRenderer {
46 |
47 | private final Semaphore mCameraLocker = new Semaphore(1);
48 |
49 | private final float[] mRes = new float[16];
50 |
51 | private final float[] mRhs = new float[16];
52 |
53 | private long mBackPressedTime;
54 |
55 | private int mTarget;
56 |
57 | private int mProgram;
58 |
59 | private GvrView mGvrView;
60 |
61 | private Handler mCameraHandle;
62 |
63 | private ShortBuffer mOrderBuffer;
64 |
65 | private FloatBuffer mPlaneBuffer;
66 |
67 | private FloatBuffer mFrameBuffer;
68 |
69 | private CameraDevice mCameraDevice;
70 |
71 | private HandlerThread mCameraThread;
72 |
73 | private CameraManager mCameraManager;
74 |
75 | private SurfaceTexture mCameraTexture;
76 |
77 | private CaptureRequest.Builder mCameraBuilder;
78 |
79 | @Override
80 | protected void onCreate(final Bundle savedInstanceState) {
81 | super.onCreate(savedInstanceState);
82 | this.setContentView(R.layout.droid_lister);
83 | this.mGvrView = (GvrView) this.findViewById(R.id.gvr_view);
84 | if (this.mGvrView != null) {
85 | this.setGvrView(this.mGvrView);
86 | // 设置视图
87 | this.mGvrView.setRenderer(this);
88 | this.mGvrView.setStereoModeEnabled(true);
89 | this.mGvrView.setTransitionViewEnabled(true);
90 | }
91 | }
92 |
93 | @Override
94 | protected void onPause() {
95 | super.onPause();
96 | if (this.mGvrView != null) {
97 | this.mGvrView.onPause();
98 | }
99 | }
100 |
101 | @Override
102 | protected void onResume() {
103 | super.onResume();
104 | if (this.mGvrView != null) {
105 | this.mGvrView.onResume();
106 | }
107 | }
108 |
109 | @Override
110 | protected void onDestroy() {
111 | this.shutCamera();
112 | super.onDestroy();
113 | }
114 |
115 | @Override
116 | public void onBackPressed() {
117 | final long mCurrentTime = System.currentTimeMillis();
118 | if (mCurrentTime - this.mBackPressedTime > 1000) {
119 | Toast.makeText(this, R.string.app_logout, Toast.LENGTH_SHORT).show();
120 | this.mBackPressedTime = mCurrentTime;
121 | return;
122 | }
123 | super.onBackPressed();
124 | System.exit(0);
125 | }
126 |
127 | @Override
128 | public void onRendererShutdown() {
129 | this.shutCamera();
130 | }
131 |
132 | @Override
133 | public void onDrawEye(final Eye eye) {
134 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
135 | // 初始绘制
136 | GLES20.glUseProgram(this.mProgram);
137 | GLES20.glActiveTexture(VRDroidBuilder.GL_CAMERA_OES);
138 | GLES20.glBindTexture(VRDroidBuilder.GL_CAMERA_OES, this.mTarget);
139 | // 绘制平面
140 | final int mPositionHandle = GLES20.glGetAttribLocation(this.mProgram, VRDroidBuilder.ATTR_POSITION);
141 | GLES20.glEnableVertexAttribArray(mPositionHandle);
142 | GLES20.glVertexAttribPointer(mPositionHandle, VRDroidBuilder.COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VRDroidBuilder.COORDS_PER_VERTEX * 4, this.mPlaneBuffer);
143 | // 绘制纹理
144 | final int mTexCoordHandle = GLES20.glGetAttribLocation(this.mProgram, VRDroidBuilder.ATTR_TEXCOORD);
145 | GLES20.glEnableVertexAttribArray(mTexCoordHandle);
146 | GLES20.glVertexAttribPointer(mTexCoordHandle, VRDroidBuilder.COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VRDroidBuilder.COORDS_PER_VERTEX * 4, this.mFrameBuffer);
147 | // 顺序绘制
148 | GLES20.glDrawElements(GLES20.GL_TRIANGLES, VRDroidBuilder.ORDER_VERTICES.length, GLES20.GL_UNSIGNED_SHORT, this.mOrderBuffer);
149 | GLES20.glDisableVertexAttribArray(mPositionHandle);
150 | GLES20.glDisableVertexAttribArray(mTexCoordHandle);
151 | android.opengl.Matrix.multiplyMM(this.mRes, 0, eye.getEyeView(), 0, this.mRhs, 0);
152 | }
153 |
154 | @Override
155 | public void onNewFrame(final HeadTransform headTransform) {
156 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
157 | if (this.mCameraTexture != null) {
158 | this.mCameraTexture.updateTexImage();
159 | }
160 | }
161 |
162 | @Override
163 | public void onFinishFrame(final Viewport viewport) {
164 | }
165 |
166 | @Override
167 | public void onSurfaceCreated(final EGLConfig eglConfig) {
168 | GLES20.glClearColor(0.1F, 0.1F, 0.1F, 0.5F);
169 | // 初始绘制顺序缓冲
170 | final ByteBuffer orderBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.ORDER_VERTICES.length * 2).order(ByteOrder.nativeOrder());
171 | this.mOrderBuffer = orderBuffer.asShortBuffer();
172 | this.mOrderBuffer.put(VRDroidBuilder.ORDER_VERTICES);
173 | this.mOrderBuffer.position(0);
174 | // 初始平面顶点缓冲
175 | final ByteBuffer planeBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.PLANE_VERTICES.length * 4).order(ByteOrder.nativeOrder());
176 | this.mPlaneBuffer = planeBuffer.asFloatBuffer();
177 | this.mPlaneBuffer.put(VRDroidBuilder.PLANE_VERTICES);
178 | this.mPlaneBuffer.position(0);
179 | // 初始纹理顶点缓冲
180 | final ByteBuffer frameBuffer = ByteBuffer.allocateDirect(VRDroidBuilder.FRAME_VERTICES.length * 4).order(ByteOrder.nativeOrder());
181 | this.mFrameBuffer = frameBuffer.asFloatBuffer();
182 | this.mFrameBuffer.put(VRDroidBuilder.FRAME_VERTICES);
183 | this.mFrameBuffer.position(0);
184 | // 创建绘制应用程序
185 | this.mProgram = GLES20.glCreateProgram();
186 | GLES20.glAttachShader(this.mProgram, VRDroidBuilder.loadGLShader(GLES20.GL_VERTEX_SHADER, VRDroidBuilder.VERTEX_SHADER_CODE));
187 | GLES20.glAttachShader(this.mProgram, VRDroidBuilder.loadGLShader(GLES20.GL_FRAGMENT_SHADER, VRDroidBuilder.FACADE_SHADER_CODE));
188 | GLES20.glLinkProgram(this.mProgram);
189 | // 打开摄像头
190 | this.openCamera();
191 | }
192 |
193 | @Override
194 | public void onSurfaceChanged(final int i0, final int i1) {
195 | }
196 |
197 | private void openCamera() {
198 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
199 | this.mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
200 | if (this.mCameraManager != null) {
201 | this.openCameraThread();
202 | try {
203 | for (final String cameraId : this.mCameraManager.getCameraIdList()) {
204 | CameraCharacteristics characteristics = this.mCameraManager.getCameraCharacteristics(cameraId);
205 | if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
206 | this.mCameraManager.openCamera(cameraId, this.mCameraStateCallback, this.mCameraHandle);
207 | return;
208 | }
209 | }
210 | } catch (CameraAccessException e) {
211 | e.printStackTrace();
212 | }
213 | }
214 | }
215 | }
216 |
217 | private void shutCamera() {
218 | try {
219 | this.mCameraLocker.acquire();
220 | if (this.mCameraDevice != null) {
221 | this.mCameraDevice.close();
222 | this.mCameraDevice = null;
223 | }
224 | } catch (InterruptedException e) {
225 | e.printStackTrace();
226 | } finally {
227 | this.mCameraLocker.release();
228 | }
229 | this.stopCameraThread();
230 | }
231 |
232 | private void openCameraThread() {
233 | this.mCameraThread = new HandlerThread("VRCamera");
234 | this.mCameraThread.start();
235 | this.mCameraHandle = new Handler(
236 | this.mCameraThread.getLooper()
237 | );
238 | }
239 |
240 | private void stopCameraThread() {
241 | this.mCameraThread.quitSafely();
242 | try {
243 | this.mCameraThread.join();
244 | this.mCameraThread = null;
245 | this.mCameraHandle = null;
246 | } catch (InterruptedException e) {
247 | e.printStackTrace();
248 | }
249 | }
250 |
251 | private final CameraDevice.StateCallback mCameraStateCallback = new CameraDevice.StateCallback() {
252 | @Override
253 | public void onError(final CameraDevice cameraDevice, final int error) {
254 | mCameraLocker.release();
255 | cameraDevice.close();
256 | mCameraDevice = null;
257 | }
258 |
259 | @Override
260 | public void onOpened(final CameraDevice cameraDevice) {
261 | mCameraLocker.release();
262 | mCameraDevice = cameraDevice;
263 | mCameraTexture = new SurfaceTexture(
264 | mTarget = VRDroidBuilder.createTexture()
265 | );
266 | try {
267 | mCameraBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
268 | } catch (CameraAccessException e) {
269 | e.printStackTrace();
270 | mCameraBuilder = null;
271 | }
272 | if (mCameraBuilder != null) {
273 | final Surface surface = new Surface(mCameraTexture);
274 | if (surface != null) {
275 | mCameraBuilder.addTarget(surface);
276 | mCameraTexture.setDefaultBufferSize(
277 | VRDroidBuilder.fitPreviewWide(mGvrView.getWidth()), VRDroidBuilder.fitPreviewHigh(mGvrView.getHeight())
278 | );
279 | try {
280 | mCameraDevice.createCaptureSession(Arrays.asList(surface), mCameraCaptureSessionCallback, mCameraHandle);
281 | } catch (CameraAccessException e) {
282 | e.printStackTrace();
283 | }
284 | }
285 | }
286 | }
287 |
288 | @Override
289 | public void onDisconnected(final CameraDevice cameraDevice) {
290 | mCameraLocker.release();
291 | cameraDevice.close();
292 | mCameraDevice = null;
293 | }
294 | };
295 |
296 | private final CameraCaptureSession.StateCallback mCameraCaptureSessionCallback = new CameraCaptureSession.StateCallback() {
297 | @Override
298 | public void onConfigured(final CameraCaptureSession session) {
299 | mCameraBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
300 | try {
301 | session.setRepeatingRequest(mCameraBuilder.build(), null, mCameraHandle);
302 | } catch (CameraAccessException e) {
303 | e.printStackTrace();
304 | }
305 | }
306 |
307 | @Override
308 | public void onConfigureFailed(final CameraCaptureSession session) {
309 |
310 | }
311 | };
312 |
313 | }
314 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/droid_lister.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #DDDDDD
7 | #FFFFFF
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VRDroid-Camera
3 | 继续按返回键退出
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
4 | mavenCentral()
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle-experimental:0.7.3'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
15 | mavenCentral()
16 | jcenter()
17 | }
18 | }
19 |
20 | task clean(type: Delete) {
21 | delete rootProject.buildDir
22 | }
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 | org.gradle.jvmargs=-Xmx2048M
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 23 10:48:47 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/libraries/audio/audio.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/audio/audio.aar
--------------------------------------------------------------------------------
/libraries/audio/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('audio.aar'))
--------------------------------------------------------------------------------
/libraries/base/base.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/base/base.aar
--------------------------------------------------------------------------------
/libraries/base/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('base.aar'))
--------------------------------------------------------------------------------
/libraries/common/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('common.aar'))
--------------------------------------------------------------------------------
/libraries/common/common.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/common/common.aar
--------------------------------------------------------------------------------
/libraries/commonwidget/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('commonwidget.aar'))
--------------------------------------------------------------------------------
/libraries/commonwidget/commonwidget.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/commonwidget/commonwidget.aar
--------------------------------------------------------------------------------
/libraries/controller/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('controller.aar'))
--------------------------------------------------------------------------------
/libraries/controller/controller.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/controller/controller.aar
--------------------------------------------------------------------------------
/libraries/panowidget/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('panowidget.aar'))
--------------------------------------------------------------------------------
/libraries/panowidget/panowidget.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/panowidget/panowidget.aar
--------------------------------------------------------------------------------
/libraries/videowidget/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.create("default")
2 | artifacts.add("default", file('videowidget.aar'))
3 |
--------------------------------------------------------------------------------
/libraries/videowidget/videowidget.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babysource/VRDroid/93bd16e55cba36c08e93044fa97aed2916623af2/libraries/videowidget/videowidget.aar
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':app-malivr'
3 | include ':app-rajawali'
4 | include ':app-vrwidget'
5 | include ':libraries:base'
6 | include ':libraries:audio'
7 | include ':libraries:common'
8 | include ':libraries:controller'
9 | include ':libraries:panowidget'
10 | include ':libraries:videowidget'
11 | include ':libraries:commonwidget'
12 |
--------------------------------------------------------------------------------