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

うさがにっき

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

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

Android

概要

tiro105.hateblo.jp
の続き、native眺めてみまた&vulkan対応などの今後どうするのが正解なのか考えてみた

詳細

native層について

基本的にはOpenGLES 2の書き方をしているので、OpenGLES使える人はそんな困らないと思う(vulkan対応したソースとか欲しいけど)
ただGoogle VR関係のクラスを扱っている箇所があるのでそこだけ少し注意、けどこれまでcardboard作ってた人なら慣れてると思う

Activity側でのnativeの定義

  private native void nativeOnCreate(AssetManager assetManager, long gvrContextPtr);
  private native void nativeOnResume();
  private native void nativeOnPause();
  private native void nativeOnSurfaceCreated();
  private native void nativeOnSurfaceChanged(int width, int height);
  private native void nativeOnDrawFrame();
  private native void nativeOnDestroy();

long gvrContextPtrってのがGoogle VRクラスのポインタ、以前の記事であった以下のメソッドで該当箇所のポインタを取得している

gvrLayout.getGvrApi().getNativeGvrContext()


app_jni.hでは以下のように定義
この書き方すれば何個もメソッドの入り口作らなくていい、賢い

#define NATIVE_METHOD(return_type, method_name) \
  JNIEXPORT return_type JNICALL                 \
      Java_com_google_vr_ndk_samples_controllerpaint_MainActivity_##method_name

extern "C" {

NATIVE_METHOD(void, nativeOnCreate)(JNIEnv* env, jobject obj,
                                    jobject asset_mgr, jlong gvrContextPtr);
NATIVE_METHOD(void, nativeOnResume)(JNIEnv* env, jobject obj);
NATIVE_METHOD(void, nativeOnPause)(JNIEnv* env, jobject obj);
NATIVE_METHOD(void, nativeOnSurfaceCreated)(JNIEnv* env, jobject obj);
NATIVE_METHOD(void, nativeOnSurfaceChanged)(JNIEnv* env, jobject obj,
                                            jint width, jint height);
NATIVE_METHOD(void, nativeOnDrawFrame)(JNIEnv* env, jobject obj);
NATIVE_METHOD(void, nativeOnDestroy)(JNIEnv* env, jobject obj);

}


gvrContextPtrをもってるnativeOnCreateを追う
CHECKではちゃんとオブジェクトが入ってるか見てるだけっぽい
app_jni.cc

NATIVE_METHOD(void, nativeOnCreate)(JNIEnv* env, jobject obj,
                                    jobject asset_mgr, jlong gvr_context_ptr) {
  CHECK(!demo_app_);
  CHECK(gvr_context_ptr);
  demo_app_.reset(new DemoApp(env, asset_mgr, gvr_context_ptr));
}


見るべきはgvr_context_ptr周り
扱えるようにキャストした後、gvr_apiオブジェクト取得している
特にdaydreamを意識したソースは無いように見える
gvr::GvrApi Class Reference  |  Google VR  |  Google Developers
demoapp.cc

DemoApp::DemoApp(JNIEnv* env, jobject asset_mgr_obj, jlong gvr_context_ptr)
    :  // This is the GVR context pointer obtained from Java:
      gvr_context_(reinterpret_cast<gvr_context*>(gvr_context_ptr)),
      // Wrap the gvr_context* into a GvrApi C++ object for convenience:
      gvr_api_(gvr::GvrApi::WrapNonOwned(gvr_context_)),
      gvr_api_initialized_(false),
      shader_(-1),
      shader_u_color_(-1),
      shader_u_mvp_matrix_(-1),
      shader_u_sampler_(-1),
      shader_a_position_(-1),
      shader_a_texcoords_(-1),
      ground_texture_(-1),
      paint_texture_(-1),
      asset_mgr_(AAssetManager_fromJava(env, asset_mgr_obj)),
      recent_geom_vertex_count_(0),
      brush_stroke_total_vertices_(0),
      selected_color_(0),
      painting_(false),
      has_continuation_(false),
      switched_color_(false),
      stroke_width_(kMinStrokeWidth) {
  CHECK(asset_mgr_);
  LOGD("DemoApp initialized.");
}


全体を眺めたがOpenGLES2で描画している処理がほとんどで、他もdaydreamを意識したソースはなかったため解説は割愛

daydream開発の現場、今後

現在展開されているdaydream sampleは前述の通りopenGLES2を使ってGoogle VRでのVRを実現している
java側でdaydreamモードをONにすることにしても描画がopenGLES2であるならどれほど恩恵が得られるか少し疑問が残る(コントローラーが使えるくらいじゃ無いのか?)
やはり現状はvulkanを使ったサンプルが出るまで少し待つ、それか今はjava層だけに目を向けて置いてvulkanの書き方を身につけておくのがいいかもしれない

もしくはUnityやUnreal EngineのVulkan対応を待つという手もある
両方ともdaydreamでのvulkan対応を表明しているため今のうちに各IDEでのdaydreamの書き方を勉強しておけば後々vulkan対応時に焦らず対応できそう
Make your Daydreams a reality – Unity Blog
Vulkan Support Coming Daydream via Unreal Engine | VRFocus

こんな感じでボタンひとつで設定できるととても楽できて嬉しい
Unity - マニュアル: iOS Player Settings

感想

結論としてはvulkan対応のベストプラクティスが謎の現在ではdaydreamの本格的な開発はまだ早いと思われる
しかしvulkan自体のサンプルは公開されているのでvulkanの書き方を事前に学んでおくなどの事前準備は十分にできそう
Unityではdaydream sampleも公開されているので今のうちに書き方を習得しておけばvulkan対応もすぐできるだろう