|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 23, 2004 14:10:47 Правка Доброе время суток! есть код: XVisualInfo *visualList;
int nVisuals,depth;
ulong rShift,gShift,bShift,rDiv,gDiv,bDiv;
...
visualList = XGetVisualInfo(display, VisualNoMask, &visualTempl,&nVisuals);
if (visualList->c_class == TrueColor) {
trueColor = gTrue;
for (mask = visualList->red_mask, rShift = 0;
mask && !(mask & 1);
mask >>= 1, ++rShift);
for (rDiv = 8; mask; mask >>= 1, --rDiv);
for (mask = visualList->green_mask, gShift = 0;
mask && !(mask & 1);
mask >>= 1, ++gShift);
for (gDiv = 8; mask; mask >>= 1, --gDiv);
for (mask = visualList->blue_mask, bShift = 0;
mask && !(mask & 1);
mask >>= 1, ++bShift);
for (bDiv = 8; mask; mask >>= 1, --bDiv);
}
Как я понял, он получает информацию из графич. окружения и на основе её формирует маски для цветов. В дальшейшем они используются так:
XImage *image;
p = dataPtr.rgb8 + (y + srcY) * bw + srcX; // получение указателя на масив цветов картинки
for (x = 0; x < width; ++x) {
rgb = *p++;
r = splashRGB8R(rgb) >> rDiv;
g = splashRGB8G(rgb) >> gDiv;
b = splashRGB8B(rgb) >> bDiv;
pixel = ((Gulong)r << rShift) +
((Gulong)g << gShift) +
((Gulong)b << bShift);
XPutPixel(image, x, y, pixel);
Как сделать порт этого кода для Win32? Т.е., сам код я портировал, но не полностью понимаю, для чего используются xDiv? И ещё: Вместо XPutPixel я сделал SetPixel(hMemDc,x,y,pixel), вот только опять же хотелось бы узнать, а можно ли как-то по-другому? Просто выставлять по пикселу, рисуя большой рисунок, довольно медленно. Можно ли как-то улучшить это? Пинки приветствуются :) Если что-то нужно пояснить подробнее, поясню. |
|
|
Дата: Июн 23, 2004 15:22:35 · Поправил: Shift можно посмотреть, как люди делают: http://www.hal9k.com/cug/links/subject35.htm ещё можно посёрчить в исходниках wine - как они делают. |
|
|
Дата: Июн 23, 2004 23:55:12 IceStudent В BITMAPINFOHEADER заполняем поля biSize, biWidth, biHeight, biPlanes=1 и biBitCount, функцией GreateDIBSection создаем картинку, а затем через указатель сохраненный в ppvBits рисуем в ней. |
|
|
Дата: Июн 29, 2004 11:11:15 Правка Black_mirror Спасибо, так действительно быстрее… Насчёт первого вопроса - просто xDiv ставлю в 0, а xShift — по 00BBGGRR. Вроде бы работает правильно. И можно вовсе убрать xDiv. |
|
|
Дата: Июл 5, 2004 14:05:48 Правка Black_mirror Да, кстати, а создавать это надо на Memory context (hMemDC) или на текущем (GetDC)? |
|
|
Дата: Июл 6, 2004 16:28:10 Из описания CreateDIBSection: hdc [in] Handle to a device context. If the value of iUsage is DIB_PAL_COLORS, the function uses this device context's logical palette to initialize the DIB's colors. Так что думаю что для iUsage=DIB_RGB_COLORS пофиг. |
|
|
Дата: Июл 7, 2004 12:29:24 Правка Black_mirror Я имею ввиду, если сделать на memory context: это будет быстрее? или наоборот, медленнее, из-за создания, копирования и удаления его? |
|
|
Дата: Июл 7, 2004 13:21:28 IceStudent Если в том месте, где требуется создать картинку, можно дотянутся до какого-нибудь hDC, то я бы его и использовал, потому что если картинка RGB, то CreateDIBSection к этому контексту скорее всего вообще обращатся не будет. Намного большее влияние на скорость будет оказывать размер создаваемой картинки, особенно если винда начнет свопиться, чтобы нужный кусок памяти выделить. |
|
|
Дата: Июл 7, 2004 13:28:07 Правка Black_mirror Понятно, спасибо! |
|
|
Дата: Июл 9, 2004 11:24:34 Правка Хотя, нет. Делаю HDC hDc = GetDC(hdrawWnd); hDib = CreateDIBSection(hDc,…); SelectObject(hDc,hDib); … DeleteObject(hDib); ReleaseDC(hDc); но окошко остаётся белым. А если через memory device context, то отрисовывается нормально. Я что-то делаю не так? |
|
|
Дата: Июл 9, 2004 13:48:29 IceStudent У меня есть подозрение контект полученый через GetDC совпадает с контекстом полученный через BeginPaint, а при вызове BeginPaint винда создает картинку в которой приложение может рисовать, а после вызова EndPaint, винда скопирует данные из этой картинки на экран. А так как мы эту картинку заменили на свою, то та картинка из которой винда берет данные не изменится, поэтому на экране никаких изменений не произойдет. Чтобы скопировать картинку нужно 2 контескта. А вот какой из них передавать в CreateDIBSection совершенно не важно. |
|
|
Дата: Июл 11, 2004 11:14:26 Правка Black_mirror Спасибо за ответы! BeginPaint я не вызываю, а отрисовываю по WM_Paint., потом BitBlt. Кажется, это наиболее быстро? |
|
|
Дата: Июл 11, 2004 12:20:30 IceStudent BeginPaint я не вызываю, а отрисовываю по WM_Paint Я имел ввиду случай когда картинку создаем при обработке WM_PAINT. Вроде если при обработке WM_PAINT не вызывать BeginPaint/EndPaint, это сообщение удаляться из очереди не будет и программа будет постоянно занималься перерисовкой. |
|
|
Дата: Июл 11, 2004 12:38:07 · Поправил: IceStudent Правка Black_mirror это сообщение удаляться из очереди не будет Да нет, перерисовывает только когда надо, только надо отреагировать правильно. А Begin/End paint не обязательно, кажется (An application returns zero if it processes this message).... |
|
|
Дата: Июл 12, 2004 17:42:48 Правка Наткнулся на интересный баг: если ширина рисунка больше или равна 0х400, то возникает исключение (попятка записи по неверному указателю). С чем это связано, даже не представляю. Попробовал выделить больше памяти в BITMAPINFOHEADER (что-то подобное видел в коде ATL), но это не помогло. Попытался увеличить ширину в структуре, но даже при изменении на 1 пиксел картинка искажается самым неожиданным образом. Почему именно 0х400 — даже не представляю, когда пробегаюсь по 0х3FF и менее — всё нормально, дальше - AccessViolation. Причём если режим экрана 800х600, то до ошибки вообще дело не доходит, проблемы возникают при бОльших расширениях… Замаскировал сее недоразумение умешьшением цикла, в котором отрисовываю картинку, на единицу по ширине. Но мне кажется, что это не выход, хотелось бы разобраться до конца. |