yoppa.org


無事帰国

台湾より無事帰国しましたー。いろいろあった4日間でした…

  • 出発の際、成田空港のチェックインカウンターで同行者のパスポートの期限が足りないとの指摘を受け、出国できず。
  • 急遽、一人旅に。
  • 到着後、大学のドミトリーでMacBookを起動したところ、画面がブラックアウト、目の前もブラックアウト。
  • 夜中スカイプをしながら、ライブについていろいろ思案を巡らせる。
  • 堀尾さんにすばらしいコーディネイトをしていただき、ネットワーク経由で東京と結んでライブをすることを急遽決定。
  • お陰様で、現地では大好評。終った瞬間「イェー」って感じで拍手と歓声が。良かった…
  • 無事帰国。

というかんじでした。さらに色々なことのあった4日間だったので、時間のあるときにじっくりと詳細を書いてみたい。


明日から台湾に行ってきます!

Apple Storeでのイベント、なんとか無事に終了。

お越しいただいた方、ありがとうございました。たどたどしいプレゼンだったものの、無事、大盛況のうちに終了することができました。人によっては、既に知っている内容ばかりだったかもしれませんが、openFrameworksの最初のイベントということで、どうかご容赦を。

ひとつイベント終り、一段落できると思いきや、実は明日から台湾へ、openFramworksのワークショップをやりに行くことに。

  • 27日:台湾入り
  • 28日:レクチャー1日目 (2.5時間 x 2) + コンサート
  • 29日:レクチャー2日目 (2.5時間 x 1)
  • 30日:帰国

というかなりの突貫スケジュール。ほとんど観光する暇はなさそう。

ワークショップの内容としては、

  • レクチャー1:openFramworksの基本、アニメーション
  • レクチャー2:OOPの基本、クラスの作成
  • レクチャー3:アドオンを使用する、ofxOpenCVとofxBox2D

というような予定。ただどこまでできるかは全くの未知数なので、現場で臨機応変にやっていく必要はありそう。

とはいえ、とても良い機会なので、目一杯、楽しんできます!


openFrameworks + iPhoneで、オリジナルのカメラアプリを作る

今日の目標 – オリジナルのカメラアプリを作成する

  • iPhoneのカメラを使用して、オリジナルのカメラアプリを作成してみる
  • openFramworks for iPhoneを使用すると、簡単に内蔵カメラの画像を使用できる
  • 内蔵カメラから画像イメージを取得するには、ofxiPhoneImagePicker アドオンを使用する

カメラアプリ1:写真を撮影する

  • 内蔵カメラで写真を撮影し、撮影した写真を画像(ofImage)にコピーして表示する
  • 以降のカメラアプリの基本となる機能

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

//シミュレータを使用する際には、コメントアウトを外す
//#define _USE_SIMULATOR

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
	
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
	
    
  //カメラの画像を一時的に格納する領域
  unsigned char * cameraPixels;
  //カメラを使用するためのアドオン
  ofxiPhoneImagePicker * camera;
  //撮影した画像データ
  ofImage	photo;
  //現在の状態を格納
  //0:撮影待ち, 1:画像処理, 2:処理終了(待機)
  int status; 
	
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // iPhone用初期設定
  ofRegisterTouchEvents(this);
  ofxAccelerometer.setup();
  ofxiPhoneAlerts.addListener(this);
  ofEnableSmoothing();
  ofSetCircleResolution(64);
  ofEnableAlphaBlending();
    
  //カメラ初期設定
  cameraPixels = NULL; 
  camera = new ofxiPhoneImagePicker();
  camera->setMaxDimension(480);
    
  status = 0;
}


//--------------------------------------------------------------
void testApp::update()
{
#ifndef _USE_SIMULATOR
  //実機使用の場合
  if(camera->imageUpdated){
    //カメラのメモリ領域を確保
    if (cameraPixels == NULL){
      cameraPixels = new unsigned char [camera->width * camera->height*4];
    }
		
    //カメラの画像のままだと上下反転してるので、イメージの上下を反転
    for (int i = 0; i < camera->height; i++){
      memcpy(cameraPixels+(camera->height-i-1)*camera->width*4, camera->pixels+i*camera->width*4, camera->width*4);
    }
		
    //カメラから取得したイメージを、処理用のofImage(photo)にコピーする
    photo.setFromPixels(cameraPixels, camera->width, camera->height, OF_IMAGE_COLOR_ALPHA);  
    camera->imageUpdated = false;
    status = 1;
  }
#endif
}

//--------------------------------------------------------------
void testApp::draw()
{
  if (status == 0) {
    //撮影を促す画面を表示
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("Double tap on the screen!!", 40, ofGetHeight()/2-5);
  }
    
  if(status == 1){
    //撮影した画像を表示
    photo.draw(0, 0);
  }
}

//--------------------------------------------------------------
void testApp::exit() {
}


//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){	
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
#ifdef _USE_SIMULATOR
  //シミュレータ使用の場合:画像をロード
  photo.loadImage("images/photo.png");
  photo.setImageType(OF_IMAGE_COLOR_ALPHA);
  status = 1;
#else
  //実機使用の場合:写真を新規に撮影
  camera->openCamera();
#endif
}

//--------------------------------------------------------------
void testApp::lostFocus() {
}

//--------------------------------------------------------------
void testApp::gotFocus() {
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}


写真撮影を促す画面


カメラから取得された画像

カメラアプリ2:モザイクカメラ

  • 撮影した写真をモザイク状に加工する
  • 撮影した写真のピクセル情報を一定間隔でとりだして、取得したRGB情報をもとに四角形を描いている
  • 写真画像ののピクセル情報は、getPixel() 関数を用いて取り出している
  • 写真のイメージは、1ピクセルごとにRGBA(Red, Green, Blue, Alpha)の4つの情報が含まれている
  • ピクセルをスキャンしていく際には、4ピクセルを1単位として扱うように留意する

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

//シミュレータを使用する際には、コメントアウトを外す
//#define _USE_SIMULATOR

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
	
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
	
    
  //カメラの画像を一時的に格納する領域
  unsigned char * cameraPixels;
  //カメラを使用するためのアドオン
  ofxiPhoneImagePicker * camera;
  //撮影した画像データ
  ofImage	photo;
  //現在の状態を格納、0:撮影待ち, 1:画像処理, 2:処理終了(待機)
  int status; 
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // iPhone用初期設定
  ofRegisterTouchEvents(this);
  ofxAccelerometer.setup();
  ofxiPhoneAlerts.addListener(this);
  ofEnableSmoothing();
  ofSetCircleResolution(64);
  ofEnableAlphaBlending();
    
  //カメラ初期設定
  cameraPixels = NULL; 
  camera = new ofxiPhoneImagePicker();
  camera->setMaxDimension(480);
    
  status = 0;
}


//--------------------------------------------------------------
void testApp::update()
{
#ifndef _USE_SIMULATOR
  //実機使用の場合
  if(camera->imageUpdated){
    //カメラのメモリ領域を確保
    if (cameraPixels == NULL){
      cameraPixels = new unsigned char [camera->width * camera->height*4];
    }
		
    //カメラの画像のままだと上下反転してるので、イメージの上下を反転
    for (int i = 0; i < camera->height; i++){
      memcpy(cameraPixels+(camera->height-i-1)*camera->width*4, camera->pixels+i*camera->width*4, camera->width*4);
    }
		
    //カメラから取得したイメージを、処理用のofImage(photo)にコピーする
    photo.setFromPixels(cameraPixels, camera->width, camera->height, OF_IMAGE_COLOR_ALPHA);  
    camera->imageUpdated = false;
    status = 1;
  }
#endif
}

//--------------------------------------------------------------
void testApp::draw()
{
  if (status == 0) {
    //撮影を促す画面を表示
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("Double tap on the screen!!", 40, ofGetHeight()/2-5);
  }
    
  if(status == 1){
    //撮影した画像を表示
    photo.draw(0, 0);
        
    //画像データのビットマップ情報を配列に格納
    unsigned char * pixels = photo.getPixels();
        
    //画像の幅と高さを所得
    int w = photo.width;
    int h = photo.height;
        
    //スキャンする間隔
    int skip = 20;
        
    //モザイク化:等間隔にピクセルの色を検知し、四角形を描く
    for (int j = 0; j < h; j+=skip){
      for (int i = 0; i < w; i+=skip){
        int valueR = pixels[j*4*w + i*4];
        int valueG = pixels[j*4*w + i*4+1];
        int valueB = pixels[j*4*w + i*4+2];
        ofSetColor(valueR,valueG,valueB);
        ofRect(i, j, skip, skip);
      }
    }
  }
}

