ページ 11

WINAPI裏描写について

Posted: 2009年8月19日(水) 19:51
by kazuoni
お邪魔します。

現在WINAPIを使用して、裏描写を行っているのですが、
どうも、画像の残像が残ってしまいます。

言葉では説明できないので、全コードをアップしました。
大変申し訳ないですが、player.bmpを用意してください。。orz
(あるサイトをほぼコピーなので、画像までは添付できry)

表描写のクリアができていないのが原因のような気がするのですが、
自分では特定できずにいます。
WINAPIは全くの初心者なので、これで効率のよい描写ができているかどうか
不安なので、そのあたりも見ていただけると幸いです。。

よろしくおねがいします。

Re:WINAPI裏描写について

Posted: 2009年8月19日(水) 21:05
by Justy
 FillRectとか PatBltで消せるかと。

Re:WINAPI裏描写について

Posted: 2009年8月19日(水) 22:30
by kazuoni
Justyさん、ご回答ありがとうございます。

上書きすることでよかったのですねorz

裏描写をPatBltによって消す(上書きする)ことで、うまくいきました。

次回もよろしくお願いします。

#WINAPIのみだと、グラフィックの表現の幅で詰みそうな気がしてなりません・・・

Re:WINAPI裏描写について

Posted: 2009年8月20日(木) 13:52
by kazuoni
解決としてましたが、また分からないところが出ました。。
他の方に参考にならない質問になりますので、続きから追加質問をさせていただきます。

とりあえず、うまく描写はできるようになったのですが、
キー入力が安定していません。(キー入力が原因かも分かりませんが・・・)
添付しているプログラムでは、用意した画像が
方向キーで移動する単純なプログラムです。
恐らく、キー監査、FPS制御ともにうまくできている(はず)のですが、
ある程度長押し(約5,60ループ後)すると、いきなり画像の移動速度が下がります。
離して、再度同じキーを長押ししても、同じこの繰り返しとなります。
FPSは60で変化がないので、FPS制御はうまくいっているようです(60ちょうどっというのが怪しい気がしますが・・・)
また、速度低下後、押しているキーと別のキーを一度押すと、速度は元に戻り、
それ以降は通常の速度で移動してくれます。
FPS制御がうまくできているなら、一ループにかかる処理がキーを押してから5,60ループ後に
重くなっているということになりますが、該当するところがありません(あっても気が付きません。)

修正点がありましたら、アドバイスをよろしくお願いします。

Re:WINAPI裏描写について

Posted: 2009年8月21日(金) 00:49
by Justy
[color=#d0b0c0" face="monospace]
>重くなっているということになりますが、該当するところがありません
[/color]

 非常に単純な話です。
 
 現在の処理は Windowsメッセージがある場合、1フレームに1つだけ処理をして
次のフレームに移り、メッセージがなければメインの処理を行ない、
UpdateWindow()で描画が行われるようになっています。
 
 この処理の方法では、ウインドウに対して何のアクションも行わなければ
Windowsメッセージは WM_PAINTだけになるので、60fpsで描画されますが、
マウスを動かす、キーを押しつづけるなどメッセージが発生するアクションを起こすと
その個々のメッセージを処理するだけで1フレーム使ってしまい、
メインが2フレームに1回くらいになります。

 試しに右を押しっぱなしにしているときに途中でマウスを動かしてみて下さい。
 多分動きがさらに遅くなるか、完全に止まってしまうのではないでしょうか。



 で、解決方法ですが、手っ取り早い方法としては
[color=#d0d0ff" face="monospace]
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

BitBlt(g_hBackBuffer, player.x, player.y, player.width, player.height,player.graphic.getMask(), 0, 0, SRCAND);
...
[/color]

tと、こんな感じにメッセージを全部処理してからメインを処理するようにすると
マシンパワーが十分なら前のように遅くはならないはずです。

 ただ、PeekMessageが処理によっては重くなることもあるので、そういうことが
頻発するようならもうちょっと改善が必要になるかもしれません。

Re:WINAPI裏描写について

Posted: 2009年8月21日(金) 05:14
by kazuoni
あ、5,60フレーム=長押しのメッセージが出てきていたんですね^^;
確かにマウスの時も動きは完全に停止でした。
確かにJustyさんのおしゃるとおりに実行したら、問題なく動きました。

>ただ、PeekMessageが処理によっては重くなることもあるので、そういうことが
>頻発するようならもうちょっと改善が必要になるかもしれません。

まだPeekMessageの仕様はmsdnを眺めた程度なので、まったく理解できていませんが、
どのような処理の時に、重い挙動を見せ、
大まかな解決法はどのような道筋でしょうか?
今後の参考までに教えていただけるとありがたいです^^;

Re:WINAPI裏描写について

Posted: 2009年8月22日(土) 02:04
by Justy
[color=#d0b0c0" face="monospace]
>どのような処理の時に、重い挙動を見せ、
[/color]

 どれがどうとは言えませんが、そもそも自分で定義したプロシージャが重いとか
多くのメッセージが一度に届いた時は上のコードですと全て処理してから
メインを実行しますのでその分重くなります。


[color=#d0b0c0" face="monospace]
>大まかな解決法はどのような道筋でしょうか?
[/color]

 処理の内容にもよりますが、真っ先に思いつくのはスレッド化でしょうか。

 ウインドウとは別のスレッドでメインの処理を行えば、
最終描画以外はメッセージに引きずられることなく処理できます。

 或いは PeekMessage毎の処理の負荷を見ながらいくつ分の
メッセージの処理を行うか動的に決めて、適度に分散させる、とか。

Re:WINAPI裏描写について

Posted: 2009年8月23日(日) 16:12
by kazuoni
Justyさん、ご回答ありがとうございます!

マルチスレッドはまだ触ってもないので、これからかと思いますが・・・
もう少ししたら勉強していきたいと思います。

ご回答ありがとうございました。
次回もよろしくお願いします。