hgdrawの高速化について
撃 2013/4/27(Sat) 21:59:29|NO.53663
hgimg3を利用したプログラムが一応完成しまして、現在高速化に取り組んでおります。
当初1フレームあたり30msかかっていたものを切り詰めて24msまで落としたのですが、
そのうち13msをhgdrawが占めています。
(処理は、簡単な形状のxモデルを2300個くらい描画します。)
hgdrawを高速化する手段は無いでしょうか。
調べていた途中に見つけた文を丸々引用してしまいますが、
「hgsetreq SYSREQ_DEFTIMER,1
って入れるとHGIMG3の負荷はなくなるみたいです。
あとは、レイヤードウィンドウを作るための負荷がありそう。
例えば、LayeredWindowAlphaのソースを見ると分かるのですが
毎回32ビットのDIBを作成しているのです。
800*600*4/(1024^2)=1.8
つまり、更新するたびに1.8MBのメモリの初期化をしています。
メモリの初期化は結構負荷が大きい処理なので、
最初の1度だけ32bitDIBの準備をするように改造すれば、負荷は少しは下がると思います。」
のレイヤード云々〜以後の処理を行う手法などお聞きしたいです。
(hgsetreqは試してみたらむしろ遅くなりました)
暇人 2013/4/30(Tue) 03:05:45|NO.53709
どんな物を作ってるか分からなければ処理軽減の方法は分からない
方法を提案されても使えない可能性が高い
確実なのはオブジェクトの数を減らすぐらいしかない
カメラZ軸の範囲外とスクリーン座標のY座標が画面外なら非表示にするようにしてみたけど
2000個ともなると非表示に変える処理で数msかかるので半分以下に減らせても効果が少ない・・・
#include "hgimg3.as"
#include "objrotfv.hsp"
screen 0,640,480,0
cls 4
hgsetreq SYSREQ_MAXOBJ ,3000
hgini
setcolor 255
addbox mdid,5,5 ; BOXモデルを作成
regobj Center_objid,mdid ; BOXモデルをオブジェクトとして登録
addxfile xmdid,dir_exe+"\\sample\\hgimg3\\font_a.x" ; モデルを読み込む
modelorder xmdid,HGMODEL_ROTORDER_ZYX //通常モデルと同じ回転順序にする
DOTS=2300
repeat DOTS
regobj mychr(cnt),xmdid ;,OBJ_SORT;OBJ_LATE;OBJ_HIDE
setpos mychr(cnt),500.0-0.1*rnd(10000),500.0-0.1*rnd(10000),500.0-0.1*rnd(10000)
getpos mychr(cnt),xx,yy,zz
fvset vv,xx,-yy,zz //y軸反転してセット
fvface vv,0.0,0.0,0.0
selang mychr(cnt) //任意軸の回転させたいオブジェクト選択(objrotfvを使う準備)
fvset axis,0.0,0.0,0.0 //回転前の角度(obj初期値は全て0なので0設定)
fvdir axis,1.0 ,0.0 ,0.0 //x軸(euler2matrixの代わり)
objrotfv axis,vv //axis軸をvv分回転
fvset axis,0.0,0.0,0.0
fvdir axis,0.0 ,1.0 ,0.0 //y軸
objrotfv axis,vv(1)
fvset axis,0.0,0.0,0.0
fvdir axis,0 ,0 ,1 //z軸
objrotfv axis,vv(2)
loop
*main
hggettime tim,0
if HIDE_f=0{//非表示化処理オン[Enter]
HIDE=0
repeat DOTS
getpos mychr(cnt),x,y,z
hgcnvaxis xx,yy,zz,x,y,z,0
if zz<0.90 or zz>1.0 or yy>960 or yy<-480 {setobjmode mychr(cnt),OBJ_HIDE,0:HIDE++}else{setobjmode mychr(cnt),OBJ_HIDE,1}
loop
}else{//非表示化処理オフ[Enter]
if HIDE {
repeat DOTS
setobjmode mychr(cnt),OBJ_HIDE,1
loop
HIDE=0
}
}
hgdraw ; 描画処理
hggettime tim2,0
// hgdrawと非表示化処理の処理時間 非表示にしたオブジェクト数
title ""+(tim2-tim)+"ms "+HIDE
hgsync 16 ; 時間待ち
stick k,127-32
if k&128 : goto *owari ; [ESC]で終了
fvset cfv,0.0, 0.0, 0.0
if k&2 : cfv+0.01
if k&8 : cfv-0.01
if k&1 : cfv(1)-0.01
if k&4 : cfv(1)+0.01
if k&16 : cfv(2)+0.05
if k&64 : cfv(2)-0.05
if k&32 : HIDE_f^1 //[Enter]非表示化処理オンオフ切換
getang HGOJB_CAMERA,crx,cry,crz //現在のカメラ角度(これにcfvを各軸に加算)
selcang //カメラ選択(objrotfvを使う準備)
fvset axis,crx,-cry,crz //回転前の角度
fvdir axis,1.0 ,0.0 ,0.0 //x軸
objrotfv axis,cfv //axis軸をcfv分回転
fvset axis,crx,-cry,crz
fvdir axis,0.0 ,1.0 ,0.0 //y軸
objrotfv axis,cfv(1)
fvset axis,crx,-cry,crz
fvdir axis,0 ,0 ,1 //z軸
objrotfv axis,cfv(2)
getang HGOJB_CAMERA,crx,cry,crz
fvset vv,crx,-cry,crz
fvdir vv,0.0,0.0,100.0
selcpos
objsetfv vv
goto *main
*owari
end
自分の環境だと非表示オンで5〜6
非表示オフで7〜8
作ってるものによってはもっと効果出せたり(毎フレーム非表示化処理しなくて良いとか)
使えなかったりするだろう・・・
後半の話はウィンドウを透明、半透明にしてデスクトップマスコットを作る時の話だろう
>(hgsetreqは試してみたらむしろ遅くなりました)
昔はSYSREQ_DEFTIMER,0の設定で通常時(描画負荷関係なく)の負荷が大きかった時があった
なたで 2013/4/30(Tue) 23:48:19|NO.53729
撃さん。こんにちは。
その文章を書いたのは私です。
それは、暇人さんが言うようにレイヤードウィンドウを
デスクトップマスコットを作るときの話です。
(当時、レイヤードウィンドウを作る
モジュールを公開していたのでサイト上に質問がありました。)
「hgsetreq SYSREQ_DEFTIMER,1」っていうのは
以前、デフォルトの「hgsetreq SYSREQ_DEFTIMER, 0」の場合、
hgsyncの時間待ちモードをHGIMG3に任せるため
CPU使用率が100%になっていたためのアドバイスでした。
(正確な時間が必要なゲームならともかく、
デスクトップマスコットなので、CPU使用率を下げたかったためです。)
今はならないようですね。
撃 2013/5/1(Wed) 23:33:34|NO.53757
お二方ご回答ありがとうございました。
抜粋を読んだ自分の勘違いだったようですね。失礼致しました。
さて、何を作っているかはちょっと秘密なのですが
オブジェクトは基本、画面外に出たり隠れたりする事は少なく、
位置は毎フレーム変動するため描画オフなどの手法は難しいです。
個数も2300個は最低ラインであり実用範囲で1万個オーバーもします。
アルゴリズムの見直しや不要な計算を減らす方向での高速化は、
それなりに手を打った状態でして、各部の負荷の計測をしていた時に
hgdrawの1行がものすごく処理を喰っていました。
たった1行なので手の施しようも無く、何か裏技的な設定とか、
代替描画ルーチンなどあれば高速化が捗るのになと思い質問をさせていただきました。