2023/11/12(日) [n年前の日記]
#1 [hsp] HGIMG3のhgcaptureについて調べてる。その2
Windows10 x64 22H2 + HSP 3.7 beta7 で、仮想画面相当に HGIMG3 で描画して、その結果をメイン表示ウインドウに持ってこれないか実験中。
たぶんできたような気がする。ただ、ちと問題はあるけれど、それについては後述。
要するに以下のような仕組みにすれば、それらしくなるのかなと。
たぶんできたような気がする。ただ、ちと問題はあるけれど、それについては後述。
要するに以下のような仕組みにすれば、それらしくなるのかなと。
- プログラム起動時に作成される初期ウインドウ(ID=0)には手を付けない。(後々スクリーンセーバを作りたいので…)
- メイン表示ウインドウ(ID=2)と、仮想画面相当にする表示ウインドウ(ID=5)を新規作成。
- HGIMG3の描画結果のコピー先として、buffer ID=6 も新規作成。この buffer は、仮想画面相当ウインドウと同じサイズにしておく。
- HGIMG3を使って、仮想画面相当の表示ウインドウに色々描画。
- hgcaptureを使って、仮想画面相当表示ウインドウから、buffer ID=6 に、描画内容をコピー。
- buffer ID=6 の内容を、メイン表示ウインドウに拡大描画。その際利用するのは、HSP標準描画機能。HGIMG3で描画はできない。HGIMG3を使って描画しようとすると、仮想画面相当の表示ウインドウ側に描かれてしまうので。
◎ ソース :
_07_hgcapture_02.hsp
使用画像は以下。
_chara.png
; hgcapture使用サンプルその2 ; 表示ウインドウを2つ新規作成して、片方を仮想画面相当、片方をメイン表示にする #include "hgimg3.as" #include "d3m.hsp" ; 以下の行をコメントアウトするとウインドウ表示になる ;#define FULLSCR #packopt name "07_hgcapture_02" ; file name #packopt type 0 ; generate ".exe" #define TEXFILE "chara.png" #pack TEXFILE #define KB_ESC 128 #define KB_LEFT $00001 #define KB_UP $00002 #define KB_RIGHT $00004 #define KB_DOWN $00008 #define KB_CURSOR (KB_LEFT | KB_UP | KB_RIGHT | KB_DOWN) framerate = 60 title "Screen 0" ; メイン表示ウインドウを確保。HSPの標準描画機能で描画していく dispid = 2 #ifdef FULLSCR ; get desktop size dispw = ginfo_dispx disph = ginfo_dispy bgscr dispid, dispw, disph, 0, 0, 0, dispw, disph #else dispw = 1280 disph = 720 screen dispid, dispw, disph, 0 title "Screen " + dispid #endif ; hgcapture用バッファを確保 tbufid = 6 vscrw = 512 vscrh = 288 buffer tbufid, vscrw, vscrh ; 仮想画面相当の表示ウインドウを確保。HGIMG3で描画していく 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 = 16 texh = 16 clscolor $4080c0 ; set clear color count = 0 x = (vscrw / 2) y = (vscrh / 2) time_start = d3timer() *mainloop repeat ; get FPS tm = d3timer() - time_start fps = d3getfps() ; ESC key to exit stick k, KB_CURSOR if k & KB_ESC : break ; move character spd = 3 if k & KB_LEFT : x -= spd if k & KB_RIGHT : x += spd if k & KB_UP : y -= spd if k & KB_DOWN : y += spd hgdraw ; draw images (HGIMG3) gmode gmode_rgb0, texw, texh pos x, y src_x = ((count / 16) \ 2) * texw src_y = 0 rot = 0.0 scale = 3 dst_w = texw * scale dst_h = texh * scale hgrotate texid, src_x, src_y, rot, dst_w, dst_h ; HGIMG3 の描画結果をキャプチャしてbuffer(ID=tbufid)にコピー ; 右端と下端に数ドット黒部分が出るのはバグらしい gsel tbufid hgcapture ; メイン表示ウインドウにHGIMG3の描画結果を描画していく gsel dispid redraw 0 ; zoom copy tbufid -> dispid (HSP標準描画機能) if 1 { gmode gmode_gdi pos 0, 0 gzoom dispw, disph, tbufid, 0, 0, vscrw, vscrh, 1 } 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 t = (1000 / framerate) - 1 if t <= 0 : t = 1 hgsync t count++ loop *mainloop_end end
使用画像は以下。
_chara.png
◎ 問題点 :
問題点としては…。処理が遅い…。そのせいか、動きもガクガクしてしまう…。
前述のソースでは違いが分からないかもしれないけれど、以下に示すような描画面積がそれなりに大きい処理の場合、明らかに遅くなる。
_07_hgcapture.hsp
_tex.png
仮想画面相当を経由させずに直接描画すれば60FPSが出る処理内容でも、仮想画面を経由させると60FPSが出なくなったりする。一旦仮想画面を経由することで、描画面積はかなり少なくなって、処理時間が短くなるのではないかと予想していたのだけど、実際には真逆の結果に ―― 速くなるどころか、むしろ遅くなる状態になってしまった。
実際に測定したわけではないから、たしかなことは言えないけれど、どうも hgcapture が遅いのではないかという気がしている。関連情報を眺めると、VRAM からメインメモリに内容をコピーしてくる関係でどうしても遅くなる、と言及されているようだし…。
前述のソースでは違いが分からないかもしれないけれど、以下に示すような描画面積がそれなりに大きい処理の場合、明らかに遅くなる。
_07_hgcapture.hsp
_tex.png
仮想画面相当を経由させずに直接描画すれば60FPSが出る処理内容でも、仮想画面を経由させると60FPSが出なくなったりする。一旦仮想画面を経由することで、描画面積はかなり少なくなって、処理時間が短くなるのではないかと予想していたのだけど、実際には真逆の結果に ―― 速くなるどころか、むしろ遅くなる状態になってしまった。
実際に測定したわけではないから、たしかなことは言えないけれど、どうも hgcapture が遅いのではないかという気がしている。関連情報を眺めると、VRAM からメインメモリに内容をコピーしてくる関係でどうしても遅くなる、と言及されているようだし…。
[ ツッコむ ]
以上です。