| Summary: | У курсора мыши розовый фон | ||
|---|---|---|---|
| Product: | WINE@Etersoft | Reporter: | Илья Шпигорь <shpigor> |
| Component: | 3D-графика; GL; DirectX | Assignee: | BUGS@Etersoft <bugs> |
| Status: | DEFERRED --- | QA Contact: | |
| Severity: | normal | ||
| Priority: | P2 | CC: | kondratyuk, lav, vitperov |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | All | ||
| URL: | http://bugs.winehq.org/show_bug.cgi?id=23750 | ||
| Whiteboard: | |||
| Заявки RT: | Связано с: | ||
| Дата напоминания: | |||
| Bug Depends on: | 6565 | ||
| Bug Blocks: | 6219 | ||
| Attachments: |
Патч
Скриншот |
||
|
Description
Илья Шпигорь
2010-10-18 12:15:40 MSD
Проблема в том, что в wine не реализован механизм, который делает из розового цвета загружаемой картинки прозрачный. Т.е. сейчас wine загружает картинку курсора из файла и просто отрисовывает ее поверх фона. За отрисовку курсора отвечает библиотека wined3d. user32 тут не при чем. Приложение для вывода курсора использует интерфейс IDirectDrawSurface. ColorKey задается функцией IDirectDrawSurface::SetColorKey. После этого указанный цвет (в данном случае 0xFF00FF) становится прозрачным. Отрисовка курсора происходит в функции IDirectDrawSurface::Blt. В процессе работы она вызывает функцию GL - glAlphaFunc. Возможно, проблема в том, что ей передается неправильный параметр. GL не поддерживает color key напрямую, т.е. ему нельзя просто сказать какой цвет сделать прозрачным. Поискал решений этой проблемы. Нашел только два варианта: 1) Использовать SDL для первоначальной загрузки картинки, а потом передавать картинку GL. SDL умеет работать с color key 2) Пройти в цикле по всем пикселям и сделать прозрачными те, у которых определенный цвет Есть еще 3-е решение. Картинки с курсорами хранятся в png файлах, которые поддерживают alpha канал. Если разработчик просто заменит розовый цвет фона на прозрачный - проблема будет решена. Но не известно, как это будет работать в windows. Сделал проход в цикле по всем пикселям текстуры. Если цвет пикселя равен color key, его альфа канал выставляется в ноль. Created attachment 1881 [details]
Патч
Нужно исправить:
1. Обход цикла по смещению, а не по координатам
2. Проверка цвета через указатель на buffer типа DWORD
This is problem with color key processing. All cursor images in the application have color key 0xFF00FF what must became transparent on drawing. Wine doesn't implement color key processing now. Only alpha channel is processed i.e. the cursor images must have transparent background instead the 0xFF00FF. This patch add color key processing. The loaded texture (cursor image) is parsing to pixels. Ech pixel is compared with defined color key. The alpha channel of the pixel is set to null if its color is the same as color key. Created attachment 1882 [details]
Скриншот
Проверил на текущей версии оригинального wine - эта бага и 6221 воспроизводятся. Исправил патч. Теперь должен прикладываться к текущему wine. Выложил все в репозиторий: git.eter:/people/shpigor/packages/wine-games.git По этой баге осталось: 1) Оптимизировать (модифицировать текстуру при загрузке из файла, а не при каждой отрисовке) 2) Отправить патч на winehq (In reply to comment #10) > 1) Оптимизировать (модифицировать текстуру при загрузке из файла, а не > при каждой отрисовке) Сделал. Теперь perform_color_key вызывается из surface_load_location, т.е. в момент загрузки текстуры. Отправил патч на winehq. Из замечаний и дальнейших исследований стало ясно: 1) Обработка color key уже есть в методе d3dfmt_convert_surface 2) Метод d3dfmt_convert_surface не вызывается, т.к. приложение сообщает формат картинки курсора мыши WINED3DFMT_B8G8R8A8_UNORM (альфа канал есть), вместо WINED3DFMT_B8G8R8X8_UNORM (альфа канала нет, последние 8 бит для выравнивания). Делал тест для проверки функции CreateSurface. На данный момент тест собирается, но файл ресурсов не используется. Сделал тест. В отличие от SpongeBob2 в тесте color key корректно обрабатывается несмотря на то, что приложение сообщает тип поверхности WINED3DFMT_B8G8R8A8_UNORM (т.е. альфа канал есть). Создание поверхности в тесте и в SpongeBob2 происходит одинаково, но их вывод реализован по-разному. Получается, ошибка происходит не на этапе создания поверхности, а в момент ее вывода. У интерфейса IDirectDrawSurface в Wine есть 2 алгоритма блиттинга: Blt и BltFast. В алгоритме Blt предполагается, что если у поверхности есть альфа канал, то color key использовать нельзя. В алгоритме BltFast никаких предположений о характере поверхностей вообще нет, т.е. color key обрабатывается всегда. Поэтому в тесте (где используется BltFast) - color key отрабатывает для поверхности с альфа каналом, а в SpongeBob2 (где используется Blt) этого не происходит. В MSDN'е на страничке про альфа блиттинг http://msdn.microsoft.com/en-us/library/aa915435.aspx есть такие слова: Source color keying cannot be used with a source surface that has an alpha channel. Similarly, destination color keying cannot be used with a destination surface that has an alpha channel. Но, насколько понимаю, это относится к методу IDirectDrawSurface::AlphaBlt (который кстати в Wine сейчас не реализован). Насколько понимаю, этот метод как раз и нужен для блиттинга между поверхностями с и без альфа канала. Есть подозрение, что это замечание к методу IDirectDrawSurface::Blt не относится. Собственно осталось это проверить тестом. Обновил свой репозиторий wine-games.git. Сейчас там приложен новый патч на эту багу, разрешающий блиттинг для поверхностей с альфа каналом и старый патч на 6221. Удалось протестировать на компьютере с Windows. В Vbox не поддерживается аппаратная работа с прозрачными поверхностями, т.е. поверхности с альфа каналом не выводятся на экран. В результате выяснилось - функция IDirectDrawSurface::Blt не обрабатывает color key для поверхностей с альфа каналом. Надо еще потестировать с различными флагами, возможно они изменяют это поведение. Выяснил, что в примере и в SpongeBob создаются разные типы поверхностей (SURFACE_GDI и SURFACE_OPENGL соответственно). Поэтому поведение функции Blt может для них отличаться. Функция Blt для поверхности SURFACE_OPENGL под Windows обрабатывает color key для поверхностей с альфа каналом. Для поверхности SURFACE_GDI - тоже обрабатывает color key. Проверял на компьютере, который стоит рядом с atlant. Странно, что в комментарии 18 для SURFACE_GDI результат был другой - color key не обрабатывался (проверялось на ноутбуке mid@). Протестировал на Windows 7 (в которой вроде как интегрирован directx 10). Результаты тестов прямо противоположные: Для поверхностей SURFACE_GDI и SURFACE_D3D с альфа каналом color key не обрабатывается. Думаю надо ориентироваться на результат полученный на Windows XP и DirectX 9.0 (комментарий 20). Сделал в репозитории две ветки: 1. master - с "правильным" патчем. Сейчас выглядит очень плохо из-за того, что бага 6568 начала воспроизводится для всех курсоров. 2. stable - ветка с хаком. Работает более-менее сносно. Баг 6568 практически не заметен (проявляется только для одного вида курсора). Откладываем, bugs@ в ближайшее время делать ничего не будет. |