今回はNimとSDL2を使って、PNG画像の読込と表示の検証を行います。
前回、SDL2を使った図形の描画までは出来たので、あとはPNG画像をロードして、表示すれば良いだけだから、そんなに手間はかからないだろうと高を括っていましたが、しかしながら今回も結構ハマりました。
表示させる画像のサンプルとして、以下2枚の画像を用意しました。
手持ちの写真から切り抜いたカニの画像と、適当に作ったロゴになります。 アルファチャンネルも機能するか確認しておきたいので、ロゴは半透明の状態にしてあります。
こちらのファイルは、assets という名前のフォルダに格納しておきます。
早速コードを作っていきます。
今回、こちらのサンプルコードがとても役に立ちました。
Jipok/Nim-SDL2-and-Emscripten
これを参考にしつつ、前回のコードを修正したものがこちらになります。
ポイントとしては、従来の sdl ライブラリに加えて、sdl2/image ライブラリを新たにインポートしているところでしょうか。
あとは、TexturePtrオブジェクトに画像をロードして、それを描画しているだけです。
今回悩んだのは、ソースでは無くてコンパイルオプションの設定でした。
最終的な nim.cfg はこのような形にになりました。
ソースコードで、使用するライブラリに sdl2/image を追加しましたが、実際に使用するためにはライブラリをリンクする設定を行う必要があり、d = "use_sdl2_image", dynlibOverride = "SDL2_image", -s USE_SDL_IMAGE=2, -s SDL2_IMAGE_FORMATS=["png"] を、nim 及び Emscripten のオプションに追加してやる必要がありました。
この設定を行うと、初回コンパイル時に必要なライブラリが自動でダウンロードされます。
そのため、初回はコンパイルに結構な時間がかかるのと、オンラインで繋がっている環境で実行する必要があります。
Emscriptenで外部ファイルを扱う方法として、ファイル自体をコードに組み込む方法と、仮想ファイルシステムを使用する方法があるそうです。
--preload-file ../assets@/" を指定すると、コンパイル時に ../assets フォルダにあるファイルが仮想ファイルシステムのルートとしてマウントされ、プログラムからはローカルのファイルシステムをアクセスするのと同じ感覚で扱えます。
ただ、これはちょっと嫌ですね。
この方式でコンパイルすると、wasm_sdl02.data というファイルが作成されて、中には ../assets 以下のファイル全てが集約されています。
これを実行時に自動でキャッシュしてくれて、それにアクセスするような方式のようです。
これだと、初回に全てロードしなくてはならないし、容量が大きいとメモリも食うのでは。。。
必要な時に、必要なものだけをロードして使う方式の方が良いのですが。。。。
ネットで調べると、XMLHttpRequest とか使用すれば出来そうな感じもしますがちょっと大変そうなので今回はパス。 不本意ながら preload 形式で進める事とします。
2020/12/12追記
動的読込対応版をこちらの記事で記載しました。
[Live Demo]
出ました。
アルファチャンネルもきちんと機能しているようです。
今回作成したソースはこちら。
karasu-jp-com/wasm_sdl_nim/wasm_sdl02/
一括ダウンロードはこちら