読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

daydream現状まとめ、サンプルソース眺めた感想(java層)

www.youtube.com

概要

daydream気になる、けど現状どうなの?開発行ける雰囲気?
2016/7/16時点での雰囲気を掴む
サンプルコードあったら読んでみる

詳細

情報

qiita16件、けどだいたいGoogleIO軽くまとめた感じの記事
「daydream」の検索結果 - Qiita
stackoverflow161件、あんまり盛り上がってないかな?
Human Verification - Stack Overflow
公式情報
Developer Overview  |  Google VR  |  Google Developers
リンク切れてるところもところどころあるけどだいたい雰囲気でわかる

開発環境

Android or Unity
とりあえずAndroidで試してみる

daydream環境

daydreamはヘッドセット&コントローラーが別売りでそれにAndroidをセッティングして使用する
ヘッドセット、コントローラーはまだ買えない

現状開発環境として必要なのはコントローラー用のAndroidエミュレータとVR表示用Androidの2台

コントローラ側AndroidはNじゃなくても大丈夫、端末もそれほどスペックを要求しない
VR側はNexus6PかつN preview4以上推奨、5xでも起動はしたけど端末が発熱するだけで全然動かなかった。。。

apkとか

コントローラーはAndroid用のエミュレーターがapkとして配布されていたはず・・・なのだが公式サイトから飛んだ先が404ニナッテル
設定手順
Set up a Daydream Development Kit  |  Google VR  |  Google Developers

apk(無いよ)
https://github.com/googlevr/gvr-android-sdk/blob/master/ndk-beta/apks/controller_emulator.apk?raw=true


困った、探した、(それっぽいの)あった
gvr-android-sdk/apks at master · googlevr/gvr-android-sdk · GitHub
apkのみ

VR側も404になってるけど多分これ
gvr-android-sdk/ndk-beta/demos/controllerpaint at master · googlevr/gvr-android-sdk · GitHub
ソース見れる!

ソース解析

Activityは1つ

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setImmersiveSticky();
    getWindow()
        .getDecorView()
        .setOnSystemUiVisibilityChangeListener(
            new View.OnSystemUiVisibilityChangeListener() {
              @Override
              public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                  setImmersiveSticky();
                }
              }
            });

    // Enable VR mode, if the device supports it.
    AndroidCompat.setVrModeEnabled(this, true);
    // Get the GvrLayout.
    gvrLayout = new GvrLayout(this);

    // Enable scan line racing, if possible.
    if (gvrLayout.setScanlineRacingEnabled(true)) {
      Log.d(TAG, "Successfully enabled scanline racing.");
      // Scanline racing decouples the app framerate from the display framerate,
      // allowing immersive interaction even at the throttled clockrates set by
      // sustained performance mode.
      AndroidCompat.setSustainedPerformanceMode(this, true);
    } else {
      Log.w(TAG, "Failed to enable scanline racing.");
    }

    // Configure the GLSurfaceView.
    surfaceView = new GLSurfaceView(this);
    surfaceView.setEGLContextClientVersion(2);
    surfaceView.setEGLConfigChooser(8, 8, 8, 0, 0, 0);
    surfaceView.setPreserveEGLContextOnPause(true);
    surfaceView.setRenderer(renderer);

    // Set the GLSurfaceView as the GvrLayout's presentation view.
    gvrLayout.setPresentationView(surfaceView);

    // Enable and configure the back button in the UI layout.
    gvrLayout
        .getUiLayout()
        .setBackButtonListener(
            new Runnable() {
              @Override
              public void run() {
                onBackPressed();
              }
            });

    // Add the GvrLayout to the View hierarchy.
    setContentView(gvrLayout);

    assetManager = getResources().getAssets();

    nativeOnCreate(assetManager, gvrLayout.getGvrApi().getNativeGvrContext());

    // Prevent screen from dimming/locking.
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

setImmersiveStickyでフルスクリーン表示に