//--------------------------------------------------------------
void testApp::exit() {
}


//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){	
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
#ifdef _USE_SIMULATOR
  //シミュレータ使用の場合:画像をロード
  photo.loadImage("images/photo.png");
  photo.setImageType(OF_IMAGE_COLOR_ALPHA);
  status = 1;
#else
  //実機使用の場合:写真を新規に撮影
  camera->openCamera();
#endif
}

//--------------------------------------------------------------
void testApp::lostFocus() {
}

//--------------------------------------------------------------
void testApp::gotFocus() {
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}


モザイク化されたイメージ

カメラアプリ3:スキャンカメラ

  • モザイクの応用
  • ある高さ(Y座標)のピクセル情報のみとりだす
  • 全てのX座標のRGBAの値を取得して、縦に拡げてバーコード状に表示する
  • 取得する高さは、画面をタッチして変更できるようにする
  • 写真を指定したラインでスキャンするような効果を得ることができる

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

//シミュレータを使用する際には、コメントアウトを外す
//#define _USE_SIMULATOR

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
	
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
	
  //カメラの画像を一時的に格納する領域
  unsigned char * cameraPixels;
  //カメラを使用するためのアドオン
  ofxiPhoneImagePicker * camera;
  //撮影した画像データ
  ofImage	photo;
  //現在の状態を格納、0:撮影待ち, 1:画像処理, 2:処理終了(待機)
  int status;
  //イメージをスキャンするY座標
  int scanHeight; 
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // iPhone用初期設定
  ofRegisterTouchEvents(this);
  ofxAccelerometer.setup();
  ofxiPhoneAlerts.addListener(this);
  ofEnableSmoothing();
  ofSetCircleResolution(64);
  ofEnableAlphaBlending();
    
  //カメラ初期設定
  cameraPixels = NULL; 
  camera = new ofxiPhoneImagePicker();
  camera->setMaxDimension(480);
    
  status = 0;
  scanHeight = 0;
}


//--------------------------------------------------------------
void testApp::update()
{
#ifndef _USE_SIMULATOR
  //実機使用の場合
  if(camera->imageUpdated){
    //カメラのメモリ領域を確保
    if (cameraPixels == NULL){
      cameraPixels = new unsigned char [camera->width * camera->height*4];
    }
		
    //カメラの画像のままだと上下反転してるので、イメージの上下を反転
    for (int i = 0; i < camera->height; i++){
      memcpy(cameraPixels+(camera->height-i-1)*camera->width*4, camera->pixels+i*camera->width*4, camera->width*4);
    }
		
    //カメラから取得したイメージを、処理用のofImage(photo)にコピーする
    photo.setFromPixels(cameraPixels, camera->width, camera->height, OF_IMAGE_COLOR_ALPHA);  
    camera->imageUpdated = false;
    status = 1;
  }
#endif
}

//--------------------------------------------------------------
void testApp::draw()
{
  if (status == 0) {
    //撮影を促す画面を表示
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("Double tap on the screen!!", 40, ofGetHeight()/2-5);
  }
    
  if(status == 1){
    //撮影した画像を表示
    photo.draw(0, 0);
        
    //画像データのビットマップ情報を配列に格納
    unsigned char * pixels = photo.getPixels();
        
    //画像の幅と高さを所得
    int w = photo.width;
    int h = photo.height;
        
        
    //モザイク化:等間隔にピクセルの色を検知し、四角形を描く
    for (int i = 0; i < w; i++){
      int valueR = pixels[scanHeight*4*w + i*4];
      int valueG = pixels[scanHeight*4*w + i*4+1];
      int valueB = pixels[scanHeight*4*w + i*4+2];
      ofSetColor(valueR,valueG,valueB);
      ofRect(i, 0, 1, h);
    }
        
    //今スキャンしている場所を表示
    ofSetColor(255, 255, 255);
    ofLine(0, scanHeight, ofGetWidth(), scanHeight);
  }
}

//--------------------------------------------------------------
void testApp::exit() {
}


//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
  //画面をドラッグした場所で、スキャンする高さを決定
  scanHeight = touch.y;
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){	
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
#ifdef _USE_SIMULATOR
  //シミュレータ使用の場合:画像をロード
  photo.loadImage("images/photo.png");
  photo.setImageType(OF_IMAGE_COLOR_ALPHA);
  status = 1;
#else
  //実機使用の場合:写真を新規に撮影
  camera->openCamera();
#endif
}

//--------------------------------------------------------------
void testApp::lostFocus() {
}

//--------------------------------------------------------------
void testApp::gotFocus() {
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}


写真をスキャン

カメラアプリ4:ピクセレイトカメラ(グレイスケール版)

  • 写真イメージのピクセル情報を解析
  • 一定間隔ごとに写真のRGB別のレベル(明るさ)を取得して、その平均値をとる
  • その値で半径を変化させながら円を描いていく
  • モノクロで写真を印刷したようなドットによる濃淡の表現になる

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

//シミュレータを使用する際には、コメントアウトを外す
//#define _USE_SIMULATOR

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
	
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
	
  //カメラの画像を一時的に格納する領域
  unsigned char * cameraPixels;
  //カメラを使用するためのアドオン
  ofxiPhoneImagePicker * camera;
  //撮影した画像データ
  ofImage	photo;
  //現在の状態を格納、0:撮影待ち, 1:画像処理, 2:処理終了(待機)
  int status; 	
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // iPhone用初期設定
  ofRegisterTouchEvents(this);
  ofxAccelerometer.setup();
  ofxiPhoneAlerts.addListener(this);
  ofEnableSmoothing();
  ofSetCircleResolution(64);
  ofEnableAlphaBlending();
    
  //カメラ初期設定
  cameraPixels = NULL; 
  camera = new ofxiPhoneImagePicker();
  camera->setMaxDimension(480);
    
  status = 0;
}


//--------------------------------------------------------------
void testApp::update()
{
#ifndef _USE_SIMULATOR
  //実機使用の場合
  if(camera->imageUpdated){
    //カメラのメモリ領域を確保
    if (cameraPixels == NULL){
      cameraPixels = new unsigned char [camera->width * camera->height*4];
    }
		
    //イメージの上下を反転
    for (int i = 0; i < camera->height; i++){
      memcpy(cameraPixels+(camera->height-i-1)*camera->width*4, camera->pixels+i*camera->width*4, camera->width*4);
    }
		
    //カメラから取得したイメージを、処理用のofImage(photo)にコピーする
    photo.setFromPixels(cameraPixels, camera->width, camera->height, OF_IMAGE_COLOR_ALPHA);  
    camera->imageUpdated = false;
    status = 1;
  }
#endif
}

//--------------------------------------------------------------
void testApp::draw()
{
  if (status == 0) {
    //撮影を促す画面を表示
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("Double tap on the screen!!", 40, ofGetHeight()/2-5);
  }
    
  if(status == 1){
    //画像データのビットマップ情報を配列に格納
    unsigned char * pixels = photo.getPixels();
                
    //画像の幅と高さを所得
    int w = photo.width;
    int h = photo.height;

    //ピクセレイトの半径を設定
    int r = 12;

    //画像を等間隔にスキャン
    for (int j = 0; j < h; j+=r){
      for (int i = 0; i < w; i+=r){
	//ピクセルのRGBの値を取得
	//RGBAの順番で並んでいるので、4ピクセルずつ
	int valueR = pixels[j*4*w + i*4];
	int valueG = pixels[j*4*w + i*4+1];
	int valueB = pixels[j*4*w + i*4+2];
                
	//RGBの値の平均値を算出
	float value = r*(valueR+valueG+valueB)/2.0/255.0;

	//取得したRGB値をもとに、円を描画
	//取得したピクセルの明るさを、円の半径に対応させている
	ofSetColor(255,255,255,100);
	ofCircle(i, j, value);
      }
    }
  }
}

//--------------------------------------------------------------
void testApp::exit() {
}


//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){	
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
#ifdef _USE_SIMULATOR
  //シミュレータ使用の場合:画像をロード
  photo.loadImage("images/photo.png");
  photo.setImageType(OF_IMAGE_COLOR_ALPHA);
  status = 1;
