1

私の目的は、グラフィックスオブジェクトのメソッドを使用して描画された視覚要素を、ちらつきやアーティファクトなしでフォーム全体に移動することです(.NET 3.5の場合)。自動ダブルバッファリング(フォームのDoubleBufferedプロパティをtrueに設定)を使用するか、自分でバックバッファを実装することで、ちらつきのない動きを実現できます。しかし、はっきりと見えるアーティファクトを表示せずに、どちらの方法を使用する方法を見つけるのにも苦労しています。

自動ダブルバッファリングを使用すると、ページティアリング効果が明らかになります。60Hz LCDを3回更新すると、バックバッファがゆっくりと、徐々にフォームに上から下にコピーされているように見えます。

自分でダブルバッファリングを実装すると(詳細はコードブロックを参照)、ページティアリングが発生しないほど高速にバックバッファがフォームにコピーされているように見えます。ただし、別の種類のアーティファクトが表示される場合があります。以下のコードは、矢印キーを使用してフォームの白い背景の青い長方形を左右に移動できるようにするもので、長方形の左右の端に時々表示される一連の水平方向の白い帯として効果を再現する必要があります。動かされるのと同じように。

public partial class Form1 : Form {
    int x;
    Bitmap buffer;

    public Form1() {
        InitializeComponent();
        buffer = new Bitmap(Width, Height);
    }

    private void Form1_Paint(object sender, PaintEventArgs e) {
        Graphics g = Graphics.FromImage(buffer);
        g.Clear(Color.FromArgb(255, 255, 255));
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.FillRectangle(Brushes.Blue, x, 0, 100, 500);
        e.Graphics.DrawImageUnscaled(buffer, 0, 0);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent) {
        //Don't allow the background to paint
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e) {
        const int scrollSpeed = 20;
        if(e.KeyData == Keys.Left) {
            x -= scrollSpeed;
            Refresh();
        }
        else {
            if(e.KeyData == Keys.Right) {
                x += scrollSpeed;
                Refresh();
            }
        }
    }
}

if(他の人が効果を再現できる){
    私は何か間違ったことをしているのでしょうか、おそらく
    ペイントコードで何らかの競合状態を引き起こしているのでしょうか、それともこれは私が     生き
    なければならないランタイムの動作にすぎないのでしょうか? } else {     それは私のディスプレイカードの特性か、     バグのあるディスプレイドライバでしょうか? }





4

4 に答える 4

1

It may be important to know that graphics cards accelerating 2D operations usually accelerate GDI, not GDI+. I think that using a GDI bitmap and drawing it directly using a GDI methods (e.g. through p/invoke) would make things faster.

于 2009-04-16T16:34:46.770 に答える
1

ダブル バッファリングを行うときはいつでも、Paint イベント内にレンダリング コードがないようにしました。イベント内の唯一のコードは、バッファーから画面にコピーすることでした。

レンダリング コードを独自の関数に移動してから、領域 (この場合はフォーム) を無効にしてみてください。

RenderScene()
Invalidate()

それが役立つかどうかを確認してください。適切な測定のために、OnResize をオーバーライドしてバッファのサイズも変更します。

于 2009-04-16T16:44:40.227 に答える
0

オーバースラックスが使用すると言ったものに加えInvalidateて、変換を適用せずに四角形を塗りつぶすためのアンチエイリアシングも必要ありません。

于 2009-04-16T17:33:22.060 に答える
0

キーを押して放すと、実際には「問題なく」見えます(ただし、キーを押したままにすると、次の動きで解決する少しの裂け目があります)。

ATI x1300 と Intel e6400 を搭載した Vista を使用しています。おそらく、処理速度またはビデオ カードが問題ですか?

編集:上記のことを言って、私は他の人に同意し、高速を探しているならGDI +は行くべき道ではないと言います. DirectX または Windows API を使用する方法が適している場合があります。

于 2009-04-16T16:41:12.340 に答える