OnDraw関数での再描画について

[戻る]
ヘット 2004/04/17(土) 15:03:24
こんにちはよろしくお願いいたします。

VC6SP5 MFC XPProで開発を行っています。

OnDraw関数で再描画を高速にする方法を教えていただきたいとおもい書き込みました。

ImgBuff[(z)256][(y)512][(x)512]に三次元情報を格納しています。
これをスクロールバーでzの値を取得しSetPixelでそのときのy,xの値を
描画するようなプログラムを作成したいのですが、再描画の遅さに
戸惑っています。

LoadBitmapのようにMemoryDCに格納してBitBltして高速描画をしたいのですが
いい方法が見つかりません。

まだまだMFCをはじめて3ヶ月足らずで勉強不足かもしれませんが、
よろしくお願いいたします。

アイススケーター 2004/04/17(土) 15:09:01
遅いとはどの程度遅いのでしょうか
何秒(msecかな)

2004/04/17(土) 18:47:19
>OnDraw関数で再描画を高速にする方法を教えていただきたいとおもい書き込みました。
>
>ImgBuff[(z)256][(y)512][(x)512]に三次元情報を格納しています。
>これをスクロールバーでzの値を取得しSetPixelでそのときのy,xの値を
>描画するようなプログラムを作成したいのですが、再描画の遅さに
>戸惑っています。

OnDraw() 内で、SetPixel() で描画しているということですから
ひょっとしたら、OnDraw() の引数 CDC *pDC に対して SetPixel() で
描画しているのではないでしょうか

そうだとしたら、DIB か DibSection かに直接各ピクセルに対して色をつけて
しまった上で OnDraw() では CDC *pDC に対して適切な方法(例えば
StretchDIBits())で描画するようにしてみては如何でしょう
つまり、スクロールバーから得た z の値が判った時点で DIB か DibSection
かに生成したい画像を描画するということです
これはオフスクリーンだとか裏画面だとかいろいろな呼び方がある技法です

PATIO 2004/04/19(月) 10:27:59
GDIでの描画はDirectXなどの描画専用ライブラリを使った場合に比べれば遅いです。
GDIは出力先のデバイスを意識しなくても描画できるためのインターフェイスを提供して
いるので、どうしてもさまざまな変換処理等が入ってしまい、高速に描画できません。
裏画面を使った描画を行ったとしても自ずと限界が有ります。
高速性を求められるような描画が行いたいのであれば、DirectXなどの描画ライブラリを
つかった描画を検討した方がいいと思います。
実際、アクションゲームなどの高速描画が必要なアプリはDirectXを使っている事から
してもそれがわかると思います。
普通にMoveTo、LineToで描画しても結構遅いのにSetPixelで一点ずつ描画していたので
は遅くなっても仕方ないと思いますよ。
ただ、裏画面描画などの手法で得られる程度の高速化で満足できるのであれば、
無理にこれらの手法に走る必要は無いと思います。
適材適所といいますからね。

あと、泥臭い話になりますが、CreateDIBSectionで作成したDIBであれば、
ビットマップ情報の先頭アドレスが得られるので画素子のアドレス計算をして自前で
直接描画なんて事も可能です。うまくやれば結構高速描画できると思います。
但し、ビットマップの色深度などを考慮してアドレス計算をする必要があるのと
メモリに画素子情報を設定するにもそれなりの時間はかかるので色々調整しないと
本当の意味で早くする事は難しいと思います。
多分、DirectXなんかも同じような事をやっていると思いますので自前でやるのも
良し悪しだとは思いますけれど。

ヘット 2004/04/19(月) 20:10:52
m_circleにImgBuff[(z)256][(y)512][(x)512]
perPixelにスクロールバーから取得した値が格納されています。

    BITMAP bm;
    CPoint pt;

    CDC memDC;
    CBitmap bmp,*pbmp;
    memDC.CreateCompatibleDC( pDC );
    bmp.CreateCompatibleBitmap( pDC, 512, 512); 
    pbmp = memDC.SelectObject( &bmp );

        for(long j=0;j<200;j++){
          for(long i=0;i<200;i++){
                pt.x =i;
                pt.y =j;
                memDC.SetPixel(pt,RGB(m_circle[perPixel][j]
[i],m_circle[perPixel][j][i],m_circle[perPixel][j][i]));
          }
        }
        pDC->BitBlt(0, 0,512,512,&memDC,0,0,SRCCOPY); 
    memDC.SelectObject( pbmp );
    memDC.DeleteDC();
    bmp.DeleteObject();
    ReleaseDC( pDC );

として、描画は早くなりましたが、ちらつきます。どのように改善すればよいのでしょう
か?

n 2004/04/20(火) 08:35:55
このラウンジで「ちらつき」で検索すると色々出ますよ。

ヘット 2004/04/21(水) 17:05:58
[[解決]]
皆様有難うございました。

OnEraseBkgndをフラグをたててTRUEを返すことにより
解決できました。

古いスレッドには追加発言できません。