次世代DXRubyを考える

# まあ、素人なので色々と勘違いしていることもあるだろうが、現時点で考えていることをつらつらと。

# Window.drawのzは0以上の場合は2D、マイナスの場合には射影変換されて3D描画となる。
# いちおう右手座標系ということにしておくが、現時点ではzの符号を反転させて描画しているので内部は左手座標系。
# ポリゴンの頂点の順番が変わってしまうのでこのへんは後で考える。

# 通常描画。zは描画順として処理される。
Window.draw(0, 0, image, 10)

# 2D画像の3D空間への描画。zは3D空間でのz座標になる。
Window.draw(0, 0, image, -10)

# 3D描画。posのzは3D空間でのz座標。最後のzは描画順となる。zでは紛らわしいから表現方法は考えちゅ。
# rotとscaleは配列のかわりにnilを指定すれば行列の掛け算が省かれる。
Window.drawMesh([x, y, z], [rotx, roty, rotz], [scalex, scaley, scalez], mesh, z)

# 実際の描画順はメッシュのz(描画順)が小さいほうから順、同じならz座標でソート→2D画像描画のzが小さいほうから順。
# つまり、3D→擬似3D→2Dの順で処理される。
# zバッファを使うので重ね合わせ的には問題ない。カメラの移動は現時点ではサポートしない。将来的にはサポート予定。
# その場合はソートをもう少し考えなければならないので後で。

# 擬似3Dでは2Dと3D空間をシームレスに移動できるのを目指すので、射影変換でズームすることは無い。
# したがって、視野角をそれで調整することはできない。zのクリッピング面znで調整する。
# znを(マイナス方向に)大きくしても、draw系メソッドで指定するzは0>zという感じにする。内部でznを減算する。
# カメラを移動すると2D描画と3D描画が完全に切り離される。
# その場合、2D空間の描画はゲームの情報ウィンドウなど、2D画像の3D空間への描画はビルボードとして扱えるとよいと思う。

# ポリゴンオブジェクト。メソッド名はテキトー。
# ここで指定する座標はローカル座標系。これをメッシュに登録して、Window.drawMeshで描画する。
# ポリゴン単体での直接描画は必要性が怪しいのでサポートしない。
p = Polygon.new
p.vertex = [x1, y1, z1, x2, y2, z2, x3, y3, z3]
p.image = Image.new("gazou.png")
p.tutv = [tu1, tv1, tu2, tv2, tu3, tv3]
p.diffuse = [[a1, r1, g1, b1], [a2, r2, g2, b2], [a3, r3, g3, b3]]
# etc.何の情報を持つかでタイプが決まる。

# メッシュオブジェクト。同じタイプのポリゴンしか同時に登録できない。
m = Mesh.new([p1, p2, p3, p4, p5, p6, p7, p8])

# ファイルからでもつくれる
m = Mesh.new("mesh.x")

# こんなプログラムで3Dの絵が出てくれると大変嬉しい。
require 'dxruby'
m = Mesh.new("mesh.x")
Window.loop do
  Window.drawMesh([320, 240, -300], nil, nil, m)
end

# HLSLを文字列で渡してシェーダが使えるととても柔軟になる。
# 使える人ばっかりではないから、ありがちなシェーダプログラムはWikiにでもアップしてコピペして使ってもらえるとよい。
# FreeRGSSでやってるフラッシュ・ブレンド・グレースケール化や、バンプマッピングなんかもできれば表現力は大幅に上がるだろう。
# HLSLに渡すデータは行列・ベクトル・テクスチャの情報であり、行列とベクトルはそれ用のクラスを作って内部でD3DMATRIXなどに変換する。
# newするとコンパイルされる。コンパイラを含めるのでdxruby.soのサイズは一段とデカくなる。
sh = Shader.new(hlsl, {str1=>matrix4_4, str2=>float4, str3=>image})

# Rubyにも行列・ベクトルのライブラリはあるが、Rubyで書かれていて遅いのでDXRuby用に作る。
# Ruby上でもそれなりに高速な行列計算ができるようにしておく。
mat = Matrix.new([[1.0, 0.0, 0.0, 0.0],
                  [0.0, 1.0, 0.0, 0.0],
                  [0.0, 0.0, 1.0, 0.0],
                  [0.0, 0.0, 0.0, 1.0]])

vec = Vecter.new([0.0, 0.0, 0.0, 0.0])

# 描画
Window.drawShader(0, 0, image, sh, z)
Window.drawEx(0, 0, image, :shader = sh)

# なお、ここに書いたことは決定事項ではなく、とりあえずの叩き台。
# これをベースに考えたり作ってみたりした結果、ダメだったりもっといいことを思いついたら遠慮なく変更する。

# あ、3Dするならライトとか設定できないとあかんなあ。
Window.setLight = ???
# Lightクラスとか作らないといけない?このへんまだよくわかってない。

ということで、意見や要望や3Dに対する熱い思いがある方は何かコメントをどうそ。