我有一个指向Colorref缓冲区的指针,类似: COLORREF* buf = new COLORREF[x*y];

子例程用色素填充此缓冲区。每个Colorref代表一个像素。

现在,我想将此缓冲区绘制到设备上下文中。 我当前的方法有效,但相当慢(== 〜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并不熟悉。我听说过很多API,例如CreateSibitMap(),Bitblt(),Hbitmap,cimage和所有这些内容,但不知道如何应用它。看来一切都很复杂...
也欢迎MFC。

有任何想法吗?

提前致谢。

(背景:上面提到的子例程是OpenCL内核 - GPU计算了Mandelbrot映像并将其保存在Colorref Buffer中。)

编辑:
谢谢大家的建议。答案(和链接)使我对Windows Graphics编程有所了解。现在的性能是可以接受的(半真实的时间滚动到Mandelbrot的作品:)
我最终得到了以下解决方案(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()使我免于使用RAW API(我仍然不完全理解)。文档中的示例 CDC :: CreateCompatibledc 也很有帮助。
我的mandelbrot现在为蓝色 - 使用setPixelv()它是红色的。但是我想这与cbitmap :: createbitmap()解释我的缓冲区有关,这并不重要。

我可能会尝试使用OpenGL建议,因为这将是更合乎逻辑的选择,无论如何我都想在Linux下尝试OpenCL。

有帮助吗?

解决方案

在这种情况下,我可能会使用DIB部分(您与之创建 CreateDIBSection)。 DIB部分是一个位图,可让您直接访问内容作为数组,但仍将其与所有常规的GDI函数一起使用。

我认为这将为您提供基于GDI的最佳表现。如果您需要更好,那么@kornel基本上是正确的 - 您需要切换到对硬件加速有更多直接支持的东西(DirectX 或者 OpenGL-尽管IMO,OpenGL比DirectX是一个更好的选择)。

鉴于您目前正在进行OpenCL的计算并将输出存入颜色缓冲区,因此OpenGL将是 真的 明显的选择。特别是,您可以让OpenCL将输出存入OpenGL纹理中,然后使用该纹理绘制Quad。另外,由于无论如何您都将输出放在屏幕上,因此您可以在OpenGL片段着色器(或当然是DirectX Pixel着色器)中进行计算,因此您不会将输出放入内存中这样您就可以将结果复制到屏幕上。如果记忆有用,则橙色书将其曼德布罗特着色器作为其示例之一。

其他提示

是的,当然,这很慢。您正在为每个像素的内核和视频设备驱动程序进行往返。您可以通过首先绘制记忆来快速地制造它,然后一口气更新屏幕。例如,createCompatibledc()和bitblt()采用createCompatibledc()。

这不是关于图形编程的广泛教程的好时机和地点。 GDI和/或Windows API编程上的任何介绍性文本都涵盖了它。您需要知道的所有内容都可以在Petzold的开创性编程窗口中找到。

由于您已经有一系列像素,因此可以直接使用BitBlt将其传输到窗口的直流。有关部分示例,请参见此链接:http://msdn.microsoft.com/en-us/library/aa928058.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top