#else
  //実機使用の場合:写真を新規に撮影
  camera->openCamera();
#endif
}

//--------------------------------------------------------------
void testApp::lostFocus() {
}

//--------------------------------------------------------------
void testApp::gotFocus() {
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}


グレースケールでのピクセレイト

カメラアプリ5:ピクセレイトカメラ(カラー版)

  • ピクセレイトのカラー版
  • RGB別々に円を描いて、重ねていく
  • 描画する際の色の合成を、加算合成に変更するところがポイント
  • OpenGLの命令を直接使用する – glEnable(GL_BLEND); と glBlendFunc(GL_SRC_ALPHA, GL_ONE); で実現可能
  • カラー写真を印刷したようなドットによる濃淡の表現になる

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

//シミュレータを使用する際には、コメントアウトを外す
//#define _USE_SIMULATOR

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
	
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
	
  //カメラの画像を一時的に格納する領域
  unsigned char * cameraPixels;
  //カメラを使用するためのアドオン
  ofxiPhoneImagePicker * camera;
  //撮影した画像データ
  ofImage	photo;
  //現在の状態を格納、0:撮影待ち, 1:画像処理, 2:処理終了(待機)
  int status; 	
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // iPhone用初期設定
  ofRegisterTouchEvents(this);
  ofxAccelerometer.setup();
  ofxiPhoneAlerts.addListener(this);
  ofEnableSmoothing();
  ofSetCircleResolution(64);
    
  //カメラ初期設定
  cameraPixels = NULL; 
  camera = new ofxiPhoneImagePicker();
  camera->setMaxDimension(480);
    
  status = 0;
}


//--------------------------------------------------------------
void testApp::update()
{
#ifndef _USE_SIMULATOR
  if(camera->imageUpdated){
    //カメラのメモリ領域を確保
    if (cameraPixels == NULL){
      cameraPixels = new unsigned char [camera->width * camera->height*4];
    }
		
    //イメージの上下を反転
    for (int i = 0; i < camera->height; i++){
      memcpy(cameraPixels+(camera->height-i-1)*camera->width*4, camera->pixels+i*camera->width*4, camera->width*4);
    }
		
    //カメラから取得したイメージを、処理用のofImage(photo)にコピーする
    photo.setFromPixels(cameraPixels, camera->width, camera->height, OF_IMAGE_COLOR_ALPHA);  
    camera->imageUpdated = false;
    status = 1;
  }
#endif
}

//--------------------------------------------------------------
void testApp::draw()
{
  if (status == 0) {
    //撮影を促す画面を表示
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("Double tap on the screen!!", 40, ofGetHeight()/2-5);
  }
    
  if(status == 1){
    //背景の更新を終了
    ofSetBackgroundAuto(false);
    //画面の描画を加算合成に
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        
    //画像データのビットマップ情報を配列に格納
    unsigned char * pixels = photo.getPixels();
                
    //画像の幅と高さを所得
    int w = photo.width;
    int h = photo.height;
        
    //ピクセレイトの半径を設定
    int r = 12;
        
    //画像を8ピクセル間隔でスキャン
    for (int j = 0; j < h; j+=r){
      for (int i = 0; i < w; i+=r){
                
	//ピクセルのRGBの値を取得
	int valueR = pixels[j*4*w + i*4];
	int valueG = pixels[j*4*w + i*4+1];
	int valueB = pixels[j*4*w + i*4+2];

	//取得したRGB値をもとに、円を描画
	//取得したピクセルの明るさを、円の半径に対応させている
	ofSetColor(255, 0, 0, 63);
	ofCircle(i, j, r*valueR/255.0*2.0);
	ofSetColor(0, 255, 0, 63);
	ofCircle(i, j, r*valueG/255.0*2.0);
	ofSetColor(0, 0, 255, 63);
	ofCircle(i, j, r*valueB/255.0*2.0);
      }
    }
        
    //ステイタスを変更し、描画は1度だけに
    status = 2;
  }
}

//--------------------------------------------------------------
void testApp::exit() {
}


//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){	

}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
#ifdef _USE_SIMULATOR
  //シミュレータ使用の場合:画像をロード
  photo.loadImage("images/photo.png");
  photo.setImageType(OF_IMAGE_COLOR_ALPHA);
  status = 1;
#else
  //実機使用の場合:写真を新規に撮影
  camera->openCamera();
#endif
}

//--------------------------------------------------------------
void testApp::lostFocus() {
}

//--------------------------------------------------------------
void testApp::gotFocus() {
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}


カラーでのピクセレイト

サンプルファイルのダウンロード

今回の授業でとりあげた全てのサンプルは下記よりダウンロードすることが可能です。


しつこく告知

何度もしつこくてすみませんが、Apple Store銀座でのopenFrameworksのイベントは、明日23日の19:00から開催されます。お時間があればぜひ!! そしてできれば、下記のサイトから参加表明していただけると助かります。

http://atnd.org/events/4627

というわけで、今日はいろいろプレゼンのための仕込みをする一日。

最近どうも家のフレッツ光の調子が悪く、かなりの頻度でネットが落ちる。ストレスが溜まる。そういうわけで、たまには気分を変えて、近所の無線LANがつかえるカフェ的な場所で作業でもしてみるかということで調べてみたところ、近所のオオゼキの近くに無線LANがつかえるカフェがあった。早速作業してみようということでいってみたら、生憎貸切のイベントが入っているということで、あえなく玉砕。

そのままだとせっかくMacBook Proを持ってきた勢いが納まらず、駅前のマクドナルドに移動。ここなら問題なくネットに繋がるかと思ったら、マクドナルドはBBモバイルのサービスに加入していないと使えなかった。残念。

仕方ないのでネット無しでプレゼン資料を作ってたら、なんだか普段よりも格段に捗る。TwitterもWebも一切使えない状況に自分を追い込むと、普段いかにどうでも良いことに仕事をインタラプトされているかを思いしった。今度から、集中しなければいけないときには、敢えてネットの入らない場所で仕事するというのもアリなのかもしれない。調べ物には向いていないけど。


近況と告知

openFrameworksの本を出して以降、いろいろな方との繋りが生まれて、執筆の苦労が報われたとしみじみ感じる今日この頃。昨日は、openFrameworksの主要開発者の一人、Theo Watsonさんともお会いすることができて、とても嬉しい体験だった。学生の冷たい視線にもめげず、本にサインしてもらった。おみやげにoFステッカーを大量にもらった。嬉しい。

Theo Watsonさんのレクチャーは本当にすばらしく、優秀なプログラマーは、本当に自分のような凡人の何十倍もの生産性があるのだと痛感した。本を無事出版できていい気になってたけど、Theoさんのプレゼンを見て、自分はまだまだ修行が足りないと浮かれた気分を戒める。たぶん一生かかっても追いつけないけど、さらに地道にがんばらないと、と思った。

幸い、TheoさんにもoF本は気に入っていただけたようで(日本語は読めないので本文は読んでないけど…)、とりあえず安心。

で、今月の後半から、Beyond Interaction出版をきっかけに、いろいろなワークショップが目白押し。興味のある方はぜひ参加してください!

Beyond Interaction:メディアアートのためのopenFrameworksプログラミング入門

  • 日時:2010年5月23日(日) 7:00 pm – 8:00 pm
  • 場所:AppleStore 銀座
  • openFrameworksの簡単な紹介とデモを行います。入場は無料!!
  • 詳細情報はこちら
openFrameworksワークショップ in 台湾 !!
  • 2010年5月28日・29日
  • Taipei National University of Arts, Center for Art and Technology
  • 現在、詳細について絶賛調整中!
東京藝術大学公開講座「openFramewroks プログラミングワークショップ」
  • 日時:2010年8月7日~8月8日 ( 2日間) 両日とも10:00~19:00 計16時間
  • 場所:東京藝術大学上野キャンパス
  • 参加費:15,000円
  • 総合工房棟A棟2F 芸術情報センター内演習室1
  • 定員18名 市民一般(学生以上) 最少開講人数12名
  • 詳細情報はこちら

というわけで、諸々忙しくなってきて、ちょっと焦ってます… でも苦労した分、いろいろな人と知りあえそうなので、頑張ります!!


openFrameworks + iPhone マルチタッチイベントの取得、音アプリを作る

サンプルファイルのダウンロード

サンプルファイルは以下のリンクよりダウンロードしてください。

マルチタッチイベントの取得

マルチタッチの情報が取得できるイベント

