Siv3DでDxLibのLoadDivGraphみたいなことをする
久々にブログを書く話題がこんな小ネタというのもなんですが、地味に求められているらしいので書いておきます。
DxLib の LoadDivGraph 関数
皆さんご存知 DxLib には、指定した画像を適当なピクセル数で分割して読み込む、LoadDivGraphという関数が存在します。
関数名がゴミとかそういう話もしたいのですがグッとこらえて先に進むと、どうも gif の代わりにアニメーション用の連続した画像を格納するときとかに便利らしく、Siv3D でもそんな関数がほしいという声が散見された[要出典]ので、前に書いた Siv3D での実装を載せたいと思います。
方針&ソース
Image を読み込んで、Image::clipped 関数で指定された大きさのピクセルを切り取っていき、それぞれをTextureに変換していく感じです。
こういうところで step(Size) とかが使えると気持ちいいですね。
ちなみにコメント中の RVO とは Return Value Optimization の略で、関数の戻り値のコピーを消す最適化のことです。C++17 からは絶対にこの最適化が行われるようになります(詳しくはこのへんとかこのへんを読んで下さい)。
// image を大きさ size の画像に分割 Array<Texture> makeDividedTexture(const Image& image, const Size& size) { // 分割数 const Size numDiv{ image.size.x / size.x, image.size.y / size.y }; Array<Texture> result; result.reserve(numDiv.x * numDiv.y); for (auto&& p : step(numDiv)) result.emplace_back(image.clipped(size * p, size)); // RVO で消える return result; }
…とかいう事を書いている最中に、Siv3D の作者様から
必要なのはこのような関数ではないですか? https://t.co/PtIeDIAkNd Texture を複数作るのは実行時性能的に不利です。Texture から TextureRegion を作れば、作成されるのは 1 つの Texture で済みます。
— Ryo Suzuki (@Reputeless) 2017年6月12日
複数 Texture にすれば、mip フィルタ時に隣接する色の影響を受けずに済んだり、repeat できたりという、TextureRegion にはないメリットがあるので、必要になることもあるかもです。
— Ryo Suzuki (@Reputeless) 2017年6月12日
このようなご指摘をいただきました。というわけで、特に「読み込んだ画像を編集したい!」のような場合以外は、TextureRegion を使用した
(via Ryo Suzuki)
のような関数/コードを書くのが良いかと思われます。
結論
- 昔書いた脳死コードを適当に人に上げない。
- Texture の編集を特にしない場合、画像の一部分だけを扱いたいなら TextureRegion を使おう。
以上です。