《Cinder》是一套協助開發者寫出高品質多媒體互動作品的 C++ 函式庫,類似知名的《Processing》、《PureData》,這類工具庫嘗試彙整散落世界各地的程式資源,並降低開發者實作互動程式的難度。
多數互動媒體工具為了降低學習門檻與操作便利性,往往選擇 Script 語言或拖拉工具當載體,Cinder 反其道而行,採用困難的純 C++ 實作,這給開發者帶來相當的技術門檻。確實,Cinder 是個向程序員微笑的工具,平常有寫編譯式 OOP 程式的人們若閱讀 Cinder 程式碼,第一感受往往是:「這程式挺好看的」。
Cinder 開發者們很彈性地使用廣為人知的 C++ 技巧來設計函式庫,使得用戶在編寫應用程式時,能享受不錯的呼叫介面,撰寫所需行數亦不多。前去翻閱 Cinder 原始碼則會發現它的內部也很簡潔,看了舒爽。舒爽感的來源可以例子說明。
普通 Script 工具為了簡化難度,往往把好幾步複雜動作包成一行搞定:
tex = myImageLoader("url");
代價是執行若出問題,有各種可能的原因,我們無從理解起。
Cinder 做相同任務得多寫一些
gl::Texture tex( loadImage( loadUrl( "url" ) ) );
這行要求程式員必須知道 Texture、Image、Url 三種概念,分別代表抓網路資料、主記憶體圖片、GL 顯示材質,但幸運的是我們不必介意圖片格式種類、網址正確性、或著材質做內插的參數。
Cinder 傾向把整個工程行為內含的工程概念都保留在程式碼,但去掉全部細節。用個人的話來講,就是讓程式員在精神層面掌控全局,但不必把手弄髒。所以說它給入門者帶來少許技術門檻,但對程式員來說卻很友善。
空的 Cinder 主程式架構如下:
class BasicApp : public AppBasic { public: void mouseDrag( MouseEvent event ); void draw(); listmPoints; };
只需照框架填入事件處理與成像代碼,helloworld 就現身了。
void BasicApp::mouseDrag( MouseEvent event ) { // 拖拉時記錄滑鼠座標 mPoints.push_back( event.getPos() ); } void BasicApp::draw() { gl::setMatricesWindow( getWindowSize() ); gl::clear( Color( 0.1f, 0.1f, 0.1f ) ); // 用直線把記錄的座標點全都連起來 glColor3f( 1.0f, 0.5f, 0.25f ); glBegin( GL_LINE_STRIP ); for( list::iterator pointIter = mPoints.begin(); pointIter != mPoints.end(); ++pointIter ) glVertex2f( *pointIter ); glEnd(); } // Cinder 將程式進入點與主迴圈包裝起來 CINDER_APP_BASIC( BasicApp, RendererGl )
執行程式,我們能用滑鼠在視窗上畫線啦,很簡單吧!此例來自 Cinder 官方範例包。
再以一個 QuickTime 讀取和播放的關鍵代碼,展示 Cinder 的清晰程度。
介面
class QTimeIterApp : public AppBasic { public: void setup(); void update(); void draw(); void loadMovieFile( const fs::path &path ); qtime::MovieSurface mMovie; Surface mSurface; };
實作
void QTimeIterApp::setup() { // 取得影片檔路徑,載入之 fs::path p = getOpenFilePath(); if( ! p.empty() ) loadMovieFile( p ); } void QTimeIterApp::loadMovieFile( const fs::path &moviePath ) { // 載入 QT 影片檔 try { mMovie = qtime::MovieSurface( moviePath ); mMovie.setLoop( true, true ); mMovie.seekToStart(); mMovie.play(); } catch( ... ) { console() << "Unable to load the movie." << std::endl; } } void QTimeIterApp::update() { // 定期將影片 Frame 資料轉為成像用的 Surface if( mMovie ) mSurface = mMovie.getSurface(); } void QTimeIterApp::draw() { // 用 GL 畫出 Surface gl::clear( Color( 0, 0, 0 ) ); gl::enableAlphaBlending( true ); if( ( ! mMovie ) || ( ! mSurface ) ) return; gl::draw( gl::Texture( mSurface ) ); }
代碼規劃相當直白,對於只想借一下程式框架來做 prototyping、測試概念的人來說,也很適合。
帥氣的字型+動畫+輸入範例
Cinder 提供了內容相當豐富的範例程式,內容遍及向量繪圖工具、點陣繪圖工具、動畫管理、3D Shader、粒子系統、音效處理、字型工具、QuickTime 處理、Webcam 捕捉... 等等,此外還支援 iPhone iPad,能處理多點觸碰事件。
光看範例就能想到很多應用題目囉。
除了範例包,官方網站收集了不錯的教學指引供大家參考,這些資料都能很實在地幫助入門者深入特定主題,很有心阿。
也許挑個沒事的下午玩玩看 Cinder,說不定有意外收穫喔 :)