さっき決めたブログ

[Nim]NimとSDL2を使ってWebAssemblyからPNGを描画

2020年12月5日 2:39 PM0519NimPROGRAMNimWebAssemblyEmscriptensdl2PNG

今回はNimとSDL2を使って、PNG画像の読込と表示の検証を行います。

前回、SDL2を使った図形の描画までは出来たので、あとはPNG画像をロードして、表示すれば良いだけだから、そんなに手間はかからないだろうと高を括っていましたが、しかしながら今回も結構ハマりました。

元画像の用意

表示させる画像のサンプルとして、以下2枚の画像を用意しました。

kani.png
nim_sdl_test.png

手持ちの写真から切り抜いたカニの画像と、適当に作ったロゴになります。 アルファチャンネルも機能するか確認しておきたいので、ロゴは半透明の状態にしてあります。

こちらのファイルは、assets という名前のフォルダに格納しておきます。

早速作る

早速コードを作っていきます。

今回、こちらのサンプルコードがとても役に立ちました。
Jipok/Nim-SDL2-and-Emscripten

これを参考にしつつ、前回のコードを修正したものがこちらになります。

ポイントとしては、従来の sdl ライブラリに加えて、sdl2/image ライブラリを新たにインポートしているところでしょうか。
あとは、TexturePtrオブジェクトに画像をロードして、それを描画しているだけです。

コンパイルオプション

今回悩んだのは、ソースでは無くてコンパイルオプションの設定でした。
最終的な nim.cfg はこのような形にになりました。

SDL IMAGEを使用するための設定

ソースコードで、使用するライブラリに sdl2/image を追加しましたが、実際に使用するためにはライブラリをリンクする設定を行う必要があり、d = "use_sdl2_image", dynlibOverride = "SDL2_image", -s USE_SDL_IMAGE=2, -s SDL2_IMAGE_FORMATS=["png"] を、nim 及び Emscripten のオプションに追加してやる必要がありました。
この設定を行うと、初回コンパイル時に必要なライブラリが自動でダウンロードされます。
そのため、初回はコンパイルに結構な時間がかかるのと、オンラインで繋がっている環境で実行する必要があります。

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/
一括ダウンロードはこちら

参考文献

Jipok/Nim-SDL2-and-Emscripten
https://github.com/Jipok/Nim-SDL2-and-Emscripten

投稿者プロフィール

KARASU
うーん いろいろ考え中。。。

コメント

コメント取得中...

関連記事

TOPへ