2023/11/14(火) [n年前の日記]
#1 [hsp] HGIMG3のhgcaptureについて調べてる。その3
Windows10 x64 22H2 + HSP 3.7 beta7 で、仮想画面相当に HGIMG3 で描画して、その結果をメイン表示ウインドウに持ってこれないか実験中。
hgcapture を使えば、HGIMG3 で描画した結果を、HSP標準のイメージバッファに持ってくることができるわけだけど、フレームレートが安定しなくてそのあたりを試していた。hgsync で時間待ちをせずに await で時間待ちをしたら比較的安定しているように見えたのだけど…。こういう呼び方で正しいのかどうか…。
ハードウェアスペックは、CPU : AMD Ryzen 5 5600X (6C12T、3.7 - 4.6GHz)、GPU : NVIDIA GeForce GTX 1060 6GB、RAM : 16GB。
hgcapture を使えば、HGIMG3 で描画した結果を、HSP標準のイメージバッファに持ってくることができるわけだけど、フレームレートが安定しなくてそのあたりを試していた。hgsync で時間待ちをせずに await で時間待ちをしたら比較的安定しているように見えたのだけど…。こういう呼び方で正しいのかどうか…。
ハードウェアスペックは、CPU : AMD Ryzen 5 5600X (6C12T、3.7 - 4.6GHz)、GPU : NVIDIA GeForce GTX 1060 6GB、RAM : 16GB。
◎ ソース :
とりあえず以下のようなソースになった。
_07_hgcapture.hsp
使用画像は以下。
_tex.png
実行結果は以下。
ポイントとしては…。hgdraw → hgrotate で描画 → hgsync で時間待ちをした後、hgcapture を呼んで、そこからHSPの標準描画機能で各描画をして、最後に await で本来待つべき時間待ちをする、みたいな流れになっているところだろうか。色々順番を入れ替えてみたけど、この順番ならフレームレートが安定してくれたように見えた。
ただ、hgsync や await が具体的にどんな処理をしているのか、そのあたり自分は全く分かってないので…。もし分かってる人が見たら、「あ…それをやられてしまうとマズイんだけど」と眉をしかめる状態になっている可能性もあるかもしれない。あるいは他の環境で動かしたらかえってフレームレートが不安定になる可能性もあったりするかもしれない。
余談。上記のソースでは、仮想画面相当のウインドウも画面に表示しているけれど。screen 命令でウインドウを新規作成する際に、screen_hide というモード値を指定すれば、非表示のウインドウになる。実際に本番(?)の処理として書く場合は、仮想画面相当のウインドウは非表示にするだろうなと。
_07_hgcapture.hsp
; hgcapture使用サンプル #include "hgimg3.as" #include "d3m.hsp" ; 以下の行をコメントアウトするとウインドウ表示になる #define FULLSCR #packopt name "07_hgcapture" ; file name #packopt type 0 ; generate ".exe" #define TEXFILE "tex.png" #pack TEXFILE #define KB_ESC 128 framerate = 60 title "Screen 0" ; メイン表示ウインドウを確保 dispid = 2 #ifdef FULLSCR ; get desktop size dispw = ginfo_dispx disph = ginfo_dispy bgscr dispid, dispw, disph, 0, 0, 0, dispw, disph #else dispw = 1600 disph = 900 screen dispid, dispw, disph, 0 title "Screen " + dispid #endif ; hgcapture用バッファを確保 vscrw = 800 vscrh = 450 tbufid = 6 buffer tbufid, vscrw, vscrh ; 仮想画面相当の表示ウインドウを確保 vscrid = 5 ;modevalue = screen_hide modevalue = 0 screen vscrid, vscrw, vscrh, modevalue title "Screen " + vscrid hgini ; load texture texload2 TEXFILE texid = stat ; get texture ID texw = 512 texh = 512 clscolor $4080c0 ; set clear color angle = 0.0 time_start = d3timer() *mainloop repeat ; get FPS tm = d3timer() - time_start fps = d3getfps() ; ESC key to exit stick k, 0 if k & KB_ESC : break angle += 0.5 hgdraw ; draw images (HGIMG3) objmax = 96 repeat objmax r = double(vscrh) * 0.5 a = angle + (270.0 / double(objmax)) * double(cnt) x = int(r * cos(deg2rad(a))) + (vscrw / 2) y = int(r * sin(deg2rad(a))) + (vscrh / 2) d = double(cnt) / double(objmax) src_x = (idx \ 2) * texw src_y = ((idx / 2) \2) * texh idx = (cnt \ 4) rot = deg2rad(angle * 2.0 + 360.0 * d) ; scale = 1.0 - (0.75 * d) scale = 2.0 - (1.75 * d) dst_w = int(double(texw) * scale) dst_h = int(double(texh) * scale) ; draw image by celput gmode gmode_rgb0, texw, texh pos x, y hgrotate texid, src_x, src_y, rot, dst_w, dst_h loop if 0 { t = (1000 / framerate) - 1 if t <= 0 : t = 1 hgsync t } else { hgsync 12 } ; HGIMG3 の描画結果をキャプチャしてbuffer(ID=tbufid)にコピー ; 右端と下端に数ドット黒部分が出るのはバグらしい gsel tbufid ; redraw 0 hgcapture ; redraw 1 ; メイン表示ウインドウにHGIMG3の描画結果を描画していく gsel dispid redraw 0 ; tbufid から dispid に拡大描画 (HSP標準描画機能) if 1 { gmode gmode_gdi pos 0, 0 gzoom dispw, disph, tbufid, 0, 0, vscrw, vscrh, 0 } else { gmode gmode_gdi, vscrw, vscrh pos (dispw / 2), (disph / 2) grotate tbufid, 0, 0, 0.0, dispw, disph } ; draw text (HSP標準描画機能) if 1 { font "Tahoma", 20, 1, 2 objcolor 255, 255, 255 color 16, 16, 16 pos 16, 16 mes strf("[%dx%d] %d FPS", vscrw, vscrh, fps), 4 } redraw 1 await (1000 / framerate) loop *mainloop_end end
使用画像は以下。
_tex.png
実行結果は以下。
ポイントとしては…。hgdraw → hgrotate で描画 → hgsync で時間待ちをした後、hgcapture を呼んで、そこからHSPの標準描画機能で各描画をして、最後に await で本来待つべき時間待ちをする、みたいな流れになっているところだろうか。色々順番を入れ替えてみたけど、この順番ならフレームレートが安定してくれたように見えた。
ただ、hgsync や await が具体的にどんな処理をしているのか、そのあたり自分は全く分かってないので…。もし分かってる人が見たら、「あ…それをやられてしまうとマズイんだけど」と眉をしかめる状態になっている可能性もあるかもしれない。あるいは他の環境で動かしたらかえってフレームレートが不安定になる可能性もあったりするかもしれない。
余談。上記のソースでは、仮想画面相当のウインドウも画面に表示しているけれど。screen 命令でウインドウを新規作成する際に、screen_hide というモード値を指定すれば、非表示のウインドウになる。実際に本番(?)の処理として書く場合は、仮想画面相当のウインドウは非表示にするだろうなと。
[ ツッコむ ]
以上、1 日分です。