SetDIBitsToDevice эмуляция

Я являюсь автором инструмента DxWnd, который пытается обеспечить поддержку для запуска старых и устаревших программ в современной среде Windows.

Очень странная игра — G-Nome, которая, несмотря на то, что может работать в системах Win7-10, создает серьезную проблему для графических манипуляций.

Игра ссылается на ddraw, но строит каждый кадр как DIB_PAL_COLORS DIB и выводит DIB на экран, используя SetDIBitsToDevice user32 звонки.
Операция поддерживается OBJ_DC Напечатайте DC на видео также в 32-битных режимах видео с глубиной цвета, но выдает плохие цвета при применении к DC типа MEM_DC.
Я обнаружил это, пытаясь масштабировать DIB, используя типичную схему, подобную этой (объявления переменных и проверка ошибок для краткости):

hTempDc=CreateCompatibleDC(hdc);
hbmPic=CreateCompatibleBitmap(hdc, OrigWidth, OrigHeight);
SelectObject(hTempDc, hbmPic);
SetDIBitsToDevice(hTempDc, 0, 0, OrigWidth, OrigHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse);
StretchBlt(hdc, XDest, YDest, dwWidth, dwHeight, hTempDc, 0, 0, OrigWidth, OrigHeight, SRCCOPY);

Согласно MSDN, когда вы выводите DIB_PAL_COLORS DIB пиксели отображаются на «текущую» реализованную палитру, но, конечно, на 32-битной поверхности и в клоне DC памяти нет палитры, поэтому неудивительно, что цвета пикселей выглядят неправильно.

Альтернативным решением может быть подражание SetDIBitsToDevice построение 32-битного DC памяти для последующего масштабирования StretchBlt, но опять же не задокументировано, как я мог конвертировать 8bpp DIB_PAL_COLORS DIB на 32 бита DIB_RGB_DIB или 32bpp DC.

Я уже пробовал несколько способов, но во всех случаях кажется, что я не могу определить правильную палитру, которая будет использоваться для преобразования индексов пикселей.
Может ли кто-нибудь помочь мне интерпретировать 8bpp DIB_PAL_COLORS Формат DIB?

0

Решение

Если я правильно понимаю вопрос, у вас есть исходное изображение в виде DIB с таблицей цветов, и вы хотите перенести это изображение в непалитровый DC с помощью SetDIBitsToDevice.

Я не работал с палитрами в течение очень долгого времени, но, если я правильно помню, вы не можете использовать DIB_PAL_COLORS, если конечный DC не является устройством палитры. Кажется маловероятным, что ваш DC памяти является устройством палитры, но вы можете проверить:

GetDeviceCaps(hTempDc, RASTERCAPS) & RC_PALETTE

Предполагая, что это не устройство палитры, я думаю, что вы должны использовать DIB_RGB_COLORS для fuColorUse. SetDIBitsToDevice будет использовать индекс каждого пикселя для поиска соответствующего значения RGBQUAD в таблице цветов. (Таблица цветов следует после BITMAPINFOHEADER в BITMAPINFO, на который указывает lpbmi.) Значения RGBQUAD применяются попиксельно к устройству назначения.

Если у вас все еще есть проблемы, я бы внимательно посмотрел на BITMAPINFO и таблицу цветов, которую вы предоставляете, чтобы убедиться, что они правильно представляют формат данных пикселей и соответствующую таблицу цветов.

1

Другие решения

О, я думаю, что я понял виновника: другая проститутка DxWnd притворялась RC_PALETTE способность в GetDeviceCaps(), Удаление этой фальшивой способности игра больше не пытается использовать DIB_PAL_COLORS форматировать и строить более управляемым DIB_RGB_COLORS Бабки. Проблема исправлена, прошу прощения за ложный след и спасибо за помощь.

0

По вопросам рекламы [email protected]