はいよ。
去年はなんかアレしててアレでした。いや、わからんな。
なんか色々あって年末までに簡単なゲーム作るぜっ、ということでやってたんだが10日くらいでほぼ何も無いところから作れるわけもなく諦めた。
まー、いいんだけどね。
今年は20日に引っ越すんでそれまで忙しくていろいろ出来んかもなー。
年末年始は暇だったんでシェーダをなんとかしようと。
前から密かに考えていた計画にRubyでシェーダを書けるようにする、というのがあったんで具体的に考えてみたんだが。
う、うーん、今のところ無理っぽい…。
考えてた方法は、rubyでそのまま実行して実行した結果シェーダになるっての。
shader = RikoShader.new projection_matrix = shader.uniform(:projection_matrix, :float4x4) view_matrix = shader.uniform(:view_matrix, :float4x4) world_matrix = shader.uniform(:world_matrix, :float4x4) vertex = shader.attribute(:vertex, :float4) shader.vertex_shader do |output| output[:position] = projection_matrix * view_matrix * world_matrix * vertex end
とか、こんな感じで。これを実行するとGLSLなりCgなり下手するとVertexProgramなりにコンパイルされるとかいう寸法。
で、まあ、この単純なコードがコンパイル出来ないのかというと、これは出来るんだよな。
かなーり面倒だけど、入力から出力に単純に流れるだけのコードってのは特に苦労なくできる。
output[:vertex]に入るのはuniformやattributeが絡むならその式をなんとか記録しときゃいいだけだし、絡まないなら定数にすりゃいいしね。
でも問題はDynamicBranchingだね。つか動的分岐、というか単純に分岐とかループか。
いや、まあ、つまりifか。
問題はifはオーバーロードできないってことだよな。
例えば
if nanika.w!=1.0 then nanika /= nanika.w end
とか適当なコードがあった場合、これをシェーダ、GLSLとかに変換するなら、
if (nanika.w!=1.0) nanika /= nanika.w;
になって欲しいわけだ。が。
実際にはifの条件部分はコンパイル時に評価されちゃって、しかも評価される側からしてみればifによって評価されてんのかどうかなんて知る由も無い。
なので動的な分岐が出来ないってのよね。
これがSmalltalkなんかだとifTrueとかに反応してやりゃいいだけなんだが、Rubyではどうしようも無いからなぁ。
ifは諦めてbranchとか適当な名前にしてブロックを受けるようにしようかよも考えたが、どうにもダサい。やっぱりifはifって書きたいよ。あとelseが書けないとか。
まあ結局やるんだったらripperとかでパースしてやるしかないのかもなぁとな。
でもそれだと普通の(CPUで実行する)コードの中にシェーダ混ぜたり出来ないしねぇ。文字列として入れるなら別に今のままでも良いし。
そんなわけで今回は諦めました。Sh勉強して出直してきます。
と思ったらShはシェーダのコード、マクロで文字列にしてんじゃん! だーまーさーれーたー。
むむむ…。まあなんにせよ、完全に諦めたわけではないので勉強して出直します。
でもGLSLは非常にダサいと思います!
Cg使えばいいんだが、やっぱりランタイムが必要になるのが気にくわん。PPCのFreeBSDで動かしたいとか奇特な方が居たら困るだろ? 困らないって? 困れよ。
そこでGLSLを何重にもラップしたようなRikoShaderを作ることに。
Cgを参考に作ってたらCgっぽく書けるようにマクロとか追加したGLSLになったわけだが。
こんな感じ。
shader = RikoShader.new shader.uniform(:projection_matrix, :float4x4) shader.uniform(:view_matrix, :float4x4) shader.uniform(:world_matrix, :float4x4) shader.attribute(:vertex, :vertex) shader.varying(:position, :position) shader.shader = <<EOS rkVarying rkVertexMain(rkAttribute IN, rkUniform UNI) { rkVarying OUT; OUT.position = UNI.projection_matrix * UNI.view_matrix * UNI.world_matrix * IN.vertex; return OUT; } EOS shader.compile
とかこんなん。
まあこれだけだと全く便利でもなんでもない…というほどでもないんだが、全然嬉しくなくてCgでいいやん、ということになるんでもうちょい考える。
attributeになんかライティングとか指定しておくと計算済みの値が入ってるとかね。とかねじゃなくて考えてるわけだが。
あー、だーまーさーれーたー。
1.4 pluginのサイトをずっと見てて、更新されないなぁと思ってたんだが。
SourceForgeの方見たらちゃんと更新されててスキンアニメーション書き出せるようになってるじゃん!
うーん、読み込んでいろいろやりたいが、シェーダの方もやりたいねぇ。
そういやSmalltalkとか言ってて思い出したんだが、Visual Palmtalkってのが出てた。
以前俺も使ってたPocketSmalltalkがもうメンテされてなかったんで、それを元に強化したのを作った人がいるってわけだ。
まだいじってないのでPocketSmalltalkと何が違うのかは正確には把握してないんだが、なんとFormエディタを搭載している。
コードの編集は楽だったんだがリソースの編集が大変なPSTの欠点が大幅に改善されたことになるな。まあ日本語対応は期待できないが、それはいつものことだ…。
あとDatabaseのレコード編集機能が付いてる?
PSTでもDBアクセス用のクラスはあったけど、バイナリへのパックアンパックは自分で書かなきゃならなくて非常に面倒だったけど、それ専用のエディタが付いたらしい。すげー便利そう。
デバッガもついたらしいんだが、どうやってデバッグするんだかは謎。実機と通信してデバッグ出来るなら楽だが。あ、エミュレータと通信かな。まあそれでも楽だが。
さらにコールバックを要求するシステムAPIにも対応してるらしい。でもこれは前からあったっけ? 多分前は無かった気がする。あとOS5 better supportってことは、以前は呼べなかったOS5用のAPIにも対応してるんだろうな。
久しぶりにPalm用のアプリも書きたいなー。WillcomでTreoとか出れば速攻買うんだが。