я использую функции GDI - заполняю построчно предварительно создаый битмап через SetDIBits
Дурацкий вопрос - а битмап создается с помощью CreateDIBSection? Если нет, тогда проблема скорости вполне закономерна: при каждой модификации посредством SetDIBits системе надо из DDB сделать временный DIB (естественно не без копирования), на этом временном DIB-е проделать изменения, а потом вернуть все взад - преобразовать и скопировать из DIB в DDB, после чего удалить DIB.
---------- Post added at 18:52 ---------- Previous post was at 18:22 ----------
Короче, я понял - скорее всего битмап создается именно через CreateCompatibleBitmap, что и порождает дальнейшие тормоза с SetDIBits.
Вот пример кода:
Код:
void CBaseView::OnDraw(CDC* pDC)
{
CRect rc;
GetClientRect(&rc);
CDC dc2, *pMemDC;
CBitmap *pBmpPrev = NULL;
void *pBuf = NULL;
int width = rc.Width();
int height = rc.Height();
if(dc2.CreateCompatibleDC(pDC))
pMemDC = &dc2;
else
pMemDC = pDC;
BITMAPINFO bmp_info;
bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp_info.bmiHeader.biWidth = width;
bmp_info.bmiHeader.biHeight = height;
bmp_info.bmiHeader.biPlanes = 1;
bmp_info.bmiHeader.biBitCount = 32;
bmp_info.bmiHeader.biCompression = BI_RGB;
bmp_info.bmiHeader.biSizeImage = 0;
bmp_info.bmiHeader.biXPelsPerMeter = 0;
bmp_info.bmiHeader.biYPelsPerMeter = 0;
bmp_info.bmiHeader.biClrUsed = 0;
bmp_info.bmiHeader.biClrImportant = 0;
CBitmap *pBitmap = CBitmap::FromHandle(
CreateDIBSection(m_pDC->m_hDC,
&bmp_info,
DIB_RGB_COLORS,
&pBuf,
0,
0));
pBmpPrev = m_pDC->SelectObject(pBitmap);
//
// painting here on pMemDC...
// ...or u can paint directly in bitmap buffer pBuf
//
PaintData(pMemDC);
if(pDC != pMemDC)
{
pDC->BitBlt(0, 0, width, height, pMemDC, 0, 0, SRCCOPY);
pMemDC->DeleteDC();
}
else
pMemDC->SelectObject(pBmpPrev);
if(pBitmap)
pBitmap->DeleteObject();
}
Как видно из приведенного фрагмента и каментов, можно напрямую менять буфер по указателю pBuf, ибо он имеет простой формат BI_RGB (по конкретике в MSDN). Т.е. копирование в лице чего-либо, в том числе и SetDIBits, вообще не нужно, ибо можно заниматься формированием кадра ZX Spectrum прямо в pBuf.
---------- Post added at 19:07 ---------- Previous post was at 18:52 ----------
И еще добавлю от себя. Вопрос "зачем вообще рисовать через GDI", в случае, когда тема звучит примерно как "медленный вывод в GDI, помогите", неуместен. На вопрос же
реально ли написать нормальный вывод на экран используя только GDI?
отвечу вкратце, что сделать нормальный вывод, используя GDI, вполне реально, особенно, используя библиотеки навроде AGG; однако, если нужно использовать аппаратное ускорение 3D видеоадаптера, тут GDI отдыхает по сравнению со, скажем, OpenGL (не эмулируемым конечно же). Также, у вышеприведенного наброска метода рисования в памяти есть и другие недостатки - отсутствие какого-либо ускорения 2D и удобств, каковые имеются, к примеру, в DirectX. На мой взгляд, для эмуляции экрана ZX Spectrum, если не нужно сглаживание, эмуляция нерезкого изображения, ТВ- и прочие эффекты, GDI подойдет в самый раз. Если потенциально нужна кроссплатформенность - тогда наоборот, лучше сразу забыть про GDI.