openframeworksでシェーダーでライブコーディングしたり、デバッグのスピードを上げるためにファイルの保存を検知して、シェーダーをリロードできるようにしたいなと思って
コード
testApp.h
// デフォルトでは使えないのでヘッダーをインクルード
#include <sys/stat.h> // 注意点1
class testApp {
ofShader shader;
string shader_path; // シェーダーへの絶対パス
struct stat stat_buf; // stat使うためのやつ
time_t last_file_time; // ファイルの最終更新時間
// 以下略
}
testApp.cpp
void testApp::setup() {
shader_path = ofFilePath::getAbsolutePath("frag.frag", true); // 注意点2
shader.load("default.vert", shader_path);
stat(shader_path.c_str(), &stat_buf); // ファイル情報を取得
last_file_time = stat_buf.st_mtime; // ファイルの最終更新時間の初期値
cout << "last_file_time : " + ofToString(ctime(&last_file_time)) << endl; // 確認用 注意点3
// 以下略
}
void testApp::update() {
stat(shader_path.c_str(), &stat_buf);
if (stat_buf.st_mtime != last_file_time) { // 更新されたかチェック
cout << "shader changed" << endl;
cout << "current_file_time : " + ofToString(ctime(&stat_buf.st_mtime)) << endl; // 確認用
last_file_time = stat_buf.st_mtime; // ファイルの最終更新時間を更新
shader.load("default.vert", shader_path); // シェーダーを更新
};
// 以下略
}
// 以下略
注意点
- statはヘッダーをインクルードしないと使えません。
- 絶対パスじゃないと動いてくれないので、oFのメソッド(ofShaderのロードでも使われてるやつ)使います。
- ログに表示するときはstatのmtime使うと、人間が見られる形になります。
以上になります。訂正よろしくお願いします🙏