AGAL入門 #5 : StarlingでAGAL2、AGAL3のコードを動かす


Starlingでバージョン2以降のAGALコードを動かしたい場合、そのまま記述するとエラーになってしまう事があります。動かすための設定をメモがてら投稿しておきます。


エラーの一例

Starling2の場合

AGALバージョン指定してAssembleする

Starling2.0でカスタムフィルタなりカスタムスタイルなりを作る場合、Programクラスにて頂点および断片シェーダーのAGALコードをバイナリコードに変換している箇所があります。ここの第三引数がAGALのバージョン数なので、2を指定するとうまく動くようになります。簡単ですね。

sample.as
return Program.fromSource(vertexShader, fragmentShader, 2);

しかしながら、レジスタの範囲をAGAL3範囲まで利用すると、上記でバージョン3を指定してもエラーになってしまいます。処理をAGALMiniAssemblerまで追っていくと、どうもバージョン3指定であっても、バージョン2のレジスタ数でエラーチェックがなされている模様です。回避策として、上記を下記のように書き換えます。

sample.as
if(!_assembler) {
  _assembler = new AGALMiniAssembler();
}
return new Program(
  _assembler.assemble(Context3DProgramType.VERTEX, vertexShader, 3, true),
  _assembler.assemble(Context3DProgramType.FRAGMENT, fragmentShader, 3, true)
);

AGALMiniAssemblerのassembleメソッドの第三引数が、レジスタ数チェックを1024まで緩くする引数となっています。厳密なレジスタ数をみてくれなくなりますが、とりあえず動くようにはなります。

Starling1.xの場合

FragmentFilterのassembleAgalおよびRenderSupport.assembleAgalあたりで同様にAGALMiniAssemblerでのAssembleをやっているようですが、バージョン指定ができません。

ここはStarling側のソースを書き換えてやるしかない気がします。

Stage3Dのプロファイルを正しく選択する

それでもうまく動かない場合、Stage3Dのプロファイル指定が利用したいAGALとずれているのかもしれません。エラー文言が下記のような感じになっていないでしょうか。

error.txt
Error: Error #3725: The requested AGAL version (3) is not valid under the Context3D profile. For example AGAL version 2 requires standard profile.
    at flash.display3D::Program3D/upload()

Starling初期化後(メインクラスのインスタンス化後)であれば、下記のようにして現在のProfile名が確認できます。

sample.as
trace("Stage3D profile:", _starling.profile);

Starling2ではProfileを指定しない限り、高機能な順でProfileを利用しようとします。よって開発環境によっては、同じコードでもAGAL2や3のコードが動かなくなる場合があるわけです。

  • Context3DProfile.STANDARD_EXTENDED ... 最新スマホとかでつかえる AGAL3用
  • Context3DProfile.STANDARD ... AGAL2用
  • Context3DProfile.STANDARD_CONSTRAINED ... AGAL2用 standardの制限版 2015年初頭でiOSの90%ほどをカバー
  • Context3DProfile.BASELINE_EXTENDED ... AGAL1用のちょっといいやつ
  • Context3DProfile.BASELINE ... AGAL1用
  • Context3DProfile.BASELINE_CONSTRAINED ... AGAL1用 かなり古い環境用

各Profileとレジスタ数の関係は自分の前の投稿 AGAL入門 #4 : 各AGALバージョン (Stage3D Profile) ごとのレジスタ数 にまとめてあります。

Starlingのインスタンス化の際にStage3Dのプロファイルを指定する事もできます。指定したプロファイルが利用できないと(非同期の)エラーになりますが、AGALコードが実際に動くまで適切なProfileで動いていない事がわからないより、初期化のタイミングでエラーになったほうが良いかもしれません。

sample.as
var profiles:Array = ["standardConstrained"]; //for AGAL2
var starling:Straling = new Starling(HogeClass, stage, null, null, null, profiles );

捕捉

今回の投稿で検証したStarlingのバージョンは2.0.1と1.8です。Starling2はまだちょいちょい細かい修正アップデートがされているようです。2.0.2以降で状況変わるかもしれないのでご注意を。