定義 機能
touchDown 画面をタッチした瞬間に実行される
touchMoved 画面をタッチして移動した際に実行される
touchUp タッチしていた画面から離れた瞬間実行される
touchDoubleTap ダブルタップ(素早く2回画面をタップ)した瞬間に実行される

タッチされた情報は、以下のように格納される

  • touch.id – 現在タッチされたポイントのID (0〜4)
  • touch.x – 現在タッチされたポイントのx座標
  • touch.y- 現在タッチされたポイントのy座標
  • とりだしたタッチの座標情報は、配列に格納すると便利
  • 配列 – 簡単な配列の説明「情報のロッカーみたいなもの」

マルチタッチイベントの取得1

  • タッチした全ての場所に円を描く
  • ofPointクラスを利用して、タッチした座標を1つのインスタンス(変数)で管理している
  • [ofPointのインスタンス].x – X座標
  • [ofPointのインスタンス].y – Y座標
  • さらにそのofPointのクラスを配列にして、5つのポイントをtouchLocという配列で一括して管理している
  • touchDownした際に配列toucLocに座標を記録して、drawで記録された座標を中心に円を描いている

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

class testApp : public ofxiPhoneApp {

public:
  void setup();
  void update();
  void draw();
  void exit();

  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);

  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);

  //タッチした座標の配列(5コ)
  ofPoint touchLoc[5];
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
  // タッチイベントの登録
  ofRegisterTouchEvents(this);
  // 加速度センサの初期化
  ofxAccelerometer.setup();
  // iPhone警告メッセージの取得
  ofxiPhoneAlerts.addListener(this);

  //背景色を黒に
  ofBackground(0,0,0);
  //アルファ値を使用する
  ofEnableAlphaBlending();
  //円の解像度の設定を32に
  ofSetCircleResolution(32);

  //タッチポイントを初期化、画面の外に
  for (int i=0; i<5; i++) {
    touchLoc[i].set(-100, -100);
  }
}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){
  //タッチした位置を取得して、円を描く
  for (int i=0; i<5; i++) {
    ofSetColor(31, 127, 255,127);
    ofCircle(touchLoc[i].x, touchLoc[i].y, 60);
    ofSetColor(255, 255, 255);
    ofDrawBitmapString("touch:"
		       + ofToString(i,0)
		       + " = ("
		       + ofToString(touchLoc[i].x,0)
		       + ", "
		       + ofToString(touchLoc[i].y,0)
		       + ")",
		       2, 12*i+12);
  }
}

//--------------------------------------------------------------
void testApp::exit(){

}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
  //タッチした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
  //タッチしながら動かした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){
  //画面から指が離れたら、位置を画面外に
  touchLoc[touch.id].set(-100, -100);
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::lostFocus(){

}

//--------------------------------------------------------------
void testApp::gotFocus(){

}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){

}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){

}

マルチタッチイベントの取得2

  • タッチした場所から円が徐々に拡大していくように変更してみる

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

class testApp : public ofxiPhoneApp {

public:
  void setup();
  void update();
  void draw();
  void exit();

  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);

  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);

  //タッチした座標
  ofPoint touchLoc[5];
  //円のサイズ
  float circleSize[5];
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
  // タッチイベントの登録
  ofRegisterTouchEvents(this);
  // 加速度センサの初期化
  ofxAccelerometer.setup();
  // iPhone警告メッセージの取得
  ofxiPhoneAlerts.addListener(this);

  //背景色を黒に
  ofBackground(0,0,0);
  //アルファ値を使用する
  ofEnableAlphaBlending();
  //円の解像度の設定を32に
  ofSetCircleResolution(128);
  ofSetFrameRate(30);

  //タッチポイントを初期化、画面の外に
  for (int i=0; i<5; i++) {
    touchLoc[i].set(-100, -100);
  }
}

//--------------------------------------------------------------
void testApp::update(){
  //タッチポイントの数だけくりかえし
  for (int i=0; i<5; i++) {
    //もし円のサイズが0より大きく、画面の高さよりも小さかったら
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      //円のサイズを増加させる
      circleSize[i]+=3;
    } else {
      //それ以外だったら、円の大きさを0にリセット
      circleSize[i]=0;
    }

  }
}

//--------------------------------------------------------------
void testApp::draw(){
  //タッチした位置を取得して、円を描く
  for (int i=0; i<5; i++) {
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      ofSetColor(31,127,255,100);
      //拡大する円のサイズを指定して円を描く
      ofCircle(touchLoc[i].x, touchLoc[i].y, circleSize[i]);
      ofSetColor(255, 255,255);
    }
  }
  //ログの出力
  for (int i=0; i<5; i++) {
    ofDrawBitmapString("touch:"
		       + ofToString(i,0)
		       + " = ("
		       + ofToString(touchLoc[i].x,0)
		       + ","
		       + ofToString(touchLoc[i].y,0)
		       + "), size = "
		       + ofToString(circleSize[i], 0),
		       2, 12*i+2);
  }
}

//--------------------------------------------------------------
void testApp::exit(){

}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
  //タッチした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
  circleSize[touch.id]=1;
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
  //タッチしながら動かした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::lostFocus(){

}

//--------------------------------------------------------------
void testApp::gotFocus(){

}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){

}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){

}

音を鳴らす

  • iPhoneの音系アプリの紹介 – Bloom、SoundDrop、Rain、VectorRain ..etc
  • openFrameworksを使うと、こうした「音のおもちゃ」が簡単に作れる!!


Bloom


SounDrop


Rain

  • openFrameworks for iPhoneで音を鳴らすには – OpenALを使用する
  • OpenAL – クロスプラットフォームのオーディオAPI
  • 3次元定位オーディオを効率よく表現するように設計されている
  • OpenGLとの相性が良い
  • openFrameworksで、OpenALを利用するプロジェクトには、ofxALSoundPlayerアドオンのファイルが入っている必要がある
  • 「グループとファイル」の「addons」を右クリックして、「追加」→「既存のファイル」を選択
  • ofxALSoundPlayerのフォルダを追加する
  • [oFのフォルダ]/apps/iPhoneSpecificExamples/OpenAlExample/src/ofxALSoundPlayer


ofxALSoundPlayerの場所


アドオンの追加

caf形式のサウンドファイルの準備

  • iPhoneでサウンドファイルを扱うには、Core Audio Format(.caf)という形式に変換する必要がある
  • ターミナルから、”/usr/bin/afconvert”コマンドを使用して、AIFFファイルをCAFファイルに変換することが可能
% afconvert -f caff -d ima4 -d LEI16@22050 -c 1 -o [出力ファイル名].caf [入力ファイル名].wav

OpenALの利用1 – マルチタッチとの組み合せ

  • マルチタッチのサンプルと組み合わせてみる
  • touchDownした瞬間に、音を鳴らす
  • X座標の情報を、音の左右の定位(パン)に利用
  • Y座標の情報を、音程に利用

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"
#include "ofxALSoundPlayer.h"

class testApp : public ofxiPhoneApp {

public:
  void setup();
  void update();
  void draw();
  void exit();

  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);

  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);

  //OpenALを利用して音を再生するプレーヤー(5つ)
  ofxALSoundPlayer synth[5];
  //タッチした座標情報(5つ)
  ofPoint touchLoc[5];
  //円の大きさ情報(5つ)
  float circleSize[5];
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
  // タッチイベントの登録
  ofRegisterTouchEvents(this);
  // 加速度センサの初期化
  ofxAccelerometer.setup();
  // iPhone警告メッセージの取得
  ofxiPhoneAlerts.addListener(this);

  //背景色を黒に
  ofBackground(0,0,0);
  //アルファ値を使用する
  ofEnableAlphaBlending();
  //円の解像度の設定を32に
  ofSetCircleResolution(128);
  ofSetFrameRate(30);

  //タッチポイントを初期化、画面の外に
  for (int i=0; i<5; i++) {
    touchLoc[i].set(-100, -100);
  }

  //CAFファイルをロードして、Synthにわりあて
  for(int i=0;i<5;i++){
    synth[i].loadSound("glockenspiel.caf");
  }
}

//--------------------------------------------------------------
void testApp::update(){
  //タッチポイントの数だけくりかえし
  for (int i=0; i<5; i++) {
    //もし円のサイズが0より大きく、画面の高さよりも小さかったら
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      //円のサイズを増加させる
      circleSize[i]+=3;
    } else {
      //円の大きさを0にリセット
      circleSize[i]=0;
    }
  }
}

