C++上でライブラリとして提供される同様のものにはcinderやopenFrameworkといったものがあります.
特徴はやっぱり速いこと.
例えばProcessingと比べるとC++なので然るべきコーディングをすれば然るべき速度差で動きますし,何も考えなくともOpenGLでよろしく描画してくれるので,そこらのX11やGDIで動くGUIツールキットで頑張るのとは段違いの速度で動きます.
今cinderの人気が高まっている印象ですが,Linuxで使えない(無理ではないらしいけどタダではすまない)という僕にとってはとても残念なかんじなので,より歴史のある(らしい)openFrameworksを使ってみました.
で,実は2011年12月3日に開催される名古屋合同懇親会で,僕がこのネタでLTさせていただくことになってます.
よろしかったら直接おいでいただくかustで視聴してみてください.
NGK2011B 昼の部(LT大会) ←こっちでしゃべります
NGK2011B 夜の部(懇親会+野良LT大会)
以下面倒なので,openFrameworksをofxと略します.
環境構築
http://www.openframeworks.cc/downloadから適切に落としてきてください.
以下Ubuntu前提.
Ubuntuは11.10,Code::Blocksは10.05,ofxは0.07,gccは4.6.1です.
インストールについてはreadmeに全て書いてあるんですが,ちょっとビミョウなので,より適切と思われる方法を書いておきます.
各種パッケージのインストール
ofxを展開した中のscripts/linux/ubuntuにある
install_codeblocks.sh install_dependencies.sh install_codecs.sh
を順にrootで実行するだけ.
見ての通り,Code::Blocksがインストールされます.
Code::Blocks上でofxプロジェクトを作成できるようにする
ここが厄介です.注意深くついてきてください.
- scripts/linux/codeblocks_wizardに行く
- そこにあるopenframeworksディレクトリ自体をまるごと/usr/share/codeblocks/templates/wizard/にcp -r
- /usr/share/codeblocks/templates/wizard/config.scriptを開いて次の文を適切に追記する.
RegisterWizard(wizCustom, _T("openframeworks"), _T("OpenFrameworks"), _T("2D/3D Graphics"));
まずreadmeに「自前ビルドしたんじゃなければ$HOME/.codeblocks/…をいじってね^^」とありますがそれしちゃいかんです.
次に,プロジェクト作成スクリプト(createProject.py)の実行設定.
ofxではCode::Blocksプロジェクトを作るためにcreateProject.pyを手動またはIDE内部で実行しますが,この内部からの呼び出し設定が実にまずい.
ということで,
/usr/share/codeblocks/templates/wizard/openframeworks/wizards.script
を書き換えます(さっきコピーしてきたファイルですね.コピーする前に編集してもよかったお).
diffをとると次の感じになります.
% diff wizard.script.bak wizard.script 68c68,69 < local commands_string = g_of_project_dir + _T("/../../scripts/linux/createProjects.py ") + g_full_proj_path; --- > local commands_string = _T("$OF_ROOT/scripts/linux/createProjects.py ") + g_full_proj_path;
※この$OF_ROOTは落として展開したof_preRelease_v007_linuxの絶対パスに置換してください.
これでCode::Blocksを起動してみましょう.
File→New→Projectで出た画面に
やったね∩(・ω・)∩
プロジェクト作るときの注意
これでプロジェクトが作れるようになりました.
プロジェクト作成ウィザードの中で,配置ディレクトリを指定するところがありますが,その時は最後にスラッシュを書かないようにしてください.
これもwizards.scriptがまずいからですけども….
うーん,patchかなんか投げようかしらん.
ぺろぺろしてみましょう
さて,やっとopenFrameworksをぺろぺろできます.
ぺろぺろしましょう.
まずはプロジェクト作成
とりあえず追加ライブラリ無しでプロジェクトを作ってください.
ここではプロジェクト名はデフォルトまんまです.
こんなかんじでソースが生成されますね.
で,基本的にはtestApp.cppにごにょごにょ付け加えていくかんじになります.
その前に,ビルド設定をちょっと修正する必要があります.
- Code::Blocksからプロジェクト内のconfig.makeファイルを開き,そのOF_ROOTの値を,適切に設定してください.
ついでに僕はC++0xを使いたい人なので,USER_CFLAGSに”-std=c++0x”を追加します.
(以下のサンプルはふつーにC++0x使ってます><;;)
何もなしで実行してみましょう
これでビルドすると普通に実行できて,何もない画面が出力されます.
やったね∩(・ω・)∩
ちょっとだけ書いてみましょう
すごいですね.イベントハンドラがぜんぶ最初から書いてあるので超ラクです.
dragもあるので,フラグでクリック状態を管理する必要すら無い.
素晴らしいのは,STLだろうがboostだろうが使い放題.
てことで,わりとよくある,超簡単ペイント.ドラッグで線が描けます.
Ctrl+zで無限undo機能とか,cで全消しする機能とかあります.その気になればredoだってプラス3行くらいで書けます.
- ウィンドウサイズとかの初期設定(2行)
- 線の一覧を保存するstd::vectorオブジェクトの用意
- キーイベントの実装(6行くらい)
- 描画イベントの実装(4行くらい)
これだけです.ソース全部載せる方が長いくらい.追記した部分をハイライトしています.
クリックで展開されます.
#pragma once #include "ofMain.h" #include <vector> class testApp : public ofBaseApp{ std::vector<std::vector<ofPoint> > lines; public: void setup(); void update(); void draw(); void keyPressed (int key); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); };
#include "testApp.h" //-------------------------------------------------------------- void testApp::setup(){ ofSetWindowTitle("fish"); ofSetWindowShape(640, 480); } //-------------------------------------------------------------- void testApp::update(){ } //-------------------------------------------------------------- void testApp::draw(){ ofSetColor(0, 0, 0); for(const std::vector<ofPoint>& line : lines) for(unsigned int i = 1; i < line.size(); i++) ofLine(line[i-1].x, line[i-1].y, line[i].x, line[i].y); } //-------------------------------------------------------------- void testApp::keyPressed(int key){ if(key == ('z' - 'a' + 1)) { if(lines.size()) lines.pop_back(); } else if(key == 'c') lines.clear(); } //-------------------------------------------------------------- void testApp::keyReleased(int key){ } //-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ){ } //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button){ (lines.end()-1)->push_back(ofPoint(x, y)); } //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ lines.push_back(std::vector<ofPoint>()); } //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){ } //-------------------------------------------------------------- void testApp::windowResized(int w, int h){ } //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo){ }
ofxに関する知識ゼロの状態からここまで正味十数分といったところか.
で,実際に走らせてみて確認してほしいのですが,むっちゃ軽いです.
もうちょっと「メディアアート」なサンプルを作ってよ!
やりましょう
ちょっと待ってね
ついでに
Code::Blocksの補完なかなか賢いですね.
僕はvimでぜんぶ整えてるのでそれほど困んないですが,初心者にすすめるときはEclipseにCDT入れるよりは,ていう選択肢もありかも.
ただエディタとしてはけっこううんkなかんじ,僕はやっぱり外部エディタでgvimでやってます.
中段の
/usr/share/codeblocks/templates/wizard/openframeworks/wizards.script
は
/usr/share/codeblocks/templates/wizard/openframeworks/wizard.script
のことでしょうか?
ofプロジェクトの作成まではいくのですが、まったくの空っぽのままでテンプレートがロードされません。難しい…
createProject.py “プロジェクトのdirパス”
で直接作成しようとすると
/linux/createProjects.py”, line 3, in
from lxml import etree
ImportError: No module named lxml
lxmlモジュールがないといわれているみたいなので
sudo apt-get install python-lxml
これでテンプレートがロードできるようになりました。