HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
1118
ham透過ウィンドウでの処理落ち?9解決


ham

リンク

2017/11/18(Sat) 16:56:01|NO.81866

透過ウィンドウを使って画面に雪を降らすものを作っています。

ちらつきを無くすためにredrawを使うとどうしても描画がスムーズにならず行き詰っております。
私の環境では滑らかに動いているのに何故か途中で画面全体(マウスカーソルを含む)が一瞬止まったりする感じで不自然です。
redrawを消すと改善するのですが、当然ちらつきが出てしまいます。

皆さんの環境ではどうなりますでしょうか?
何か分かれば何でも教えて欲しいです!


//透過ウィンドウ準備 #uselib "user32.dll" #cfunc GetWindowLongA "GetWindowLongA" int,int #func SetWindowLongA "SetWindowLongA" int,int,int #func SetLayered "SetLayeredWindowAttributes" int,int,int,int #func SetParent "SetParent" int,int #func SetWindowLong "SetWindowLongA" int,int,int;ウィンドウの透明化・半透明化・不透明化_用↓ #func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int,int,int,int #const LWA_COLORKEY 1 ;透明色を指定 #const LWA_ALPHA 2 ;アルファー値を指定 #const GWL_EXSTYLE -20 ;拡張ウィンドウスタイル #const WS_EX_LAYERED $00080000 ;透明なウィンドウ属性 #const WS_EX_TRANSPARENT $00000020 bgscr 0,ginfo(20),ginfo(21),0,0,0:gsel 0,2:title"雪" // 1,1,1 を透過色として利用 color 1,1,1:boxf //ウィンドウすり抜け SetWindowLong hwnd,-20,WS_EX_LAYERED|WS_EX_TRANSPARENT // 背景(ID 1)を 透明化 & 子ウィンドウ化 SetWindowLongA hwnd,-8,_hwnd SetWindowLongA hwnd,-20,GetWindowLongA(hwnd,-20)|0x00080000 SetLayered hwnd,0x010101,0,1 ;準備 max=55 ddim x,max:ddim y,max:ddim xx,max:ddim yy,max:dim size,max:dim a,max:randomize repeat max x(cnt)=rnd(ginfo(20)*2.5)-ginfo(20):y(cnt)=rnd(ginfo(21))*-1 size(cnt)=rnd(10)+5 xx(cnt)+rnd(5)-2 yy(cnt)=1:b=0.0:b+rnd(9)+1:b/10:b+rnd(9)+1:yy(cnt)+b loop ;メインループ *main redraw 0 repeat max a(cnt)=rnd(5) if a(cnt)=0:b=0.0:b+rnd(21)-10:b/15:xx(cnt)+b : if xx(cnt)>2.0:xx(cnt)=2.0:else:if xx(cnt)<-2.0:xx(cnt)=-2.0 if xx(cnt)=0.0:b=0.0:b+rnd(21)-10:b/15:xx(cnt)+b x(cnt)+xx(cnt):y(cnt)+yy(cnt) if y(cnt)>ginfo(21){ x(cnt)=rnd(ginfo(20)*2.5)-ginfo(20):y(cnt)=rnd(ginfo(21))*-1 if x(cnt)<-15|x(cnt)>ginfo(20)+15:y(cnt)=rnd(ginfo(21)):else:y(cnt)=-15 size(cnt)=rnd(10)+5 yy(cnt)=1:b=0.0:b+rnd(9)+1:b/10:b+rnd(9)+1:yy(cnt)+b } loop color 1,1,1 boxf color 245,245,245 repeat max circle x(cnt),y(cnt),x(cnt)+size(cnt),y(cnt)+size(cnt),1 loop await 16 redraw 1 await 0 goto*main



この記事に返信する


ham

リンク

2017/11/18(Sat) 22:52:12|NO.81868

すみません。自己解決しました。
仮想画面に描画しておいて更新が必要な部分だけgcopyすればredraw無しでもチラつきを無くせて高速になりました。



沢渡

リンク

2017/11/18(Sat) 23:07:28|NO.81869

画面全体に及ぶ処理を、秒間60回以上もやっているせいで、マシンに大きな負荷がかかっているのではないでしょうか?
私の環境でも明らかに様々な処理が重くなっていて、実際タスクマネージャーを見たら25%〜30%もCPUパワーを食っていました。

対処法としては、await 16の部分の数値をもっと大きく(たとえば10倍の160とか)にして、
その分、 y(cnt)+yy(cnt) を y(cnt)+yy(cnt)*10 などとし、雪の落下速度を上げてやれば
良いのではないでしょうか。



沢渡

リンク

2017/11/18(Sat) 23:09:19|NO.81870

おっと、すれ違いか。
解決したようなら失礼しました。



ham

リンク

2017/11/18(Sat) 23:43:13|NO.81871

沢渡 様 回答ありがとうございます。

かなり負荷掛かってますよね。
自分も60fpsがやりすぎなのかと思い30fpsで試したのですが何故か症状が変わらずでして...

一応解決しましたがまだまだ負荷が高いのが心残りではありますね。
でも、なるべく滑らかに雪を降らせたい、、もっと高速な透過方法があればいいのですが。。



ソラ

リンク

2017/11/19(Sun) 00:28:13|NO.81872

雪1つ1つを小さいウインドウにし、
ウインドウの位置を移動させる事で雪を落下させてはどうでしょう。
試していないので軽いかどうか断言はできません。



ham

リンク

2017/11/19(Sun) 08:34:25|NO.81876

ソラ 様 回答ありがとうございます。

その発想はなかったです!さっそく試して見ました。
残念ながらCPU負荷は透過しなくても60%を超えてしまいました!
でもありがとうございます。面白かったです。

https://i.imgur.com/dGC0Szu.png



Tsubame

リンク

2017/11/20(Mon) 09:50:18|NO.81878

これ恐らくですが、透過以前に全画面表示の60fpsだとredrawで更新するだけでCPUかなり使ってますね...
こちらの環境では、雪を表示するしないに関わらず、CPU使用率20%越えました。
ご参考まで。


以下、最小限で実行した場合

bgscr 0,ginfo(20),ginfo(21),0,0,0:gsel 0,2 ;メインループ *main await 16 redraw 0 redraw 1 goto*main



Tsubame

リンク

2017/11/20(Mon) 09:53:52|NO.81879

すみません、上記補足です。
画面サイズ:1920x1080
CPU:Core i5-3470



ham

リンク

2017/11/20(Mon) 14:57:06|NO.81880

Tsubame 様 回答ありがとうございます。

私の場合、透過も雪も無しでhspのCPU使用率は5%になりましたがGPU使用率が28%になるので
かなり負荷かかってる感じですかねこれ...
ちなみにXeon X3430 4.2GHz GTX560Ti 1920x1080です。

高解像度になってくると標準命令での描画は厳しいですかね・・・
hgimg3や4の描画と同じ透過方法は共存できませんでしたが;;



ONION software Copyright 1997-2018(c) All rights reserved.