//--------------------------------------------------------------
void testApp::draw(){
  //タッチした位置を取得して、円を描く
  for (int i=0; i<5; i++) {
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      ofSetColor(31,127,255,100);
      //拡大する円のサイズを指定して円を描く
      ofCircle(touchLoc[i].x, touchLoc[i].y, circleSize[i]);
      ofSetColor(255, 255,255);
    }
  }
  //ログの出力
  for (int i=0; i<5; i++) {
    ofDrawBitmapString("touch:"
		       + ofToString(i,0)
		       + " = ("
		       + ofToString(touchLoc[i].x,0)
		       + ","
		       + ofToString(touchLoc[i].y,0)
		       + "), size = "
		       + ofToString(circleSize[i], 0),
		       2, 12*i+6);
  }
}

//--------------------------------------------------------------
void testApp::exit(){

}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
  //タッチした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
  circleSize[touch.id]=1;
  synth[touch.id].setPitch(0.5 + touch.y / ofGetHeight());
  synth[touch.id].setLocation(touch.x/(float)ofGetWidth()*2-1.0, 0,0);
  synth[touch.id].play();
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
  //タッチしながら動かした場所を取得
  touchLoc[touch.id].set(touch.x, touch.y);
  synth[touch.id].setPitch(0.5 + touch.y / ofGetHeight());
  synth[touch.id].setLocation(touch.x/(float)ofGetWidth()*2-1.0, 0,0);
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::lostFocus(){

}

//--------------------------------------------------------------
void testApp::gotFocus(){

}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){

}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){

}

OpenALの利用2 – Bloomっぽいアプリを作る

  • タッチした演奏情報を記録して、くりかえし演奏させてみたい (超簡易シーケンサー?)
  • 次の方法で簡単に実装可能
  • タッチした瞬間に音を鳴らす
  • タッチした座標を中心にして、円が一定速度で拡大していく
  • 円が一定の大きさより大きくなったら、最小のサイズに戻す
  • 最小のサイズに戻す際に、また音を鳴らす
  • 調整のある音階を鳴らしてみたい
  • 音階の比率をあらかじめ定義しておく
  • (純正律の)ドレミファソラシは、下記の比率になる
  • 1 : 9/8 : 5/4 : 4/3 : 3/2 : 5/3 : 15/8
  • タッチした際のY座標からピッチを決めるようにする

testApp.h

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"
#include "ofxALSoundPlayer.h"

//最大発音数を定義 (20)
#define NUM_SYNTH 20

class testApp : public ofxiPhoneApp {

public:
  void setup();
  void update();
  void draw();
  void exit();

  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);

  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);

  //サウンドプレーヤーの配列
  ofxALSoundPlayer synth[NUM_SYNTH];
  //円の大きさ情報の配列
  float circleSize[NUM_SYNTH];
  //タッチした座標情報の配列
  ofPoint touchLoc[NUM_SYNTH];
  //現在タッチした数(0〜20)
  int currentTouch;
  //音階を生成するための比率
  float pitchRatio[7];
  //演奏した音程の記録
  float noteTable[NUM_SYNTH];
};

testApp.mm

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
  // タッチイベントの登録
  ofRegisterTouchEvents(this);
  // 加速度センサの初期化
  ofxAccelerometer.setup();
  // iPhone警告メッセージの取得
  ofxiPhoneAlerts.addListener(this);

  //背景色を黒に
  ofBackground(0,0,0);
  //アルファ値を使用する
  ofEnableAlphaBlending();
  //円の解像度の設定を32に
  ofSetCircleResolution(128);
  ofSetFrameRate(30);

  //タッチポイントを初期化、画面の外に
  for (int i=0; i<NUM_SYNTH; i++) {
    touchLoc[i].set(-100, -100);
    synth[i].loadSound("glockenspiel.caf");
  }

  //現在タッチされた数
  currentTouch = 0;

  //音階を生成
  pitchRatio[0]= 1.0;
  pitchRatio[1]= 9.0/8.0;
  pitchRatio[2]= 5.0/4.0;
  pitchRatio[3]= 4.0/3.0;
  pitchRatio[4]= 3.0/2.0;
  pitchRatio[5]= 5.0/3.0;
  pitchRatio[6]= 15.0/8.0;
}

//--------------------------------------------------------------
void testApp::update(){
  //タッチポイントの数だけくりかえし
  for (int i=0; i<NUM_SYNTH; i++) {
    //もし円のサイズが0より大きく、画面の高さよりも小さかったら
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      //円のサイズを増加させる
      circleSize[i]+=3;
    } else {
      if(touchLoc[i].x > 0 && touchLoc[i].y > 0){
	//円の大きさを1にリセットして、サウンドを再度鳴らす
	//記録されている音が順番にパターンとして生成される
	circleSize[i]=1;
	synth[i].setPitch(noteTable[i]);
	synth[i].setLocation(touchLoc[i].x/(float)ofGetWidth()*2-1.0, 0,0);
	synth[currentTouch].setVolume(0.2);
	synth[i].play();
      }
    }
  }
}

//--------------------------------------------------------------
void testApp::draw(){
  //タッチした位置を取得して、円を描く
  for (int i=0; i<NUM_SYNTH; i++) {
    if(circleSize[i]>0 && circleSize[i]<ofGetHeight()){
      ofSetColor(31,127,255,200);
      ofNoFill();
      ofSetLineWidth(4);
      //拡大する円のサイズを指定して円を描く
      ofCircle(touchLoc[i].x, touchLoc[i].y, circleSize[i]);
      ofSetColor(255, 255,255);
    }
  }
}

//--------------------------------------------------------------
void testApp::exit(){

}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
  //タッチした場所を取得
  touchLoc[currentTouch].set(touch.x, touch.y);
  circleSize[currentTouch]=1;
  //タッチしたY座標から、ピッチを選択
  noteTable[currentTouch] = pitchRatio[int(7.0*touch.y/ofGetHeight())] * 0.5;
  synth[currentTouch].setPitch(noteTable[currentTouch]);
  //パンを設定
  synth[currentTouch].setLocation(touch.x/(float)ofGetWidth()*2-1.0, 0,0);
  //音量を設定
  synth[currentTouch].setVolume(0.2);
  //音を鳴らす
  synth[currentTouch].play();
  currentTouch++;
  if (currentTouch>NUM_SYNTH-1) {
    currentTouch = 0;
  }
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){

}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
  //ダブルタップでリセット
  for (int i=0; i<NUM_SYNTH; i++) {
    circleSize[i]=0;
    touchLoc[i].set(-100, -100);
  }
}

//--------------------------------------------------------------
void testApp::lostFocus(){

}

//--------------------------------------------------------------
void testApp::gotFocus(){

}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){

}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){

}


完成!!


メディアリテラシー2. インターネットの活用法

Twitter

  • Followerは増えたか?
  • Follower数選手権、クラス1位は誰か?

Googleアカウントの取得

  • 前回Gmailのアカウントを作成しなかった人 – Googleのアカウントを取得する

検索画面のカスタマイズ

  • Googleアカウントでログイン
  • iGoogleを活用
  • ガジェットを追加してみる

メール

  • Gmailの様々な使用法
  • 分類する:ラベル
  • 自動的にふりわける:フィルター
  • アカウントの追加:[アカウント名]+文字列@gmail.com

スケジュール管理、Todo

  • Google Calender – Eventを追加して、スケジュールを管理する
  • Todo – TaskによるTodoリストの作成

地図、位置情報

  • Google Mapsでマイマップを作成
  • ルート検索 – 家から大学までの経路を探索 – 歩いたら?
  • 地図を共有 – 世界遺産を探せ!

情報を収集する

  • RSSリーダ:Google Reader – 情報芸術コースのRSSを追加、その他お気にいりのフィードを追加する
  • 取得したフィードを共有する
  • 参考:delicious
  • 参考:はてなブックマーク

メディアを公開する:写真を共有する

  • Picasaを使って写真を公開
  • 参考:Flickr

動画を共有する

  • YouTubeを使って動画を公開
  • 参考:Vimeo

グループワーク

  • Google Document – ワードプロセッサ、スプレッドシート、フォーム作成、文書の共有
  • Google Wave – リアルタイムに協調作業

日常の全てを記録する、ライフログ

  • Google Buzzで、日常の全てを記録
  • 参考:FriendFeed

