なでしこの実行速度はCPUの性能・分解能に非常に大きく依存します。
また、なでしこの実行はシングルスレッドでしか行われないため、マルチスレッドCPUの恩恵を受けられません。
さらに、最近のIntel Core iシリーズのCPUでは低負荷時クロックダウンでの運用がされますが、
なでしこで60FPSゲームを実行した際にクロックアップが行われず処理落ち(30fps程度まで落ちる)する現象が確認されています。
具体的な描画速度の向上方法は、スレッドを分けることであると思います。
例えば弾幕系であれば、まずダブルバッファリング同様、裏画面を複数(4つぐらい?)用意し、MAPや背景、敵&自機、弾&自機弾・・・の様にバラバラに描画したあと、
最後に一枚に描画する方法です。
この場合、描画面積の多い背景画像等をひとつのスレッドに割り当て、
同様に計算から描画まで全ての弾をひとつのスレッドに割り当てて実行することになります。
つまり、
- 初期化
- 入力系
- 座標系の計算(ここでLUAを用いてもよいが、オブジェクト指向のデータが渡せない問題有り)
- 描画系 (ここまでスレッドに分割する)
- 待機時間 &スレッドの終了と回収
という流れになります。
問題はLuaの呼び出しに少なからず時間が掛かるという点です。
また、なでしこ側の変数はLUAからあえて参照してLUA側で変数を毎回用意する必要があるため、実はなでしこのオブジェクト指向とかなり相性が悪いです。
GLシリーズは、基本的にオブジェクト指向が前提なため、ここの連携が大きな課題となります。
60FPSを目標とするゲームでは、実際のところ初期化と描画待機時間(プロシージャ不応答による描画スキップ回避)で2~3msec損しています。
そのため実際は1フレームあたりの余裕は14msec程度しか存在せず、1000を超えるオブジェクトの管理においては1つの要素の計算あたり14μsec程度しか掛けられません。
加えてGLの回転用の演算などは一回で6μsecあたり必要とし、さらに透過のために転送処理を2度行う必要があります。
なでしこの演算速度はCPUに寄りにけりですが、使い物にならないほど遅いというわけではなく、必要な速度は出ていると思います。
工夫次第でなんとかなるところはいくらかあると思いますし、絶望的な程余裕がないかといわれればそうでもありません。
ただ留意すべきなのは、イマドキのゲームを作るには厳しい ということです。
なでしこで作れるゲームというのは良くてGBAレベルです。
解像度も高くないし、表現力もドット絵に頼ることが多いわけです。
GLシリーズというのはそういうプログラミングよりもゲームを作りたい人向けのツールなので、どうしても複雑化することができません。
従って、スレッド化等は可能な限りユーザーが意識する必要なく作り込む必要があります。
ということで、今後スレッド化について長く調べていこうと思います。
何かアイディアや情報があれば提供お願いします。
・おまけ
Luaでベジェ曲線の点を出す関数を即席で作ってみた。
実際に1000回ほど試して比べてみると差が結構出てしまう。
結果はLua惨敗、最適化等は行なっていないため、他にもっと良いやり方があるとは思われるが、この時点では実用的ではない。
//Lua版
●LUA_Bezier(p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y,t,{参照渡し}xx,{参照渡し}yy)
xとは整数
yとは整数
`
t=nako_get("t")
p1x=nako_get("p1x")
p1y=nako_get("p1y")
p2x=nako_get("p2x")
p2y=nako_get("p2y")
p3x=nako_get("p3x")
p3y=nako_get("p3y")
p4x=nako_get("p4x")
p4y=nako_get("p4y")
lx=p1x+(p2x-p1x)*t
ly=p1y+(p2y-p1y)*t
mx=p2x+(p3x-p2x)*t
my=p2y+(p3y-p2y)*t
nx=p3x+(p4x-p3x)*t
ny=p3y+(p4y-p3y)*t
sx = lx + (mx - lx)*t
sy = ly + (my - ly)*t
tx = mx + (nx - mx)*t
ty = my + (ny - my)*t
x = sx + (tx - sx)*t
y = sy + (ty - sy)*t
nako_set("x",x)
nako_set("y",y)
`をLUAする
xx=x
yy=y
//ベジェ曲線演算関数
●Bezier({配列}p1,{配列}p2,{配列}p3,{配列}p4,t,{参照渡し}x,{参照渡し}y)
lxとは実数;lyとは実数;mxとは実数;myとは実数;nxとは実数;nyとは実数;sxとは実数;syとは実数;txとは実数;tyとは実数;
lx=p1[0]+(p2[0]-p1[0])*t;
ly=p1[1]+(p2[1]-p1[1])*t;
mx=p2[0]+(p3[0]-p2[0])*t;
my=p2[1]+(p3[1]-p2[1])*t;
nx=p3[0]+(p4[0]-p3[0])*t;
ny=p3[1]+(p4[1]-p3[1])*t;
sx=lx+(mx-lx)*t;
sy=ly+(my-ly)*t;
tx=mx+(nx-mx)*t;
ty=my+(ny-my)*t;
x=sx+(tx-sx)*t;
y=sy+(ty-sy)*t;
戻る