Shuhei Kagawa

iPhone で OpenFrameworks

二次元で Strange Attractor 的なものをつくってみました。パーティクルの点描ではなく軌跡を描いています。

Attractor2D

Processing と全く同じような感じで書けるので、よけいなことに労力を費やさずにすみます。今後 iPhone で OpenFrameworks を使って行くならば、UIKit との組み合わせ方と、審査が通るかどうかを調べなければいけませんね。

OpenGL のブレンディング方法について

Aug 2, 2009 - C/C++, OpenFrameworks

OpenFrameworks が iPhone 上で動くというので、触ってみています。ついこの前、Objective-C やりますと書きましたが、最近 C++ がマイブームなので・・・。

そこで調べてみた OpenGL のブレンディングについてメモ。一言で言うと、ブレンディングとは画像に画像を合成することです。Photoshop などでは、レイヤーとレイヤーの画像の合成の方法をブレンドモードと言っていますね。OpenGL では自分で書く訳ですから、ブレンディングの方法をさらに柔軟に指定できます。

まずは有効に

ブレンディングを有効にするには以下の関数を呼ばなければなりません。

glEnable(GL_BLEND);

設定関数

ブレンドする二つの画像を source と destination とします。OpenGL では、これから描くのが source、destination はフレームバッファ上の画像だそうです。

glBlendFunc

glBlendFunc では、それぞれの画像の RGBA にかける係数を設定します。下記は一例です。

  • GL_ONE RGBA 全てを 0 にする
  • GL_ZERO RGBA 全てそのまま
  • GL_SRC_ALPHA RGBA 全てに source の A をかける

glBlendEquation

glBlendEquation では、画像同士の RGBA を合成する方法を設定します。

  • GL_FUNC_ADD 足す
  • GL_FUNC_SUBTRACT source から destination を引く
  • GL_FUNC_REVERSE_SUBTRACT destination から source を引く
  • GL_MAX 大きい方をそのまま使う
  • GL_MIN 小さい方をそのまま使う

その他

iPhone では glBlendEquation ではなく glBlendEquationOES を使いますが、働きは同じもののようです。また glBlendFuncglBlendEquation では RGBA 全てを一緒に設定しますが、 glBlendFuncSeparateglBlendEquationSeparate を用いると RGB と Alpha を別々に設定できるようです。

実例

Additive blending

光の表現に。暗めの色を重ねていくと、ぼんやりと光るようないい感じになります。

glBlendEquationOES(GL_FUNC_ADD); // デフォルトは GL_FUNC_ADD のようで必要ないかも
glBlendFunc(GL_ONE, GL_ONE);
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); // こっちの方がいい感じになるとか・・・。

フェードアウト

もっといい方法があるかもしれませんが、他にやり方が思いつかなかったので。

glBlendEquationOES(GL_FUNC_REVERSE_SUBTRACT_OES); // 暗くするため、元画像から引く
glBlendFunc(GL_ONE, GL_ONE); // そのまま
ofSetColor(10, 10, 10, 0); // 少しずつ暗くします
ofRect(0, 0, ofGetWidth(), ofGetHeight()); // 画面全体に適用します

const とポインタ

Aug 1, 2009 - C/C++

下のように const は型名の前後どちらに書いても同じです。

const int a = 1;
int const b = 2;

Bjarne Stroustrup’s C++ Style and Technique FAQ では、前者がわかりやすくおすすめとされていますが。

では、ポインタについてはどうでしょうか?

const int* pa = new int(10);  // "const な int" へのポインタ
int const* pb = new int(11);  // "const な int " へのポインタ
int* const pc = new int(12);  // int への  "const なポインタ"

一つ目と二つ目は同じです。では、どのような挙動になるのでしょうか?

// *pa = 20;  // エラー! "const な int" の値を変えることはできない
// *pb = 21;  // エラー! "const な int" の値を変えることはできない
*pc = 23;

delete pa;   // delete はできる
delete pb;   // delete はできる
delete pc;

pa = NULL;
pb = NULL;
// pc = NULL;  // エラー!ポインタ自体が const なため

というような感じになります。普通は const int* pa の方を使う機会が多いような気がしますね。