独り言日記
2004/05/31 update.

イラディアンスキャッシュ
更新日時 2004/05/31
内容 パストレで放射照度キャッシュ(irradiance caching)を実装してみました。 2倍速くらいになりました。しかも、パストレでの高周波ノイズが消えますね(低周波化する)。
ただ、理解するまでにかなり時間を費やしてしまいました。Jensen本だけではなんのことやら・・・(^_^;;。 結局、藤田さんのlucilleのソースを見ながらようやくどういうことか理解できた次第です。
考え方としては、視点からレイを飛ばしたときの交点での間接照明を計算し(ここから拡散反射でA回レイを反射させて、 さらにぶつかった交点でA回反射する場合、全部でA^2の交点計算を行います)この情報を「キャッシュ」することになります。
パストレでは、サンプリング時は1つのレイを反射させて(分岐させずにロシアンルーレットして)計算した放射照度の平均を取る、となるのですが、 irradiance cachingの場合は、グループ化した1点を中心とした(半球で表される)放射照度の集合を元に調和球を作成して、これを八分木に納めていく といった感じになります。まずはじめに、irradiance cachingを利用するためのスキャンを行っておくというのがミソです。
実際のレイトレース処理では、キャッシュに蓄えた情報での重み付けを元に放射照度を「補間」します。 なんで、ノイズが出ないんですね。
図解やサンプル比較画像で示したらわかりやすいのですが、ちとサーバ容量の都合上文章のみです。
また日記に関しては、新サーバのwikiにでも移行しようかな。
irradiance cachingでは「放射照度勾配」により、さらに精度をアップできるらしいですので ここまで試してみることにします。
問題は、微調整のパラメータ(有効範囲の半径と、重み付けのしきい値)が増えることでしょうか。 この制御が面倒っすね(うまくやらないと綺麗な絵が出ないです)。
続・パストレ
更新日時 2004/05/28
内容 パストレの照度計算について調べると、私の実装は思いっきり間違ってました。
今までは拡散反射するたびに交点での放射照度を加算していたのですが、どうも掛けていくのが 正しいようです。

そして、修正して以下のような画像になったのですが(100 paths/pixel)、 一応重点的サンプリング(フォトンマップを使ったやつではありません。単純な方です。)で ノイズを緩和しています。

Jensen氏の本では視点の後ろが黒(または背景が黒)なのに、 そのノイズがシーン内に入ってきていません(10 paths/pixelのパストレのサンプルを見ても)。
私の場合は、バックを黒にすると激しくノイズが出るのですが・・・。 う〜ん、まだ根本的に私のほうが間違っている予感・・・(^_^;;
もうちと、基礎的な部分を重ねてからフォトンに行こうかなと。いかんせん、まだ知識不足ですわ。

以下、フォトンマップ本のJensen氏のサイトなのですが、
http://graphics.ucsd.edu/~henrik/
http://graphics.ucsd.edu/~henrik/images/imgs/cboxgi.jpg
で、Dual Pentium III 800MHzで15秒って・・・すごすぎ。もう、マジシャンですね(^_^;;
てろてろ
更新日時 2004/05/26
内容 矢野絢子のマキシシングル「てろてろ」を購入。ピアノで歌い上げる方で、聴き入りますなぁ。 って、ライブの方がビフラートが綺麗に出ていてCDのほうはちと薄いですね。

さて、話題はがらっと変わって3DNow!をいじってます。
これを使った場合の消費クロック数を精密に求めることができないか、ということで調べてみました。
ある処理の消費クロック数を調べます。


//現在のCPUクロックを取得
LARGE_INTEGER GetClockCounter()
{
  LARGE_INTEGER cycles;
  _asm {
    cpuid
    rdtsc
    mov cycles.LowPart,  eax
    mov cycles.HighPart, edx
  }
  return cycles;
}
これで、現在のクロック数累積が出るわけで、この戻り値の差を調べると その間の処理での消費クロック数が求まるわけです。
しかし、この関数呼び出しでも時間を食ってしまいます。そこで、あらかじめカラ処理の時間を求めておきます。

//CPUクロック差を計算
int CalcDiffCPUClock()
{
  LARGE_INTEGER c1, c2;
  int i;
  int minVal, val;

  minVal = 0x7fffffff;
  for(i = 0; i < 100; i++) {
    c1 = GetClockCounter();
    c2 = GetClockCounter();
    val = (int)(c2.QuadPart - c1.QuadPart);
    if(val < minVal) minVal = val;
  }
  return minVal;
}
なぜ100回もループさせているかというと、誤差で揺れるからです。 キャッシュが効いたりするからでしょうか。ですので、一番小さい差分のみを保持して 返すようにします。
で、時間を計る場合は以下のようにします。

LARGE_INTEGER stTim, endTim;

//クロックカウントの時間差を取得
int diffTim = CalcDiffCPUClock();

//クロックカウントの取得
stTim = GetClockCounter();

//この間で、処理を行う
_asm {
  push eax
  xor eax, eax
  pop eax
}

//クロックカウントの取得
endTim = GetClockCounter();

//時間差(クロック数の差)を求める
int val;
val = (int)(endTim.QuadPart - stTim.QuadPart) - diffTim - 1;
printf("消費クロック数 : %d clocks\n", val);
この場合、_asmの中でかかるクロック数を取得することになります。
なお、カラで計測をした場合に0になるように微調整してください。 うちのAthlon1100MHzでは、カラでも1クロックのカウントをしていたので、 計測値を-1しました(valの末尾)。
この例では2クロックです。おそらく、UVのパイプラインのペアリングが効いているのでしょう。
後はいかに効率のいいコード(コード記述とペアリング)を書いてしのぎを削るか、ですね。

ちなみに、3DNow!でのベクトルの長さを求める、というのをアセンブラで書いた場合は 以下のようになります。

//3頂点の情報
typedef struct {
    float x, y, z;
} POINT3D;

float VectorLength_3DNow(POINT3D *p)
{
    _declspec(align(16)) float len;
    void *pPos = (void *)p;

    _asm {
        femms
        push esi

        //x,yの要素を[mm0]に入れる
        mov esi, pPos
        movq mm0, [esi]

        //zの要素を[mm1]に入れる
        movd mm1, [esi + 8]

        //mm0(low) = x * x + y * y
        pfmul (m0, m0)
        pfacc (m0, m0)

        //mm1(low) = z * z
        pfmul (m1, m1)
        
        //mm0(low) = x * x + y * y + z * z
        pfadd (m0, m1)

        //m1 = 1/sqrt(x * x + y * y + z * z)
        pfrsqrt (m1, m0)
        movq mm2, mm1
        pfmul (m1, m1)
        pfrsqit1 (m1, m0)
        pfrcpit2 (m1, m2)

        //m0 = sqrt(x * x + y * y + z * z)
        pfmul (m0, m1)

        movd len, mm0

        pop esi
        femms
    }

    return len;
}
これで、_asm内は38クロック消費です。が、まだパイプラインでの最適化は考慮してませんので どれくらい速くなるか試してみようかと思います。
ちなみに現在の段階でも3DNow!の場合、普通のFPU(単精度浮動小数点)計算の2倍強高速化できています。
これは2並列のSIMDを行ってるからでしょうね。
ただ、3DNow!では、加減乗算は2並列で処理できるのですが、わり算(逆数を求める)・平方根・逆数平方根を求める部分は 並列にはできません。ですので、このあたりはPentium3以降のSSE/SSE2に軍配が上がります。

レンダラにこのCPU最適化を取り込む場合は部分的でなくて全体的な 調整が不可欠なんですが(ベクトル演算・行列演算くらいではあまり貢献しないです)、 チリも積もれば山となる、でクロックのしのぎを削ることでちょっとは速くなればいいなぁ。
また、パストレの速度アップ・品質アップのいいアイデアが浮かびましたので、 このあたりもせめてみようかと思ってます。
CPUレベルのカスタマイズ
更新日時 2004/05/24
内容 こちらの環境はAthlonであるので、SIMD(複数の演算を並列で行う)が不可能かと思ったのですが、 工夫次第で可能なようです。
まず、MMXレジスタとしては64ビットのレジスタmm0〜mm7の計8個分あるわけですが、「32ビット+32ビット」の 2並列のfloat演算などは「3DNow!」にて可能になります。
また、基本的にMMXは2パイプラインで動作しますのでfloat演算の場合は、2 x 2 = 4並列で動かそうと思うと 動かせそうです。
これ、うまく使って速度アップに利用できないかなぁと考えています。
ということで、今更「3DNow!」テクノロジを熱くいぢくろうかと(^_^;;
フォトン対応
更新日時 2004/05/23
内容 フォトン対応してみました。
30000フォトンを面光源から飛ばし、サンプリング数は 10/pixel、640x480pixelでレンダリングです。
これで、Athlon 1100MHz/Mem512MBで302秒(約5分)。 ドラゴンのあるシーンは面光源と点光源を配置しています(全10万ポリゴン強)。これで718秒(約12分)。

まだ最適化はしていないのですが、後3倍は高速化したいなぁ。 やはり、モヤモヤが気になりますので何とかしたいところです。かなり適当にフォトンをかき集めてますので、普通よりも粗いかと思います。
まだ、フォトンを飛ばしたときの照度計算を理解してませんので、 基礎から積み重ねていこうと思っています。
・・画像をアップするとすぐ容量オーバしてしまいますね(^_^;; はやくこのあたりを整備しないと。
パストレでの低周波ノイズ化
更新日時 2004/05/20
内容 実験結果、パストレでの低周波ノイズ化はできることはできましたが、 kd-treeを使うとフォトンライクなモヤモヤが出てきますね。でも、間接光だけ ノイズを低周波化して扱い、直接光の部分と合成すると緩和できるかも。
ちなみに、レンダリング時間は(5/17の日記に載せている) ドラゴンの画像が3分(640*480 pixel)、 面光源のある部屋の画像が12分(640*480pixel)でした。 サンプル数が10/pixelでもそれなりの画像が得られますね。
アルゴリズム的には、交点位置と放射照度をキャッシュした といった感じになるのですが(それの平均を取って平滑化する)、 蓄える放射照度の数を考えると フォトンマップのほうが現実的かな(^_^;;。
「サンプリング」を前提とした処理はパストレ・フォトンマップの両方でも存在しているわけで、 これを根本から変えないことにはノイズからは逃げることはできないなぁ。
なんとかいい抜け道を編み出したいところですが・・・。
メモリ使用量を考えると、フォトンを使ったkd-treeも案外圧迫しますねぇ。 プログラム的には純粋なパストレのほうが美しいのですが、速度が・・・
フォトンも一通り実験した後はイラディアンスキャッシュですねぇ、とりあえずは。
面光源
更新日時 2004/05/19
内容 面光源対応してみました。アルゴリズムはいつも通り妄想で。

これで640x480ピクセル、1ピクセルでのサンプル数120なんですが、 パストレでこれだけすると、1時間は軽くかかってしまいます。 そろそろ最適化をということでkd-treeクラスを構築中です。フォトンの前に、ちとパストレで 検証したいネタがあるので、そのためのkd-treeですが。
パストレでもノイズを低周波化できないだろうか、ということでとりあえず実験予定です。
浅草
更新日時 2004/05/18
内容 時間が出来たので散歩がてら浅草に行って来ました。
上野駅から浅草までずっと歩いて「古風なところないかぁ」ということで ぶらぶらしていたのですが、近代的なビルばっかり。 が、雷門に近づくにしたがって江戸ライクになってきてました。 雷門は初めて直に見たのですが、雷門をくぐった後の出店の通り〜神社までの雰囲気が いい感じでした。
雷門の大提灯って松下幸之助さんが寄贈したものだったんですね。これも初めて知ったり。 ネットで調べると、焼けたりして空白の時代が結構あったらしい。
門は3つあるのですが(雷門・宝蔵門・二天門)、大提灯はさることながら仁王がかっこよかったです。 NHKのプロジェクトXでもちょうど仁王の話だったのですが、すごい造形美っすねぇ。
・・・が、雷門の風神雷神に気が付きませんでした(^_^;;。ずっと提灯眺めていて気づかなかったっす。 途中で雨が降ってきたので引き返したのですが、また機会があれば見に行こうかな。
ほんと、オフィス街の中の一角といった感じでした。 やはり観光地といった感じで、学生の修学旅行(?)・外国の方・年輩の方が多かったです。 ただ、その中で明らかに「この近辺に住んでいます・この近辺のオフィスで仕事してます」という方が 足早に通り過ぎるのを見たりすると、ちと滑稽でありますね。
拡散光の追跡
更新日時 2004/05/17
内容 パストレにて、もう一度光の計算を見直しました。

ドラゴンのモデルは「http://www.3dcafe.com/asp/freestuff.asp」の「3D MODELS」より拝借しています。 3DアトリエでDXF形式で吐き出して、オリジナルのレンダラ「SRender」に渡しています。
パストレの場合は、拡散反射の面の場合も再帰的にレイを反射させてたどるわけですが、このときの色の合成がよくわからん、 ということでアルゴリズムをでっち上げてみました。
以下のようにレイが4回の反射(拡散反射・鏡面反射などの区別は不要です)を行った後にシーンから抜ける、 という場合を考えます。

このときの個々の交点位置(と面の法線)・光源・視点を元に、個々の放射輝度(色)を計算します。 それをC[0]/C[1]/C[2]/C[3]/C[4]とします。C[4]はオブジェクトにぶつかることはないので背景色とします。
1レイ分の色情報数をMaxCou(=5)とすると、
  col.red = col.green = col.blue = 0.0f;
  for(i = 0; i < MaxCou; i++) {
    fDat = (float)i / MaxCou;
    fDat = 1.0 - fDat * fDat;
    col += C[i] * fDat;
  }
な感じで求めたcolが、レイがたどったピクセルでの色としています。
で、何をしているのかというと、C[0]はそのまま採用しC[1]/C[2]に行くにしたがって 徐々に色の影響がでないようにしています。つまり、光の減衰を表現しているわけです。

  col = Σ(C[i] * (1.0 - (i/MaxCou)^2))

のような感じですね。
で、全反射・透過・屈折の場合でも、実はレイが曲がるだけで計算は上記のもので 含めてしまうことができます。よってレイトレよりもシンプルになります。
これは「ロシアンルーレット」という確率のマジックなのですが、それはまた別の機会にでも。
ただ、これは「だいたいこんな感じだろう」という妄想で考えてますので、 実際はきっちりとした計算式があると思われます。
わざと迷ってみる
更新日時 2004/05/15
内容 息抜きをしたいときはぶらっと散歩に行くのですが、ちょっとした 楽しみを見つけようということで変わった散歩をしたりします。まぁ、一人遊びです。
とりあえず、いろいろ縦横無尽に歩いて「迷った」状態にします。 東京なら、歩けば駅にぶち当たりますので怖くはないです(^_^;;。 さて、そこから地名や建物を見て「あれ、どっかで見た道だな?」とか 記憶をたどりながら帰るわけです(ただし、来た道と同じ道はたどらない)。 きっちりと、「分かる場所」までたどり着いたなら勝ちで、元来た道を引き返す・またはギブアップして 電車に乗ったら負けです。
なんて感じで散歩してみると、だた歩いているだけだといろいろ気づかなかったことに 気づいたり観察力がついたりでいいですよ。
案外東京でも古風なところがあるな、とかここは金持ちの通りだな、とか・・・。 一度おためしあれ。ただし、本当に迷子にならない程度に(^_^;;

さて、レンダラのほうですがどうも拡散反射時の輝度の累積が間違ってるっぽい。 よくわからんので、現在は拡散反射時は再帰で求まった色を加算していってます。
まぁ、それらしいのでいいとしよう、ということで本日の画像です。レイトレと比較してみました。

わずかにコースティクスが出ているのも確認できるかと思います。 Shade7のパストレと画像比較をしたのですが、全然絵柄が違いますね。計算間違いだろうか・・・
それにしても、最適化していないからか描画速度が遅いです。今はShadeとほぼ同等くらいの速度かな。
速度的に行き詰まってる状態ですので(かといって他に画期的な解決策も見あたらないので)、 フォトンマップにも手を出してみようかなと思います。
フォトンマップ本のシーンを再現したかったのですが、面光源対応できてなかったので確認できず。 実装はできそうな気がするので、レイトレ・パストレでの面光源も実装しておこうと思います。
極座標からデカルト座標へ変換
更新日時 2004/05/14
内容 引き続きパストレですが、先日のところで極座標計算でミスがあったため修正です。

拡散反射するときに、面の法線を中心に半球上にベクトルをランダムに飛ばすわけですが、

以前は、(θ,φ) = (0.5 * π * r1 , 2.0 * π * r2)
としていたわけです。
Jensen氏のフォトンマップ本では、(θ,φ) = (acos(sqrt(r1)) , 2.0 * π * r2)です。
r1とr2は、0.0から1.0の間のランダムな実数。
同じ意味じゃないかと思ったのですが、レンダリング結果を見るかぎりはどうも違うらしい。 ということで、従うことにします(^_^;;
このときのデカルト座標系(一般的な(x, y, z)の座標系)に変換する方法ですが、

X = sinθcosφ
Y = sinθsinφ
Z = cosθ

となります(上軸をZとする)。これを正規化して単位ベクトル化しておきます。 ただ、これだけでは(0, 0, 1)を法線方向としたときの座標系なので本来のベクトルNに沿った座標値(ワールド座標値)に変換する必要があります。
法線をN(n.x, n.y ,n.z)とします。
ここで、この法線を出している接平面より2点取り出し(これは面の頂点0-1でいいです)差を取ってベクトル化して正規化します。これをベクトルbx(bx.x, bx.y, bx.z)とします。
そして、Nとbxの外積を取り、これをby(by.x, by.y, by.z)とします。これも正規化します。
ベクトルbxとbyは、法線Nで表すことのできる接平面の方向ベクトルとなり、bx・by・Nは、それぞれが正規直交であるといえます。
後は、はじめに求めた(X, Y, Z)をこの直交を構成するベクトルで構成される行列で変換すると、対象となるベクトルが求まります。

X' = [bx.x by.x n.x] X
Y' = [bx.y by.y n.y] Y
Z' = [bx.z by.z n.z] Z
  ↓
X' = bx.x * X + by.x * Y + n.x * Z
Y' = bx.y * X + by.y * Y + n.y * Z
Z' = bx.z * X + by.z * Y + n.z * Z

このときの(X', Y', Z')が拡散反射後の方向ベクトルとなります。
再帰的に このベクトルを使って次のレイを追跡すればよい、ということになります。
なお、拡散反射時でも交点での輝度(色)を累積していくことにより、間接光の影響を表現します。 なお、鏡面反射時・屈折時は普通のレイトレと同じ処理でOKです。
拡散反射でいかに間接光を表現するか、というのがGIの醍醐味でありますね。
「ランダムで拡散反射」という部分を繰り返して、なおかつ1ピクセル内での サンプリングを繰り返す。最終的なピクセル色決定時に サンプリング結果を平均する、これによりモンテカルロの確率的な意味合いがあるんすねぇ。
確率に関してはよくわかってなかったりしますが、面白いなぁ。
パストレーシング実装
更新日時 2004/05/13
内容 ひさびさに3Dの話題を。オリジナルのレンダラ(SRender)にパストレース機能を追加しました。
以下、光源無しで周りの「白」を反映している状態です。

ということで、ようやくGI分野に突入です。
速度的にはまだまだ最適化の余地有りなのですが、意外にもレイトレレンダラにパストレ実装部をかぶせるだけで 対応できました。と、レイキャスト部とは完全に分離して管理できますね。
で、気づいた点として・・・
  • レイの追跡に関して
    GIの場合、1ピクセル内のとある一点からレイを飛ばして「反射しない物体にぶつかっても(拡散)反射を繰り返す」 わけですが、あくまでも1レイとして反射させて分岐させない(反射・屈折時は除く)。
    本来でしたら、拡散反射の面にぶつかったら そこより複数のレイを飛ばしてサンプリング、と したいところですが、ねずみ算になり速度の問題もあり現実的でありません。
    また、そうしなくても統計的には十分ってことでしょうね。これ、勘違いしていました。

  • アンチエイリアス処理に関して
    単純なパストレの場合は、特に考慮する必要なし。というのも、1ピクセル内の細かい部分で レイを飛ばして「サンプリング」しないと、精度を保てないため。上記では1ピクセルを描画するのに120のレイを 飛ばしています。
    ただ、速度を求めるとなると何かしら「はしょる」ことになり、アンチ処理も考えないといけなくなるかもしれません。

  • 天球(半球)計算はいるのか
    スカイライト(といったら聞こえがいいでしょうか)の計算処理を入れないと、 環境光としての間接光は表現できないと思っていたのですが、これも勘違いだったようです。
    レイを拡散反射してサンプリングすることにより、自動的に計算が行われて影も生成されます(「統計的に」といった感じでしょうか。勝手に出来てます)。 よって、間接光の処理時は特別な天球計算は不要です(ただ単に、拡散反射(ランダム入れる)でレイを曲げて再帰させるだけ)。

  • セレクティブレイトレース
    速度アップ機能としてほぼ、無効ですね(^_^;;
    カットしたところで、あまり速度的なデメリットにはならないです。
なんだかんだで計算時間がかかりますね。 やはり、全体で圧倒的にしめる部分が「レイをたどるときのポリゴンとの交差計算」です。
レイトレよりもさらに敏著ですので、この部分のパフォーマンスが全体に大きく左右しています。
ですが、プログラムとして触っていると最適化できる点はいくつも見えてきました。 これは実際GIレンダラを書いてみなければ見えなかった部分ですが。
ルックアップテーブルを作ったほうがいい部分、キャッシュできる部分、などなどありますねぇ。
それと・・・数学の知識の無さを痛感しました(^_^;;。 極座標からデカルト座標の変換方法が分からず、シクハクしてました(苦笑)
その他、パストレ恒例の「ノイズ」ですが、フォトンとは違う方向性で緩和できないかなぁと思ってます。
Wiki
更新日時 2004/05/06
内容 Web上の情報サイトの自動作成・更新の仕組みとして「Wiki」というのがあります。
ちょっとこれをあさってみました。
結城浩さんの「YukiWiki」(http://www.hyuki.com/yukiwiki/)を動かしてみましたが、 さくっと動いてさくっと使えますねぇ。
「Wiki」とは何かというと、平たく言うとHTMLを触らずに しかもWebブラウザ上の操作でページを作ってしまおう、といったもの(プログラム)です。いろいろ派生がありますが、 YukiWikiはPerlで作成されたCGIプログラムです。
Weblogとの違いは、みんなで寄ってたかってページを更新できる(誰でもが更新できる) といった部分でしょうか。「ページ」として情報を持ちますので、特に日記のような形に こだわる必要もありません。グループウェアとしても利用できますね。
この手の拡張版のようなものをただいま作成していたりしますが、 記述ルールはWiki互換にしようかなぁ。 結構気に入ってしまいました。
その他YukiWikiにほしいというか、この手のツールとしてほしい機能としては、 ページの階層管理、画像のアップロードと表示、ファイルのアップロードとダウンロード、 トップメニューを常に表示、といったところでしょうか(別のWikiではすでに対応できているのもありますが)。 後、情報量が多くなってきた場合に向けてのデータベース対応もほしいところです(こうなると出てくる問題が、 システムが「複雑化する」ことではあります)。
これは、こちら側でも展開していきたいですね。
MegaDemo
更新日時 2004/05/04
内容 2chプログラム板より。
「MegaDemo」とは、元々の意味としてフロッピー1枚(約1MB)内に収まるような実行ファイルサイズで すごいプログラムを魅せようというジャンル(?)なんですが、今でもまだまだ健在なようです。
今は、ハードウェアアクセラを使う方向でシフトしているようですが。
ここに、メガデモがいろいろ紹介されています。
http://www.scene.org/

で、「Zoom3」というデモ(Doom3のパロディかな)。
ftp://ftp.jp.scene.org/pub/scene/parties/2003/assembly03/in64/zoom3_v1_02_final.zip

技術解説は以下。
http://and.intercon.ru/zoom3_idp.pdf

なんと、ファイルサイズが64KB。これで、グリングリン動きます(要:DirectX9)。
影生成はDoom3と同じ、ステンシルを使ったシャドウボリュームみたいですね。
それにしても、このファイルサイズに抑えるということがスゲーです。

これは、過去に話題になっていたのですが「Heaven Seven」というデモがあります。
http://www.demoscene.hu/~picard/h7/

これは有名なリアルタイムレイトレーシングを取り入れたものですが(というよりも、それの先駆者かな)、 理論的にはレイを飛ばすときに4ピクセルごとにスキップして走査し、 近接しているピクセルと同じポリゴン(ここでは球)に当たる場合はその間の交差判定をはしょる(決め打ちする)、 という感じの方法を使ってます。アンチエイリアスの手法を交差判定で取り入れた、といった感じでしょうか。
大きな走査から小さな探索、といった感じに再帰的に処理を行います。
アルゴリズムもご本家で紹介されてますね。

http://www.demoscene.hu/~picard/h7/subsample/subsample.html

これ、レンダラーのプレビューなどで使えないかなぁ(荒くなるでしょうけど)。
なにせ、触発される・・・というより神の領域入ってますなぁ。
「Heaven Seven」も、64KB強ほどのファイルサイズです(Direct3Dは使わず)。 うひょ〜〜・・・
このレベルのを10代〜20代前半の方が作るんですから、クールとしかいいようがないですわ(^_^;;
wxWidgets
更新日時 2004/05/03
内容 マルチプラットフォームなGUIライブラリ「wxWidgets」をいじってみました。 これは、過去に「wxWindows」と呼ばれていたものです。

http://www.wxwindows.org

触ってみた感じ、結構使えそうです。プログラムスタイルとしてはMFCのようにクラスをオーバラップしていく形になります。
対応は、Windows / UNIX(GTK+/Motif) / Mac(OS 9/OS X) / OS 2などで、一通りのOSで使えますねぇ。

以下、WindowsのVC++での使い方です。
上記サイトでダウンロードしてきたものはソースのみでライブラリなどはコンパイルする必要があります。
VC++などで「jpeg.lib/png.lib/regex.lib/tiff.lib/wxmsw.lib/zlib.lib」のライブラリを作成します。 (デバッグ版では、「jpegd.lib」のようにファイル名末尾に「d」が付いたものが生成されます)
これは、「/src」ディレクトリ内のmakefileもしくは「wxWindows.dsw」にて作成。普通のプロジェクトでのライブラリビルドになります。
参照するinclude/libのディレクトリ指定は以下の通り。
メニューの[ツール]-[オプション]の[VC++ディレクトリ]で指定しましょう。

   include : 「wxWidgetsインストール先\contrib\include」
   include : 「wxWidgetsインストール先\include」
   lib     : 「wxWidgetsインストール先\contrib\lib」
   lib     : 「wxWidgetsインストール先\lib」
なお、ビルド後のライブラリは「/lib」ディレクトリ内に配置されます。
さて、wxWidgetsを使用したアプリを作成する場合は、 追加で参照されるincludeディレクトリとして以下が必要です。

   wxWidgetsインストール先\lib\msw
lib内にincludeファイルが展開されています。デバッグ版でアプリをビルドする場合は参照先としては「wxWidgetsインストール先\lib\mswd」の追加が必要となります。
これは、「setup.h」を参照するためです。

また、プリプロセッサの定義は以下の通り。

   デバッグ時:
   _DEBUG;WIN32;_WINDOWS;WINVER=0x400;_MT;
   wxUSE_GUI=1;__WXDEBUG__;WXDEBUG=1

   リリース時:
   NDEBUG;WIN32;_WINDOWS;WINVER=0x400;_MT;
   wxUSE_GUI=1;WXDEBUG=0
コード生成時のランタイムライブラリとして「マルチスレッド DLL(/Md デバッグ時は/MDd)」 とする点に注意してください。ランタイムの指定としてはDLLとなります(生成されるファイルはEXEですが)。

後は、リンク時のライブラリとして「kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib comctl32.lib uuid.lib rpcrt4.lib wsock32.lib zlib.lib regex.lib png.lib jpeg.lib tiff.lib wxmsw.lib」 を指定します。wxWidgets関連のものは、デバッグ版でビルドするときは、libの名前の後ろに「d」をつけたのを指定します。
後は、適当にソースを書いてビルドするとexeが生成されます。
サンプルソース・プロジェクトは、80個強ありますので、いじりながらいろいろ理解できそうです。
サンプルソースとして長いものが多いのですが、「Hello World」レベルのなら90行くらいでおさまります。
といっても、雛形的な表記が大半ですので基本を押さえることができれば後は惰性でなんとかなりそうな感じです。
ソースの記述については機会があるときにでも。結構さわり甲斐がありますねぇ。

私はあまりライブラリとかを使うよりもAPI直たたきのほうが安心できる性格なのですが、 さすがにこの状態では「ライブラリを作ることが目的」になってしまって、先に進まないジレンマもありますので(^_^;;。 完成したライブラリがあれば、今後は有効に取り入れていこうかと。 先人の知恵バンザイ!!
KOKIA
更新日時 2004/05/01
内容 渋谷に行ってKOKIAの「song bird」を購入。
この方の歌は、CMやドラマの主題歌などで最近ちらほら聞きますね。 でも、小さめなCD屋では置いてないところが多かったりします。知名度は低いのかな。 澄んだ声で透き通っている感じが好きですねぇ。落ち着きたい人は聞いてみるのがいいかと。
その足で、月島に行って「もんじゃ焼き」食べてきました。 ひさびさの休日ということでSawaさんと。
それよりも、見渡す限り「もんじゃ」でびっくりでしたが(^_^;;
とりあえず上戸彩と中村玉緒のサインのあったもんじゃ焼きの店につっこみました。 なかなかうまかったです。
ちょっとしたプチ旅でしたが、月島はレトロな感じがしていいですね。
また、ゴールデンウィーク中にでも旅に出てみようかな。