進捗置き場というわけでもない場所

プログラミングしてる中で見つけたこととか

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 の作者様から

このようなご指摘をいただきました。というわけで、特に「読み込んだ画像を編集したい!」のような場合以外は、TextureRegion を使用した

gist.github.com

(via Ryo Suzuki)

のような関数/コードを書くのが良いかと思われます。

結論

  • 昔書いた脳死コードを適当に人に上げない。
  • Texture の編集を特にしない場合、画像の一部分だけを扱いたいなら TextureRegion を使おう。

以上です。