imguiでofImageをできるだけ簡単に表示する

ofxImGuiでofImageを表示する

imguiはテクスチャIDをopenGL/DirectXにそれぞれ対応するようになっているので、ofxImGuiがofImageを読み込めるようなメソッドを用意してくれている。なので

ofxImGui::Gui gui;
ofImage image;
ImTextureID texId = gui.loadImage(image);

//======以下描画

gui.begin();
ImGui::Image(texId, ImVec2(image.getWidth(), image.getHeight());
gui.end();

とすりゃ表示できるんだけど、画像一枚出すのに手数がやや多い気がする。たくさんあるとだるい…

ofImageにimgui用の機能を足す

ようはARB拡張の無いテクスチャを作ってあげればよいので、その辺を良い感じにできる継承クラスを作る

    class guiImage : public ofImage{
    public:

        void ImLoadImage(string path) {
            ofDisableArbTex();
            ofImage::load(path);
            ofEnableArbTex();
        }

        ImTextureID ImGetTex() {
            return ImTextureID(getTextureReference().getTextureData().textureID);
        }

        ofVec2f getScale(float resize)
        {
            return ofVec2f(getWidth() * resize, getHeight() * resize);
        }
    };

こうしておけばArbのフラグを忘れることもないし、guiImageから必要なものは呼び出せるので、大分スッキリする。

//初期化
guiImage image;
image.ImLoadImage("sample.png");

//描画
Imgui::Image(image.ImGetTex(), image.getScale(1.0));

レイアウトを綺麗にするTips

ちなみにimageButtonを使うとマージンの設定が楽なので、中央に配置できる関数を作ったのでメモ。クラス名は当時のまんま

bool baseView::centeredImageButton(guiImage& icon, ofVec2f buttonScale, float imageScale)
{
    ofVec2f imageSize = icon.getScale(imageScale);
    ofVec2f padding = (buttonScale - imageSize) / 2.0;

    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, padding);
    ImGui::PushStyleColor(ImGuiCol_Button, ofFloatColor(0, 0));
    ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ofFloatColor(0, 0));
    ImGui::PushStyleColor(ImGuiCol_ButtonActive, ofFloatColor(0, 0));

    bool ret = ImGui::ImageButton(icon.ImGetTex(), imageSize);

    for (int i = 0;i < 3;i++) ImGui::PopStyleColor();
    ImGui::PopStyleVar();

    return ret;
}