GILでPNGの読み込み

ショボイ原因も分かったところで、Boost.GILでのPNGの読み込み解説です。

#include "png_loader.hpp"
#include <boost/gil/extension/io/png_io.hpp>
#include <boost/gil/image_view_factory.hpp>

namespace gil = boost::gil;

direct3d_texture9
create_png_texture(direct3d_device9& device, const std::string& filename)
{
    // 画像サイズを取得
    const gil::point2<std::ptrdiff_t>& dim
        = boost::gil::png_read_dimensions(filename);

    // テクスチャを準備
    direct3d_texture9 texture =
        device.create_texture(
            dim.x, dim.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED
        );

    // テクスチャをロックして生メモリを取得
    direct3d_texture9::scoped_lock locking(texture, 0);

    // リトルエンディアン32ビットでARGBなので、GILではbgra8
    typedef gil::bgra8_pixel_t pixel_t;
    typedef gil::type_from_x_iterator<pixel_t*>::view_t view_t;

    // インタリーブビューを作成
    view_t out = gil::interleaved_view(
        dim.x, dim.y,
        static_cast<pixel_t*>(locking.address()),   // 生メモリ
        locking.pitch()                             // 幅+パディング
    );

    // ピクセルフォーマットを変換しながら読み込み
    gil::png_read_and_convert_view(filename, out);

    return texture;
}

読み込みに際して、PNGとテクスチャのピクセルフォーマットが違うのでフォーマットの変換が必要です。
そのものズバリpng_read_and_convert_view()という関数があるのでこれを使っています。


ちなみに、最初24ビット+透過色のPNGで試していたのですが、今のところGILが透過色に対応していないようで、結局アルファチャネル付きの32ビットカラーを使いました。