Edited at

[openFrameworks] imguiで楽々save/load


はじめに

 oFにおけるsave/load機能を実装したい場合、ofxGuiとofxXmlSettingsでの実装が散見されるが、imguiでこれをやりたい。

cerealでもいいけど、ofParameterGroupに対応させるのめんどくさい。どうにか楽に実装できないか調べてみた。


結論

ofSerializeとofDeserializeを使う。

 とりあえず一番これが低カロリーで実装できた。ofParameterGroupにも対応。

何より、コアの機能で実現できたのでメンテナンスのコストもない。(わーい)


保存

ofJson json;

ofSerialize(json, parameter_group_);
ofSaveJson("settings.json", json);


呼び出し

ofJson json = ofLoadJson("settings.json");

ofDeserialize(json, parameter_group_);


How to Use

ofxImGuiと組み合わせて使うとこんな感じと思う。

class BaseLayer 

{
public:
BaseLayer(const std::string& unique_name)
: name_(unique_name)
{
parameter_group_.setName(name_);
}

void drawGui() {
auto Settings = ofxImGui::Settings();
ofxImGui::AddGroup(this->parameter_group_, Settings);

ImGui::Begin("Util");
if (ImGui::Button("Save")) {
ofJson json;
ofSerialize(json, parameter_group_);
ofSaveJson(name_ + "_settings.json", json);
}
if (ImGui::Button("Load")) {
ofJson json = ofLoadJson(name_ + "_settings.json");
ofDeserialize(json, parameter_group_);
}
ImGui::End();
}
std::string name_;
ofParameterGroup parameter_group_;
};

みたいに親クラスで実装して子クラスのコンストラクタで....

class MyGenLayer : public BaseLayer

{
MyGenLayer(const std::string& unique_name)
: BaseLayer(unique_name)
{
vec2_param.set("Emit Position", glm::vec2(5.0f, 5.0f), glm::vec2(0.0f, 0.0f), glm::vec2(12.0f, 12.0f));
vec3_param.set("Rotation", glm::vec3(5.0f, 5.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(12.0f, 12.0f, 12.0f));
parameter_group_.add(vec2_param);
parameter_group_.add(vec3_param);

ofJson json = ofLoadJson(name_ + "_settings.json");
ofDeserialize(json, parameter_group_);
}
void update() {}
void draw() {}

private:
//user define
ofParameter<glm::vec2> vec2_param;
ofParameter<glm::vec3> vec3_param;
};