private void setImmersiveSticky() {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
  }


AndroidCompat.setVrModeEnabledはGoogle VR SDKのメソッド
AndroidCompat  |  Google VR  |  Google Developers
N+であればVRモードになる
例えばコントローラーが使えるようになったりする、これでdaydream modeになるってことでいいのかな?


GvrLayoutはGoogle VR SDKにあるlayout
GvrLayout  |  Google VR  |  Google Developers
中身はだいたいsurfaceview, GLSurfaceviewにしてVRを表現するらしい
こんな感じ

gvrLayout.setPresentationView(surfaceView);


また、GvrLayoutから取得できるGvrApiを使えばステレオVRなどが簡単に設定できるらしい・・・けどこれnativeでなんか書いて設定してるって感じに見える
GvrApiはポイントになりそう
GvrApi  |  Google VR  |  Google Developers

gvrApi = gvrLayout.getApi();
nativeOnDrawFrame(gvrApi.getNativeGvrContext());


スマホの動きが検知できてるか確認
動きが検知できたらsustainedperformancemodeなるものにする、なんだろこれ

   // Enable scan line racing, if possible.
    if (gvrLayout.setScanlineRacingEnabled(true)) {
      Log.d(TAG, "Successfully enabled scanline racing.");
      // Scanline racing decouples the app framerate from the display framerate,
      // allowing immersive interaction even at the throttled clockrates set by
      // sustained performance mode.
      AndroidCompat.setSustainedPerformanceMode(this, true);
    } else {
      Log.w(TAG, "Failed to enable scanline racing.");
    }

GLSurfaceView設定
GLSurfaceViewについては以下
GLSurfaceView | Android Developers

setEGLContextClientVersion指定してるってことはVulkan使ってないのかな?
nativeざっと眺めてもvk系の関数はなかった

    // Configure the GLSurfaceView.
    surfaceView = new GLSurfaceView(this);
    
    surfaceView.setEGLContextClientVersion(2);
    surfaceView.setEGLConfigChooser(8, 8, 8, 0, 0, 0);
    surfaceView.setPreserveEGLContextOnPause(true);
    surfaceView.setRenderer(renderer);


renderは以下の感じでnativeでやってる

  private final GLSurfaceView.Renderer renderer = new GLSurfaceView.Renderer() {
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
      nativeOnSurfaceCreated();
    }
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
      nativeOnSurfaceChanged(width, height);
    }
    @Override
    public void onDrawFrame(GL10 gl) {
      nativeOnDrawFrame();
    }
  };


Gvrlayoutを使うとデフォルトでバックボタンが効かなくなるらしい
GvrUiLayout  |  Google VR  |  Google Developers
のでわざわざイベントとってonBackPressedしてる

    // Set the GLSurfaceView as the GvrLayout's presentation view.
    gvrLayout.setPresentationView(surfaceView);

    // Enable and configure the back button in the UI layout.
    gvrLayout
        .getUiLayout()
        .setBackButtonListener(
            new Runnable() {
              @Override
              public void run() {
                onBackPressed();
              }
            });

    // Add the GvrLayout to the View hierarchy.
    setContentView(gvrLayout);

    assetManager = getResources().getAssets();

    nativeOnCreate(assetManager, gvrLayout.getGvrApi().getNativeGvrContext());

    // Prevent screen from dimming/locking.
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  }

わからないこと

  • 公式からのサンプルリンク切れてたけどもっといいサンプルがどこかにあるのか?
  • google vr sdkで作れるよ!って言ってるけどcardboardとの違いはsetVrModeEnabledでいいのか?

感想

ドキュメントがリンク切れがあったりするがAPI Documentは割としっかりしてたので思ってたより理解できた
java層読むだけでも勉強になる
時間あったらcpp層も読んでみよう
これでOpen GLES層が既存とあまり変わってないならJava層少し触るだけでdaydream対応できるってことになるのでCardboardアプリが簡単にdaydream対応できるかも?