最后提供的代码使用AlphaBlend()
绘制一个红色3x3px矩形网格,其中包含随机常数alpha值。然而,输出结果并非如此"相当"随机:
注意沿x轴运行恒定的alpha。
可能导致这种情况的原因是什么?
P.S。通过调试器步进产生预期的输出。
产生输出的代码:
void draw_mark(HDC hdc, int x, int y,
COLORREF mark_clr, int mark_w, int mark_h, BYTE alpha);
void produce_output(HWND hWnd) {
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
const int grid_w = 64, grid_h = 64;
const int mark_sz = 3;
HDC hdc = GetDC(hWnd);
for(int y = 0; y < grid_h; ++y) {
for(int x = 0; x < grid_w; ++x) {
BYTE rnd_alpha = rand(); // use random alpha for each mark
draw_mark(hdc, x * mark_sz, y * mark_sz,
RGB(255,0,0), mark_sz, mark_sz, rnd_alpha);
}
}
// clean-up
ReleaseDC(hWnd, hdc);
}
// draws a [mark_w x mark_h] rectangle at (x,y) with alpha
void draw_mark(HDC hdc, int x, int y,
COLORREF mark_clr, int mark_w, int mark_h, BYTE alpha)
{
HDC hdcMem = CreateCompatibleDC(NULL);
HBITMAP hbm = CreateCompatibleBitmap(hdc, mark_w, mark_h);
HGDIOBJ hOldBmp = SelectObject(hdcMem, hbm);
for(int x = 0; x < mark_w; ++x) {
for(int y = 0; y < mark_h; ++y) {
SetPixel(hdcMem, x, y, mark_clr);
}
}
POINT marker_center{mark_w / 2, mark_h / 2};
SetPixel(hdcMem, marker_center.x, marker_center.y, RGB(255, 255, 255));
BLENDFUNCTION bf{};
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = 0; // ignore source per-pixel alpha and...
bf.SourceConstantAlpha = alpha; // ...use constant alpha provided instead
AlphaBlend(hdc,
x - marker_center.x, y - marker_center.y,
mark_w, mark_h,
hdcMem, 0, 0, mark_w, mark_h, bf);
// clean-up
SelectObject(hdcMem, hOldBmp);
DeleteObject(hbm);
DeleteDC(hdcMem);
};
编辑 - 当我更多地了解它时,我注意到了其他问题:
1-当AlphaBlend()
目的地是内存DC时输出正常,但在窗口DC时则不正常。所以这个问题与直接在屏幕上显示有关。
2- Corrupt输出与使用rand()
功能无关。用BYTE rnd_alpha = rand();
替换++alpha
也会产生类似的损坏输出。
3-更有趣的是,将帖子暂停在内循环中,例如Sleep(some_duration)
似乎可以减少损坏。 some_duration
越高,腐败越少。这是一个示例输出:
首先输出到存储器DC,然后到窗口,产生第一个输出。其余的直接到窗口。注意随着线程暂停时间的减少,腐败如何增加(即输出变得不那么随机)。