中間課題講評会

課題講評会

  • 連休中の課題の講評会を行います

課題内容の確認

  • 2つの物体による、アニメーション表現
  • 単純な形態を2つ(円や四角形、三角形など)をシンボルに
  • 物体の動きだけで、感情や意味を表現する
  • 映像の5つの動き(等速、加速、減速、静止、ランダム)を活用して
  • シンボルの移動だけでなく、変形、回転、色の変更などを自由に使用して

課題の提出方法

  • 作成した課題は、Webブラウザで見られるようにして、大学のWebサーバにアップロード
  • Webブラウザで見られるように、.fla形式のファイルを変化する操作を「パブリッシュ」と呼ぶ

パブリッシュの手順

  • 作成した、課題のFlashファイル(.fla形式)を開く
  • メニューから「ファイル」→「パブリッシュ設定」を選択
  • 「パブリッシュ設定」画面の「形式」タブを選択
  • タイプから、「Flash (.swf)」と「HTML (.html)」を選択
  • Flashのファイル名は、半角英数文字で任意の名前を、拡張子は「.swf」にすること
  • HTMLのファイル名は必ず「index.html」に設定する
  • 「Flash」と「HTML」のタブは、デフォルトの設定のまま
  • 設定が完了したら「パブリッシュ」ボタンを
  • パブリッシュが完了すると、「xxx.swf (任意の名前)」「index.html」というファイルが生成される
  • ffftpを使用して、cucのweb-publicの以下の場所に生成された2つのファイルをアップロードする
  • http://www.cuc.ac.jp/~ログイン名/webani/assingment1/
  • 詳細は授業内で解説します


「パブリッシュ設定」メニュー


「パブリッシュ設定」設定画面

ActionScript はじめの一歩

ActionScriptとは

  • ActionScript – Flashで使用されるプログラミング言語
  • コンテンツにインタラクション(双方向性)を持たせる
  • 動画や音声の再生
  • Flash CS4で用いることのできる最新バージョンは、ActionScrpt 3.0 (AS3)

最初の一歩 – フレーム間の移動

  • 単純なスクリプトでまずは実践
  • フレーム間の移動を試してみる

最後のフレームで再生を終了する

  • タイムラインにActionScriptを記述するためのレイヤーを追加
  • 追加したレイヤーの最終フレームにキーフレームを追加
  • 追加したキーフレームを選択した状態で、メニューから「ウィンドウ」→「アクション」を開く
  • 表示された画面に以下のスクリプトを記述
  • 最終フレームで再生が止まるはず
stop();


最終フレームにキーフレームを追加


「アクション」ウィンドウを開く


ActionScriptの記入


アニメーション、条件分岐

アニメーション

アニメーションをするには

  • プログラミングの構造化が必要となる
  • setup:初期化関数
  • draw:メインループ関数

Processingのプログラム構造のイメージ

setup:初期化関数

  • プログラムの最初に、1回だけ実行される処理を記述、アニメーションの前準備
  • setupの中で行われることの多い処理
  • size:画面のサイズを設定
  • colorMode:カラーモードを設定
  • frameRate:画面の書き換え速度を設定

draw:メインループ関数

  • プログラムが終了するか、noLoop()関数が呼ばれるまでは、プログラムを実行し続ける
  • ループの中で図形の場所や色、形を操作してアニメーションにする
  • 画面の書き換え頻度はsetup()関数内のframerate()関数で設定する

構造化されたプログラムの例:増殖する円

//setup - 初期化関数
void setup()
{  
    size(480,480);
    //書き換え頻度の設定
    frameRate(12); 
    //円弧の描画をなめらかに
    smooth();
    //背景を最初に描く
    background(0);
}

//draw - メインループ
void draw()
{
  //円の直径をランダムに設定  
  float diameter = random(100);
  noStroke();
  //塗りの色をランダムに
  fill(random(255),random(255),random(255));
  //円を描画
  ellipse(random(width),random(height),diameter,diameter);
}

アニメーション作成の考えかた

  • setup関数で全体に共通の設定を初期化
  • draw関数を繰り返す
  • 背景の描画
  • 図形を描く
  • パラメータ(場所、色など)を微妙に変更

アニメーションの例1:円を動かしてみる

//グローバル関数の定義 (x座標、y座標)
int x, y;  

//初期化関数
void setup(){ 
  //画面サイズの設定  
  size(640,480);
  //フレームレート(書き換え頻度)設定
  frameRate(30);
  //色の設定
  colorMode(HSB,360,100,100,100);
  noStroke();
  fill(200,80,80);
  //初期位置の座標を設定
  x = 0;
  y = 0;
}

//メインループ
void draw(){ 
  //背景の再描画
  background(0); 
  //円の描画
  ellipse(x,y,50,50);
  //x座標更新
  x = x+1; 
  //y座標更新
  y = y+1; 
}

円が画面の幅(width)と高さ(height)から、はみ出ないようにするには?

  • 方法:画面の幅 (width) を変化する変数 x の場合
  • x を 画面の幅(width)で割った余りを、円のx軸上の位置にする
  • 画面の幅からはみ出た場合は、また0に戻る
  • y は 画面の高さ(height)の余りをとる
  • よって以下のようにする
  • x座標の位置 = x % width;
  • y座標の位置 = y % height;
  • % : 余りを計算する演算子
  • 例:5 % 2 = 1 (5/4 = 2 余り1 だから)
  • アニメーションの例1:円を動かしてみる – 画面からはみ出さないようにしたバージョン
//グローバル関数の定義 (x座標、y座標)
int x=0, y=0;
//初期化関数
void setup()
{
    size(640,480);
    frameRate(30);
    colorMode(HSB,360,100,100,100);
    noStroke();
    fill(200,80,80);
}

//メインループ
void draw()
{
    background(0);
    //画面からはみ出さないように座標を計算
    ellipse(x%width,y%height,50,50);
    x = x+5;
    y = y+3;
}

座標以外の値をアニメーションする

  • アニメーションの変化するパラメータは座標だけではない
  • 色をアニメーションすることも可能
  • fillの値を変化させれば、色が徐々に変化していく
  • アニメーションの例2:色相の変化
//グローバル変数 (色相の変化)
int h = 0; 

//初期化関数
void setup()
{
    size(640,480);
    frameRate(30);
    colorMode(HSB,360,100,100,100);
    smooth();
    noStroke();
    fill(200,80,80);
}

//メインループ//メインループ
void draw(){
    background(0);
    //色相を変数「h」で 0〜360の間で変化させている
    fill(h%360,80,80);
    //設定した塗りの色で円を再描画
    ellipse(width/2,height/2,200,200);
    //変数の値を更新
    h++;
}

条件分岐

条件分岐をつかって、円が画面からはみ出ないようにしてみる

  • 剰余演算子「%」を使用した方法意外のやりかたで、画面からはみ出ないようにしてみる
  • 条件分岐を使用して、画面の端に来たら位置を修正するようにしてみる
  • パックマンの画面移動のイメージ

条件分岐の構文

  • 例 – 「もし画面の外にでたら、反対から出現する」
  • もし○○したら、××せよ:条件分岐命令の典型的な例
  • if〜else文:条件分岐をProcessingで記述する
if( [条件式] ){
    [条件が正しい場合の処理]
} else {
    [条件が誤っている場合の処理]
}

条件「もし画面の外に出たら」→ 4つの可能性

  • 画面の右端にはみ出る
  • 条件式:x > width
  • 画面の左端にはみ出る
  • 条件式:x < 0
  • 画面の下端にはみ出る
  • 条件式:y > height
  • 画面の上端にはみ出る
  • 条件式: y < 0

それぞれの条件をif文に書いてみる

  • 画面の右端からはみ出たら、左端に移動
  • if(x > width) { x = 0; }
  • 画面の左端からはみ出たら、右端へ移動
  • if(x < 0) { x = width; }
  • 画面の下端からはみ出たら、上へ移動
  • if(y > height) { y = 0; }
  • 画面の右端からはみ出たら
  • if(y < 0) { y = height; }

条件分岐を付加したプログラム

//x座標、y座標
float x, y;
//x軸方向のスピ-ド, y軸方向のスピ-ド
float xSpeed, ySpeed; 

