mieki256's diary



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。

ソース :

とりあえず以下のようなソースになった。

_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 日分です。

過去ログ表示

Prev - 2023/11 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project