0

私は wxWidgets にかなり慣れていないので、ご容赦ください。10Kx10K の画像があり、wxScrolledWindow のサイズが 640x480 だとします。画像全体を、ペイント関数で使用する wxBitmap に読み込みます。

今私のOnPaint関数で私はただ言います

wxPaintDC dc(this);
dc.DrawBitmap(_Bitmap, 0, 0 );

これは、最初の数回のペイントではある程度機能しますが、すぐにウィンドウの内容が乱れ、アーティファクトが表示されます。これは、スクロール バーを前後にすばやく動かすと、非常に速く発生します。

Windows 7 マシンで最新の wxWidgets を使用しています。

では、ペイント コードを改善するにはどうすればよいでしょうか。

どうもありがとう、クリスチャン

4

3 に答える 3

3

10000x10000 の wxBitmap を使用すること自体は悪い考えです。古いシステム (400MiB のビデオ RAM) では作成に失敗する可能性があります。それを完全に描くのはまったくの狂気です。

データがどこから来たのかはわかりませんが、たとえば画面に表示されるマップの典型的なケースでは、それをタイルに分割し、現在画面に表示されているタイルを wxBitmap (またはそれらのいくつか) に変換する必要があります。それらだけを描きます。

次に、ダブル バッファリング (すべてを単独でダブル バッファリングする Windows 7 では比較的役に立たない) を使用して描画を最適化できますが、適切なサイズのバッキング ストア ビットマップを使用する必要があります。

于 2012-08-29T23:10:33.320 に答える
1

これは、ダブル バッファリングを使用することで改善される可能性があるように思えます。

最初に試みることは、wxPaintDC をwxBufferedPaintDCに置き換えることです。

その他の提案については、このテーマに関する wiki 記事をご覧ください: http://wiki.wxwidgets.org/Flicker-Free_Drawing

于 2012-08-29T21:59:05.150 に答える
0

Ravenspoint が親切に指摘したように、wxWidgets の wiki に記事があります。したがって、その記事によると、2 つのことが起こる必要があります。最初に EVT_ERASE_BACKGROUND を空の関数でオーバーライドします。

void Canvas::EraseBackground( wxEraseEvent& WXUNUSED(event))
{
}

次に、基本的なダブル バッファリング スキームを実装します。これが私がやった方法です。

void Canvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    int x, y;
    GetViewStart(&x, &y);
    wxRect Client_Area = GetClientRect();

    int width  = Client_Area.width;
    int height = Client_Area.height;

    wxBitmap Current = _Bitmap.GetSubBitmap(wxRect( x * 10, y * 10, width, height ));

    wxPaintDC dc(this);
    dc.DrawBitmap(Current, 0, 0, false );
}

x と y の両方のスクロール レートは 10 に設定されています。そのため、ビューの開始座標を乗算します。

これ以上の洞察は大歓迎です。

ありがとう、クリスチャン

于 2012-08-29T22:22:02.043 に答える