SurfaceTextureレンダラ ( 画像を1度だけ画面に描画 )
SurfaceTexture に出力した画像を、画面に描画する方法を解説します。
本項では、画像を1度だけ画面に描画するSurfaceTextureレンダラを作成します。
解説
大きな処理の流れは以下です。
- SurfaceからCanvasを取得し、Canvasの描画命令を用いて画像を描画します。結果として、SurfaceTexture の画像が更新されます。
- SurfaceTexture の画像が更新されると、onFrameAvailable コールバック関数が呼び出されます。
- onFrameAvailable コールバック関数の呼び出しをトリガとして、updateTexImage関数を呼び出します。
- updateTexImage 関数を呼び出すと、SurfaceTexture に出力した画像が、GLESの外部テクスチャとして使用できるようになります。
- GLESの描画命令を用いて、GLESの外部テクスチャを、画面に描画します。
実装
アプリの仕様
- アプリを起動すると、メインアクティビティが表示される。
- 背景色は、灰色。
- 左上座標値 ( 200, 300 )、右下座標値 ( 400, 600 )、赤色で塗りつぶしの矩形が表示される。
- 中心座標値 ( 400, 600 )、半径 200、緑色で、線の太さ30の円が表示される。
プロジェクトの作成
(開発環境としては、Android Studio 4.2.2 を使用しています)
(この設定でプロジェクトを作成しなければいけない、というわけではありません。)
「Welcome to Android Studio」画面の「Create New Project」をクリックします。
「Empty Activity」を選択し、「Next」ボタンを押します。
Nameに、「SurfaceTextureRendererTest」と入力します。
Package nameのドメイン部分に、会社のドメイン名を指定します。
Save locationに、プロジェクトを保存するフォルダパスを指定します。
Minimum SDKを選択します(たとえば、「API 23: Android 6.0 (Marshmallow)」)。
「Finish」ボタンを押します。
しばらく待ちます。
Android Studio のステータスバーに「Gradle sync finished in ・・・」や「*daemon started
successfully ・・・」と出るまで待ちます。
以上で、プロジェクトができました。
クラスファイルの作成
2つのクラスファイルを作成します。
①便利関数を集めたユーティリティクラス ( MyUtilsクラス )
②SurfaceTextureレンダラクラス ( SurfaceTextureRendererクラス )
①便利関数を集めたユーティリティクラス ( MyUtilsクラス )の作成
「Project」ペインの「app > java > パッケージ名」を右クリックします。
右クリックメニュー「New > Java Class」を選択します。
クラス名欄に「MyUtils」と入力しエンターキーを押します。
(変更なし)
「OK」ボタンを押します。
「MyUtils」クラスファイルができました。
②SurfaceTextureレンダラクラス ( SurfaceTextureRendererクラス )の作成
「Project」ペインの「app > java > ドメイン.パッケージ名」を右クリックします。
右クリックメニュー「New > Java Class」を選択します。
クラス名欄に「SurfaceTextureRenderer」と入力しエンターキーを押します。
INTERFACES欄に「GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener」と入力します。
「OK」ボタンを押します。
「SurfaceTextureRenderer」クラスファイルができました。
ユーティリティクラス ( MyUtilsクラス )の定義
便利関数を集めたユーティリティクラス ( MyUtilsクラス )に以下の定義を追加します。
- Float型のバイト数定数
- GLESシェーダー読み込み関数
- GLESシェーダープログラムの作成関数
- GLESエラーチェック関数
クラス全体としては、以下のようにします。
「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
SurfaceTextureレンダラクラス ( SurfaceTextureRendererクラス )の定義
SurfaceTextureレンダラクラス ( SurfaceTextureRendererクラス )に、以下の定義を追加します。
- コンストラクタ関数
- 「GLSurfaceView.Renderer」インターフェースで定義されている「onSurfaceCreated」「onSurfaceChanged」「onDrawFrame」の3つの関数
- 「SurfaceTexture.OnFrameAvailableListener」インターフェースで定義されている「onFrameAvailable」関数
- Surfaceでの描画関数
処理の流れは、以下です。
- SurfaceTextureをインスタンス化の際に、コンストラクタ関数が呼ばれます。コンストラクタ関数では、でメンバー変数の初期化を行います。
- アプリケーションが開始した際や、一時停止状態から再開した際に、onSurfaceCreated関数が呼ばれます。onSurfaceCreated関数では、GLESの初期化処理、および、SurfaceTextureとSurfaceの作成を行います。
- アプリケーションが開始した際や、一時停止状態から再開した際や、画面の向きを変更した際に、onSurfaceChanged関数が呼ばれます。onSurfaceChanged関数では、ビューポート設定処理、テクスチャの大きさの変更処理、および、「Surfaceでの描画」関数呼び出しを行います。
- 「Surfaceでの描画」関数では、SurfaceからCanvasを取得し、Canvasの描画命令を用いて画像を描画します。結果として、SurfaceTexture の画像が更新されます。
- SurfaceTexture の画像が更新されると、onFrameAvailable コールバック関数が呼び出されます。
- onFrameAvailableコールバック関数では、m_bNewFrameAvailableのフラグを立てます。
- onDrawFrame関数は、高頻度で繰り返し呼び出されます。m_bNewFrameAvailableのフラグが立っているときは、SurfaceTextureの画像が変わっているので、onDrawFrame関数では、updateTexImage関数を呼び出し、m_bNewFrameAvailableのフラグを倒します。
- updateTexImage関数を呼び出すと、SurfaceTexture に出力した画像が、GLESの外部テクスチャとして使用できるようになります。
- onDrawFrame関数では、GLESの描画命令を用いて、GLESの外部テクスチャを、画面に描画します。
クラス全体としては、以下のようにします。
「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
レイアウトの変更
メインアクティビティのレイアウトを変更します。
「Project」ペインの「app > res > layout > activity_main.xml」を開きます。
「Code」タブをクリックし、コードビューに変更します。
「TextView」定義を削除します。
「GLSurfaceView」定義を追加します。
activity_main.xmlの内容を以下のようにします。
メインアクティビティクラスの変更
メインアクティビティの、onCreate関数内で、以下を行います。
- GLSurfaceVeiwオブジェクトを取得します。
- GLESバージョンとしてGLES 2.0 を指定します。
- 「SurfaceTextureRenderer」クラスのオブジェクトを生成します。
- 3.で生成した「SurfaceTextureRenderer」オブジェクトを、1.で取得したGLSurfaceViewオブジェクトに、setRenderer関数でセットします。
- GLSurfaceViewの描画モードは、「絶え間なく描画するというモード」と「描画要求があったときだけ描画するというモード」があります。「絶え間なく描画するというモード」にします。
GLSurfaceViewクラスのオブジェクトメンバー変数を追加します。
メインアクティビティに、「初回表示時、および、ポーズからの復帰時」に呼ばれる関数である onResume関数と、「別のアクティビティ(か別のアプリ)に移行したことで、バックグラウンドに追いやられた時」に呼ばれる関数である
onPause関数を追加します。
クラス全体としては、以下のようにします。
「Cannot resolve symbol」エラーは、「Alt + Enter」で、必要なクラスをimportします。
リビルドし、エラー、警告がないことを確認します。
実行
Android端末にて、動作確認。
アプリを起動すると、メインアクティビティが表示されます。
背景色は、灰色。
左上座標値 ( 200, 300 )、右下座標値 ( 400, 600 )、赤色で塗りつぶしの矩形が表示されます。
中心座標値 ( 400, 600 )、半径 200、緑色で、線の太さ30の円が表示されます。
ダウンロード
関連ページ
SurfaceTextureレンダラ ( 画像を1度だけ画面に描画 ) - 本ページ
SurfaceTextureレンダラ ( 連続画像を画面に描画 )
SurfaceTextureレンダラ ( 頂点バッファオブジェクトの利用 )