//初期化関数
void setup()
{
    size(480,480);
    frameRate(30);
    colorMode(HSB,360,100,100,100);
    noStroke();
    fill(180,100,80,80);
    //初期位置を画面の範囲内でランダムに決定
    x = random(width);
    y = random(height);
    //スピードも -10〜10 の範囲でランダムに
    xSpeed = random(-10,10);
    ySpeed = random(-10,10);
}

//メインループ
void draw(){ 
  background(0); 
  //円の描画
  ellipse(x,y,40,40);
  //x座標更新
  x+=xSpeed;
  //y座標更新
  y+=ySpeed;

  //条件分岐で画面の範囲内にいるかを判定
  
  //条件1.もし画面の右端からはみ出たら
  if(x > width){
      //画面の左端に移動
      x = 0;
  }

  //条件2.もし画面の左端からはみ出たら
  if(x < 0){
      //画面の右端に移動
      x = width;
  }

  //条件3.もし画面の下端からはみ出たら
  if(y > height){
      //画面の上端に移動
      y = 0;
  }

  //条件3.もし画面の上端からはみ出たら
  if(y < 0){

      //画面の下端に移動
      y = height;
  }
}

壁で跳ね返ってくる動き

  • 現状のプログラムを改造して、画面からはみ出た際に反対側から出現するのではなく、画面の境界を壁にして、跳ね返るように変更してみる
  • ブロック崩しのイメージ
  • バウンドを表現するには?
  • x方向のスピードはどうなるのか?
  • y方向のスピードはどうなるのか?

//グローバル変数
float x, y, xSpeed, ySpeed; 

//初期化関数
void setup()
{
    size(480,480);
    frameRate(30);
    colorMode(HSB,360,100,100,100);
    noStroke();
    fill(180,100,80,80);
    x = random(width);
    y = random(height);
    xSpeed = random(-10,10);
    ySpeed = random(-10,10);
}

//メインループ
void draw()
{ 
    background(0);
    ellipse(x,y,40,40);
    x += xSpeed;
    y += ySpeed;

    //画面の左端、もしくは右端からはみ出たら
    if(x > width || x < 0){
	//X軸方向のスピードを反転
	xSpeed *= -1;
    }
    
    //画面の上端、もしくは下端からはみ出たら
    if(y > height || y < 0){
	//Y軸方向のスピードを反転
	ySpeed *= -1;
    }
}    

openFrameworks入門

openFrameworks入門

  • OpenFrameworksの紹介
  • OpenFrameworksを使ってみる
  • 簡単なプログラムを実行
  • OpenFramwroskをiPhoneで使ってみる
  • 簡単なアニメーションを作成してみる

OpneFrameworksについて

  • OpenFrameworksとは、シンプルで直感的なフレームワークによって、創作活動を手助けするようにデザインされた、C++のライブラリ
  • オフィシャルページ
  • Zach LiebermanとTheodore Watson、Arturo Castroを中心に開発が進められている
  • Processingからの強い影響
  • C++の細かな知識なしに、クリエイティブな部分のみコーディングすることで、高度なアプリケーションを開発可能
  • openFrameworksから影響を受けたプロジェクトも派生している → Cinder

made with openFrameworks from openFrameworks on Vimeo.

OpneFrameworksの入手方法

  • openFrameworksのダウンロードページから
  • 最新のバージョンをダウンロードする
  • 2009年5月現在の最新は、v0.061
  • iPhoe版の “iPhone 0061 FAT” をダウンロード
  • Macでも開発したい人は、mac版の ”x-code FAT” をダウンロード、OS 10.5と10.6によって別になっているのに注意
  • FAT版とは?
  • あらかじめ主要な addon (拡張機能) が組込まれたバージョン
  • OpenCV, OSCの入出力 など

サンプルを実行してみる

  • Mac版「of_preRelease_v0061_osxSL_FAT/apps/examples/」以下にあるフォルダ内のXCodeのプロジェクトファイル「.xcodeproj」を開く
  • iPhone版の場合は「of_preRelease_v0061_iPhone_FAT-pre3/apps/examples/」以下
  • プロジェクトファイルを開くと、自動的にXcodeが起動するはず
  • ツールバーの「ビルドして進行」を押す
  • プログラムがコンパイルされ、エラーが無ければそのままサンプルが実行される


advancedGraphics (iPhone版)

新規プロジェクトの作成場所

  • まずは、自分のプロジェクトを格納するためのフォルダを用意する
  • openFrameworksでは、プロジェクトを格納する場所が指定されている – それ以外の場所にプロジェクトを作成しても動かないので注意!!
  • プロジェクトを格納する場所
  • Mac版「of_preRelease_v0061_osxSL_FAT/apps/[任意のフォルダ]/」以下に
  • iPhone版「of_preRelease_v0061_iPhone_FAT-pre3/apps/[任意のフォルダ]/」以下に
  • 例えば自分用の新規プロジェクトを作成するフォルダを「myApps」とすると
  • Mac版「of_preRelease_v0061_osxSL_FAT/apps/myApps/」以下にプロジェクトのフォルダを作成
  • iPhone版「of_preRelease_v0061_iPhone_FAT-pre3/apps/myApps/」以下にプロジェクトのフォルダを作成

新規プロジェクトの作成

  • openFrameworksの新規プロジェクトを作成する際には、空のプロジェクトをフォルダごとコピーして使用する
  • Mac版 「of_preRelease_v0061_osxSL_FAT/apps/examples/emptyExample」
  • iPhone版 「of_preRelease_v0061_iPhone_FAT-pre3/apps/iPhoneExamples/emptyExample」
  • プロジェクトのフォルダごとコピーして、myAppsフォルダ以下に配置
  • コピーしたemptyExampleフォルダの名称を変更 – 「myNewApp」など
  • プロジェクトのフォルダ内にある、XCodeのプロジェクトファイルの名称も変更 – 「myNewApp.xcodeproj」など
  • XCodeのプロジェクトファイルをダブルクリックして、XCodeを起動
  • グループとファイル」の一覧の中の「ターゲット」の項目内のターゲットファイルのアイコンを右クリックして、「名称変更」を選択します
  • ターゲットの名称をプロジェクト名と同じ名前に – 「myNewApp」など


emptyExampleフォルダの場所


myAppsフォルダにコピー


プロジェクトのフォルダ名の変更


プロジェクトファイル名の変更


ターゲットの名称を変更


ターゲットの名称変更が完了した状態

OpneFrameworksのコード構造

  • さしあたって、編集する必要のあるファイルは、testApp.hとtestApp.cpp (iPhone版の場合は、testApp.mm) のみ!
  • 様々な既存のライブラリが結びついている
  • アプリケーション作成のための「糊」のような存在


openFrameworksの構造

プログラムを作成してみる

  • testApp.h
  • プログラムの中心となるヘッダファイル
  • testApp.cpp で使用される、変数、メソッドなどを宣言する場所

testApp.h (OS X 版)

#ifndef _TEST_APP
#define _TEST_APP


#include "ofMain.h"

class testApp : public ofBaseApp{

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);

};
#endif

testApp.h (iPhone版)

#pragma once

#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"

class testApp : public ofxiPhoneApp {
	
public:
  void setup();
  void update();
  void draw();
  void exit();
	
  void touchDown(ofTouchEventArgs &touch);
  void touchMoved(ofTouchEventArgs &touch);
  void touchUp(ofTouchEventArgs &touch);
  void touchDoubleTap(ofTouchEventArgs &touch);
    
  void lostFocus();
  void gotFocus();
  void gotMemoryWarning();
  void deviceOrientationChanged(int newOrientation);
};
  • testApp.cpp (iPhone版の場合は、testApp.mm)
  • プログラムの中心となる実装ファイル
  • 画面の表示、アニメーション、マウスやキーボードとのインタラクションなど、主要な機能はここで定義される

testApp.cpp (OS X 版)

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    
}

//--------------------------------------------------------------
void testApp::update(){
    
}

//--------------------------------------------------------------
void testApp::draw(){
    
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
    
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){
    
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
    
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
    
}

testApp.mm (iPhone版)

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
  // register touch events
  ofRegisterTouchEvents(this);
  
  // initialize the accelerometer
  ofxAccelerometer.setup();

  //iPhoneAlerts will be sent to this.
  ofxiPhoneAlerts.addListener(this);
  
  //If you want a landscape oreintation 
  //iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);
  ofBackground(127,127,127);
}

//--------------------------------------------------------------
void testApp::update(){
    
}

//--------------------------------------------------------------
void testApp::draw(){
	
}

