colorRefからdeviceContextを描く[
-
01-10-2019 - |
質問
ColorRefバッファーへのポインターがあります。 COLORREF* buf = new COLORREF[x*y];
サブルーチンは、このバッファーを色の情報で満たします。各ColorRefは1つのピクセルを表します。
次に、このバッファーをデバイスコンテキストに描画したいと思います。 私の現在のアプローチは機能しますが、かなり遅いです(画像のサイズに応じて、== 〜200ms、== 〜200ms:
for (size_t i = 0; i < pixelpos; ++i)
{
// Get X and Y coordinates from 1-dimensional buffer.
size_t y = i / wnd_size.cx;
size_t x = i % wnd_size.cx;
::SetPixelV(hDC, x, y, buf[i]);
}
これをより速く行う方法はありますか。一度に、次々とピクセルではありませんか?
私はGDIに本当に精通していません。 createdibitmap()、bitblt()、hbitmap、cimageなどのようなallocy apiについて聞いたことがありますが、それを適用する方法がわかりません。それはすべてかなり複雑に見えます...
MFCも大歓迎です。
何か案は?
前もって感謝します。
(背景:上記のサブルーチンはOpenCLカーネルです - GPUはマンデルブロットの画像を計算し、ColorRefバッファーで安全です。)
編集:
ご提案ありがとうございます。回答(およびリンク)は、Windowsグラフィックプログラミングに関する洞察を与えてくれました。パフォーマンスは現在受け入れられました(マンデルブロットの作品へのセミリアルタイムスロール:)
次のソリューション(MFC)になりました。
...
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
CBitmap mandelbrotBmp;
mandelbrotBmp.CreateBitmap(clientRect.Width(), clientRect.Height(), 1, 32, buf);
CBitmap* oldBmp = dcMemory.SelectObject(&mandelbrotBmp);
pDC->BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &dcMemory, 0, 0, SRCCOPY);
dcMemory.SelectObject(oldBmp);
mandelbrotBmp.DeleteObject();
したがって、基本的にcbitmap :: createbitmap()は、生のAPIを使用することを節約しました(まだ完全にはわかりません)。のドキュメントの例 CDC :: CreateCompatibledC また、役に立ちました。
Mandelbrotは青色になりました - setpixelv()を使用して赤くなりました。しかし、それはCBITMAP :: CreateBitMap()のバッファーの解釈と関係があると思いますが、それほど重要ではありません。
OpenGLの提案を試してみるかもしれません。なぜなら、それははるかに論理的な選択だったので、とにかくLinuxの下でOpenCLを試してみたかったからです。
解決
状況下では、おそらくDIBセクションを使用します(あなたが作成します CreateDIBSection
)。 DIBセクションは、コンテンツに直接配列としてアクセスできるビットマップですが、通常のすべてのGDI関数で使用します。
GDIに基づいたあらゆるものの最高のパフォーマンスを提供すると思います。あなたがより良い必要がある場合、 @Kornelは基本的に正しいです - あなたはハードウェア加速度をより直接的なサポートを持っているものに切り替える必要があります(DirectX また OpenGL -IMOですが、OpenGLはDirectXよりもジョブにとってはるかに優れた選択肢です)。
現在、OpenCLで計算を行っており、カラーバッファーに出力を堆積させていることを考えると、OpenGLは 本当 明らかな選択。特に、OpenGLをOpenGLテクスチャにOPENCLでデポジットすることができます。その後、そのテクスチャを使用してOpenGL DrawをQuadに描画できます。または、とにかく画面に出力を配置するだけなので、OpenGLフラグメントシェーダー(またはもちろん、DirectXピクセルシェーダー)で計算を行うことができます。結果を画面にコピーできます。メモリが役立つ場合、オレンジ色の本には、その例の1つとしてマンデルブロットシェーダーがあります。
他のヒント
はい、確かに、それは遅いです。個々のピクセルごとにカーネルとビデオデバイスドライバーを往復します。最初にメモリに描画することで速くなり、次に画面を1つの倒れた状態で更新します。たとえば、createdibitmap、createcompatibledc()およびbitblt()が必要です。
これは、グラフィックプログラミングに関する広範なチュートリアルの良い時期ではありません。 GDIおよび/またはWindows APIプログラミングに関する入門テキストでよくカバーされています。 Petzoldの独創的なプログラミングウィンドウで見つけることができることを知る必要があるすべてのもの。
すでにピクセルの配列があるため、Bitbltを使用してウィンドウのDCに直接転送できます。部分的な例については、このリンクを参照してください。http://msdn.microsoft.com/en-us/library/aa928058.aspx