Aqoole_Hateenaの技術日記

vulkan+raytraceで色々描いてます

popup windowの表示方法

動機

C/C++コード出身の人がndkを用いてandroidでコーディングする際に、追加情報などを画面に表示したいという需要はあると思う。
とりあえずコードがコンパイルできてプログラムが実行できれば、そこからは何とか勉強できる、というのが持論なので、ちょうどよさそうなサンプルコードを探していた。

サンプルコード

ndk samplesという、androidの公式が出しているサンプルコード集がある。
その中のteapotsというプロジェクトで、現在のFPSをpopup windowで表示するということを行っている。
Sample: Teapot  |  Android NDK  |  Android Developers
Giuhub Sampleはこちら
ndk-samples/teapots at main · android/ndk-samples · GitHub
おそらく権限の関係で公式のrepositoryから直接cloneできないので、私は一旦自分のrepositoryにforkしてからgit cloneした。

TeapotNativeActivity.java

このクラスに含まれている

public void showUI()

という関数がある。これがpopup windowを表示させる関数であるが、これをC++のコード側から呼び出す。

TeapotNativeActivity.cpp

ここでEngineというクラスの中でShowUI()という関数が用意されている。

void Engine::ShowUI() {
  JNIEnv* jni;
  app_->activity->vm->AttachCurrentThread(&jni, NULL);

  // Default class retrieval
  jclass clazz = jni->GetObjectClass(app_->activity->clazz);
  jmethodID methodID = jni->GetMethodID(clazz, "showUI", "()V");
  jni->CallVoidMethod(app_->activity->clazz, methodID);

  app_->activity->vm->DetachCurrentThread();
  return;
}

このような形で、これをmain関数の中で呼び出す。

updateFPS()

popup windowでwindowを作成した後は、そこに値を書き込む準備が必要である。
showUIと同じ要領でupdateFPSを、C++で呼び出して値を渡す。
今回はupdateなので、main loopの中で呼び出して値を更新する。

表示例

vulkanで試しているが、このように表示させることができる。
画面では、たくさんのcubesと左上にFPS表示をさせている。

f:id:Aqoole_Hateena:20220321194623p:plain
cubes + fps

あとがき

popup windowについて調査した理由

最初はimguiでデバッグ情報やinteract部分を担えるようなボタンやwindowを作成しようと思っていたが、これがなかなかに難航した。
single windowで、ユーザ定義の図形とimguiの図形の両方をレンダリングしようとすると、imageが交互に切り替わるような感じになり、非常に画面がチラつく。
ひとつのwindowにはひとつのswapchainしか作成できないので、swapchainを複数作成するという方法も不可能である。
複数作成しようとすると、VK_ERROR_NATIVE_WINDOW_IN_USE_KHRというエラーが表示される。
案としてはview portを変えて、ユーザ定義の領域とimguiのボタン用の領域を分けるか、新たにwindowを作成するかがあると思ったが、window作成の方が色々小回りが利くと思い、popup windowの作成方法を調べてみた。
このwindow領域にimguiのレンダリングが可能かどうかは、今後調べる必要がある。

git hub repository

上記のようなandroid + vulkanで色々描いている私のrepositoryはこちら
https://github.com/kodai731/Aqoole-Engine-Android-Vulkan-Rendering-Engine-