//--------------------------------------------------------------
void testApp::exit(){
    
}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::lostFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){
    
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
    
}

testApp内で使用される主な関数(メソッド)

  • testApp.hとtestApp.cpp (testApp.mm) 内には、様々な関数が宣言されている
  • void setup(); / void update(); / void draw(); / void keyPressed(int key); ..etc
  • それぞれの関数で処理される内容が来まっている
定義 機能
setup プログラムが起動した際に1度だけ実行される。初期化。
update 一定間隔で繰り返し実行される。draw関数の直前に実行される。変数の値の更新に使用する。
draw update関数の直後に実行される。描画に関する命令に使用する。
exit プログラムが終了する直前に実行される。
keyPressed キーボードを押した瞬間に実行される。
keyReleased キーボードを離した瞬間に実行される。
mouseMoved マウスを移動した際に実行される
mouseDragged マウスをドラッグした際に実行される
mousePressed マウスボタンを押した瞬間に実行される
mouseReleased マウスボタンを離した瞬間に実行される
touchDown 画面をタッチした瞬間に実行される(iPhone版のみ)
touchMoved 画面をタッチして移動した際に実行される(iPhone版のみ)
touchUp タッチしていた画面から離れた瞬間実行される(iPhone版のみ)
touchDoubleTap ダブルタップ(素早く2回画面をタップ)した瞬間に実行される(iPhone版のみ)

簡単な図形を描いてみる

  • 3つの円を描いてみる
  • アルファチャンネル(透明度)を指定
  • 色の混色を、加法混色に
  • testApp::draw() 関数に色を指定して円を描く命令を追加する

testApp.cpp (OS X 版)

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    ofBackground(0, 0, 0);
}

//--------------------------------------------------------------
void testApp::update(){
    
}

//--------------------------------------------------------------
void testApp::draw(){
    //アルファチャンネル(透明度)を使用可能に
    ofEnableAlphaBlending();
    //混色を、加算混色に
    glBlendFunc(GL_ONE, GL_ONE);
    //塗りの色を赤に
    ofSetColor(255, 0, 0, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2, ofGetHeight()/2-40, 150, 150);
    //塗りの色を青に
    ofSetColor(0, 0, 255, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2-40, ofGetHeight()/2+40, 150, 150);
    //塗りの色を緑に
    ofSetColor(0, 255, 0, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2+40, ofGetHeight()/2+40, 150, 150);  
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
    
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){
    
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
    
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
 
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
    
}

testApp.mm (iPhone版)

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){	
	// register touch events
	ofRegisterTouchEvents(this);
	
	// initialize the accelerometer
	ofxAccelerometer.setup();
	
	//iPhoneAlerts will be sent to this.
	ofxiPhoneAlerts.addListener(this);
	
	//If you want a landscape oreintation 
	//iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);
	
	ofBackground(0,0,0);
}

//--------------------------------------------------------------
void testApp::update(){
    
}

//--------------------------------------------------------------
void testApp::draw(){
    //アルファチャンネル(透明度)を使用可能に
    ofEnableAlphaBlending();
    //混色を、加算混色に
    glBlendFunc(GL_ONE, GL_ONE);
    //塗りの色を赤に
    ofSetColor(255, 0, 0, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2, ofGetHeight()/2-40, 150, 150);
    //塗りの色を青に
    ofSetColor(0, 0, 255, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2-40, ofGetHeight()/2+40, 150, 150);
    //塗りの色を緑に
    ofSetColor(0, 255, 0, 63);
    //円を描く
    ofEllipse(ofGetWidth()/2+40, ofGetHeight()/2+40, 150, 150);
}

//--------------------------------------------------------------
void testApp::exit(){
    
}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::lostFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){
    
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
    
}


実行結果(iPhone版)

アニメーションの基本構造

  • アニメーションを構成する3つの関数 – setup()、update()、draw()
  • setup()
  • 初期化関数
  • プログラムを実行したときに最初に1回だけ実行したい命令を記入
  • 画面書き換えの速度の設定(フレームレート)、背景色、外部データのロードなど
  • update()
  • メインループ関数、指定した画面書き換え速度の設定(フレームレート)の設定に従って、繰り返し実行、
  • draw()関数の前に実行され、プログラムに記憶された値を更新する際に使用される
  • draw()
  • 描画関数
  • update()関数と同様に、指定された画面書き換えの間隔(フレームレート)でプログラムが終了するまで、繰り返し実行
  • 画面の描画に関する命令を実行する

簡単なアニメーションを作成する

  • 画面全体を回転してみる
  • 回転角度は、angleという変数に格納
  • setup() – 表示の初期設定、背景色の定義、フレームレート設定、回転角度の初期化
  • update() – 回転角度を10°増加させる
  • draw() – 画面を描画

testApp.cpp (OS X 版)

#include "testApp.h"

double angle; //傾きの角度

//--------------------------------------------------------------
void testApp::setup(){
    //背景色を黒に
	ofBackground(0,0,0);
    //フレームレートを60fpsに
    ofSetFrameRate(60);
    //角度を初期化
    angle = 0;
}

//--------------------------------------------------------------
void testApp::update(){
    //角度を10°増加させる
    angle+=10;
}

//--------------------------------------------------------------
void testApp::draw(){
    //現在の座標系を保存
    ofPushMatrix();
    //座標系の原点(0,0)を、画面の中心に
    ofTranslate(ofGetWidth()/2, ofGetHeight()/2, 0);
    //画面のX軸を40°回転
    ofRotateX(40);
    //画面のZ軸を、angleの角度回転させる
    ofRotateZ(angle);
    //アルファチャンネル(透明度)を使用可能に
    ofEnableAlphaBlending();
    //混色を、加算混色に
    glBlendFunc(GL_ONE, GL_ONE);
    //塗りの色を赤に
    ofSetColor(255, 0, 0, 63);
    //円を描く
    ofEllipse(0, -40, 150, 150);
    //塗りの色を青に
    ofSetColor(0, 0, 255, 63);
    //円を描く
    ofEllipse(-40, 40, 150, 150);
    //塗りの色を緑に
    ofSetColor(0, 255, 0, 63);
    //円を描く
    ofEllipse(40, 40, 150, 150);
    //座標系を復元
    ofPopMatrix();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
    
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){
    
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
    
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
 
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
    
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
    
}

testApp.mm (iPhone版)

#include "testApp.h"

double angle; //傾きの角度

//--------------------------------------------------------------
void testApp::setup(){	
	// register touch events
	ofRegisterTouchEvents(this);
	
	// initialize the accelerometer
	ofxAccelerometer.setup();
	
	//iPhoneAlerts will be sent to this.
	ofxiPhoneAlerts.addListener(this);
	
	//If you want a landscape oreintation 
	//iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);
	
    //背景色を黒に
	ofBackground(0,0,0);
    //フレームレートを60fpsに
    ofSetFrameRate(60);
    //角度を初期化
    angle = 0;
}

//--------------------------------------------------------------
void testApp::update(){
    //角度を10°増加させる
    angle+=10;
}

//--------------------------------------------------------------
void testApp::draw(){
    //現在の座標系を保存
    ofPushMatrix();
    //座標系の原点(0,0)を、画面の中心に
    ofTranslate(ofGetWidth()/2, ofGetHeight()/2, 0);
    //画面のX軸を40°回転
    ofRotateX(40);
    //画面のZ軸を、angleの角度回転させる
    ofRotateZ(angle);
    //アルファチャンネル(透明度)を使用可能に
    ofEnableAlphaBlending();
    //混色を、加算混色に
    glBlendFunc(GL_ONE, GL_ONE);
    //塗りの色を赤に
    ofSetColor(255, 0, 0, 63);
    //円を描く
    ofEllipse(0, -40, 150, 150);
    //塗りの色を青に
    ofSetColor(0, 0, 255, 63);
    //円を描く
    ofEllipse(-40, 40, 150, 150);
    //塗りの色を緑に
    ofSetColor(0, 255, 0, 63);
    //円を描く
    ofEllipse(40, 40, 150, 150);
    //座標系を復元
    ofPopMatrix();
}

//--------------------------------------------------------------
void testApp::exit(){
    
}

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::touchDoubleTap(ofTouchEventArgs &touch){
    
}

//--------------------------------------------------------------
void testApp::lostFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotFocus(){
    
}

//--------------------------------------------------------------
void testApp::gotMemoryWarning(){
    
}

//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
    
}


実行結果(iPhone版)