Я являюсь автором инструмента 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?
Если я правильно понимаю вопрос, у вас есть исходное изображение в виде DIB с таблицей цветов, и вы хотите перенести это изображение в непалитровый DC с помощью SetDIBitsToDevice.
Я не работал с палитрами в течение очень долгого времени, но, если я правильно помню, вы не можете использовать DIB_PAL_COLORS, если конечный DC не является устройством палитры. Кажется маловероятным, что ваш DC памяти является устройством палитры, но вы можете проверить:
GetDeviceCaps(hTempDc, RASTERCAPS) & RC_PALETTE
Предполагая, что это не устройство палитры, я думаю, что вы должны использовать DIB_RGB_COLORS для fuColorUse. SetDIBitsToDevice будет использовать индекс каждого пикселя для поиска соответствующего значения RGBQUAD в таблице цветов. (Таблица цветов следует после BITMAPINFOHEADER в BITMAPINFO, на который указывает lpbmi.) Значения RGBQUAD применяются попиксельно к устройству назначения.
Если у вас все еще есть проблемы, я бы внимательно посмотрел на BITMAPINFO и таблицу цветов, которую вы предоставляете, чтобы убедиться, что они правильно представляют формат данных пикселей и соответствующую таблицу цветов.
О, я думаю, что я понял виновника: другая проститутка DxWnd притворялась RC_PALETTE
способность в GetDeviceCaps()
, Удаление этой фальшивой способности игра больше не пытается использовать DIB_PAL_COLORS
форматировать и строить более управляемым DIB_RGB_COLORS
Бабки. Проблема исправлена, прошу прощения за ложный след и спасибо за помощь.