Здравствуйте! Помогите разобраться с SetDIBitsToDevice
. В программе, в которую я хочу внедрить эту функцию, используется двойная буферизация, на конечный HDC
выводиться всё с помощью ф-ии BitBlt
. Естественно проблемы с производительностью. Раньше, при изучении, пропустил мимо SetDIBitsToDevice
, теперь понял что она, видимо то что мне нужно.
Итак, если я правильно понял алгоритм таков:
Создаём массив, который будет нашей "матрицей" - создаём BITMAPINFO
, заполняем - "рисуем" в нашей "матрице" - вызываем SetDIBitsToDevice
.
Код ниже выполнятся правильно, видим розовый фон и чёрный квадрат.
BITMAPINFO bif;
ZeroMemory(&bif, sizeof(BITMAPINFO));
bif.bmiHeader.biSize = sizeof(bif);
RGBQUAD *im = new RGBQUAD[r.right*r.bottom];
for (int i(0); i < r.right*r.bottom; i++)
{
im[i].rgbBlue = 255;
im[i].rgbRed = 255;
im[i].rgbGreen = 0;
}
for (int i(0); i < 200; i++)
for (int ii(0); ii < 200; ii++)
{
if (r.right*i + ii < r.right*r.bottom)
{
im[r.right*i + ii].rgbBlue = 0;
im[r.right*i + ii].rgbRed = 0;
im[r.right*i + ii].rgbGreen = 0;
}
}
bif.bmiHeader.biHeight = -r.bottom;
bif.bmiHeader.biWidth = r.right;
bif.bmiHeader.biSizeImage = ((bif.bmiHeader.biWidth * 24 + 31)& ~31) / 8 * bif.bmiHeader.biHeight;
bif.bmiHeader.biPlanes = 1;
bif.bmiHeader.biBitCount = sizeof(RGBQUAD)*8;
SetDIBitsToDevice(hdc, 0, 0, r.right, r.bottom, 0, 0, 0, r.bottom, im, &bif, DIB_PAL_COLORS);
delete[] im;
Но писать свои Rectangle
Ellipse
и т.д. времени нету, да и я о сглаживании молчу. Значит нужно использовать GDI и GDI+. Каков алгоритм в этом случае(если я не прав, то поправьте):
Создаём совместный ДС, и битмап - рисуем там - создаём массив, который будет нашей "матрицей" - создаём BITMAPINFO
, заполняем, с помощью SetDIBits - вызываем SetDIBitsToDevice
.
Код ниже не выполнятся правильно, просто белый фон
tagPAINTSTRUCT ps;
hdc=BeginPaint(hWnd, &ps);
HDC hdcc = CreateCompatibleDC(hdc);
HBITMAP bm = CreateCompatibleBitmap(hdc, r.right, r.bottom);
SelectObject(hdcc, bm);
HBRUSH hb = CreateSolidBrush(RGB(0, 0, 0));
SelectObject(hdcc, hb);
Rectangle(hdcc, 0, 0, 100, 100);
DeleteObject(hb);
BITMAPINFO bif;
ZeroMemory(&bif, sizeof(BITMAPINFO));
bif.bmiHeader.biSize = sizeof(bif);
RGBQUAD *im = new RGBQUAD[r.right*r.bottom];
SetDIBits(hdcc, bm, 0, r.bottom, im, &bif, DIB_PAL_COLORS);
SetDIBitsToDevice(hdc, 0, 0, r.right, r.bottom, 0, 0, 0, r.bottom, im, &bif, DIB_PAL_COLORS);
delete[] im;
DeleteObject(bm);
DeleteDC(hdcc);
EndPaint(hWnd, &ps);
1)На МСДН написано, что нельзя в SetDIBits
передавать использующийся в данный момент HBITMAP, но как тогда в него рисовать?
2)Возможно я не полностью\не правильно заполняю HBITMAP
. В одном из примеров видел что SetDIBits
вызывается дважды, в первый раз в качестве указателя на массив передаётся 0, как объяснял автор, именно так заполняется HBITMAPINFO
.
P.S. час ночи, голова не варит, может я просто туплю
Походу всё из-за того, что на часах было час ночи. Вся проблема была в том, что я для конвертации HBITMAP
использовал SetDIBits, a надо было GetDIBits. И да, вызвать надо дважды. Вот полностью рабочий пример:
GetClientRect(hWnd, &r);
tagPAINTSTRUCT ps;
hdc=BeginPaint(hWnd, &ps);
HDC hdcc = CreateCompatibleDC(hdc);
HBITMAP bm = CreateCompatibleBitmap(hdc, r.right, r.bottom), sec = CreateCompatibleBitmap(hdc, r.right, r.bottom);
SelectObject(hdcc, bm);
//ТОДО: код прорисовки
HBRUSH hb = CreateSolidBrush(RGB(255, 0, 0));
SelectObject(hdcc, hb);
Rectangle(hdcc, 0, 0, 100, 100);
DeleteObject(hb);
//
BITMAPINFO bif;
ZeroMemory(&bif, sizeof(BITMAPINFO));
//Эти поля нужно зполнять вручную
bif.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bif.bmiHeader.biBitCount = 4*8;
bif.bmiHeader.biWidth = r.right;
bif.bmiHeader.biHeight = r.bottom;
GetDIBits(hdcc, bm, 0, 0, 0, &bif, DIB_RGB_COLORS);
RGBQUAD *im = new RGBQUAD[r.right*r.bottom];
GetDIBits(hdcc, bm, 0, r.bottom, im, &bif, DIB_RGB_COLORS);
SetDIBitsToDevice(hdc, 0, 0, r.right, r.bottom, 0, 0, 0, r.bottom, im, &bif, DIB_RGB_COLORS);
delete[] im;
DeleteObject(bm);
DeleteDC(hdcc);
EndPaint(hWnd, &ps);
Как всегда пришлось перерыть 300 форумов, мсднов и стэковерфлоувов...
Если закрыть глаза на "особенности кода", то похоже Ваше проблема закралась здесь
Здравствуйте, нашел на неком ресурсе подобный код(немного его модифицировал под себя):