Лучшие практики для поддержки Alt-Tab в приложении DirectX?
При написании приложений DirectX, очевидно, желательно поддерживать пользователя, приостанавливающего приложение через Alt-Tab, таким образом, чтобы он был быстрым и безошибочным. Каков наилучший набор методов для обеспечения этого? Вещи, которые необходимо решить, включают в себя:
- Лучшие методы определения того, когда ваше приложение было выделено и когда оно было возвращено.
- Какие ресурсы DirectX теряются, когда пользователь alt-tabs, и лучшие способы справиться с этим.
- Основные вещи, которые нужно сделать, и вещи, которых следует избегать в архитектуре приложения в целях поддержки alt-tab.
- Любые существенные различия между основными версиями DirectX в том, что касается вышеизложенного.
Интересные трюки и ошибки также хорошо слышать.
4 ответа
Я предполагаю, что вы используете C++ для моих ответов, но если вы можете позволить себе использовать C#, XNA ( http://creators.xna.com/) - отличная игровая платформа, которая решает все эти проблемы для вас.
1]
Эта статья полезна для событий Windows в оконной процедуре, чтобы определить, когда окно теряет или получает фокус, вы можете обработать это в главном окне: http://www.functionx.com/win32/Lesson05.htm. Кроме того, проверьте сообщение WM_ACTIVATEAPP здесь: http://msdn.microsoft.com/en-us/library/ms632614(VS.85).aspx
2]
Графическое устройство теряется, когда приложение теряет фокус из полноэкранного режима. Microsoft предлагает статью о том, как с этим справиться: http://msdn.microsoft.com/en-us/library/bb174717(VS.85).aspx этой статье также есть учебник для потерянных устройств: http://www.codesampler.com/dx9src/dx9src_6.htm
DirectInput также может иметь состояние ошибки устройства, вот ссылка на это: http://www.toymaker.info/Games/html/directinput.html
DirectSound также может иметь состояние ошибки устройства, эта статья содержит код, который обрабатывает: http://www.eastcoastgames.com/directx/chapter2.html
3]
Я бы позаботился о том, чтобы никогда не отключать Alt-Tab. Возможно, вам нужна минимальная загрузка ЦП, когда приложение не активно, потому что пользователь, вероятно, использует Alt-Tabbed, потому что хочет сделать что-то еще, чтобы вы могли полностью приостановить приложение или уменьшить количество кадров, отображаемых в секунду. Если приложение свернуто, вам, конечно, тоже не нужно ничего визуализировать. Подумав о сетевой игре, мое лучшее решение состоит в том, что вы все равно должны уменьшить количество отображаемых кадров в секунду, а также количество обрабатываемых сетевых пакетов, возможно, даже отбрасывая многие входящие пакеты до тех пор, пока игра не будет повторно активирована.
4]
Честно говоря, я бы просто придерживался DirectX 9.0c (или DirectX 10, если вы хотите ограничить целевую операционную систему до Vista и новее), если это вообще возможно:)
Наконец, DirectX SDK содержит множество учебных пособий и примеров: http://www.microsoft.com/downloads/details.aspx?FamilyID=24a541d6-0486-4453-8641-1eee9e21b282&displaylang=en
Мы решили это, вообще не используя полноэкранное устройство DirectX - вместо этого мы использовали полноэкранное окно с самым верхним флагом, чтобы скрыть панель задач. Если вы используете Alt-Tab, вы можете убрать флаг и свернуть окно. Ресурсы текстуры поддерживаются окном.
Тем не менее, этот подход не обрабатывает потерянное событие устройства, происходящее из-за "экрана блокировки", Ctrl+Alt+Delete, подключений к удаленному рабочему столу, переключения пользователей или подобного. Но они не должны обрабатываться очень быстро или эффективно (по крайней мере, так было в нашем приложении)
Все серьезные приложения D3D должны быть способны обрабатывать потерянные устройства, поскольку это может происходить по разным причинам.
В DX10 под Vista есть новая функция "Обнаружение и восстановление тайм-аута", которая, по моему опыту, часто сбрасывает графические устройства, что может привести к потере устройства для вашего приложения. Кажется, это улучшается по мере взросления водителей, но вам все равно придется с этим справляться.
В DX8 и 9 (и 10?), Если вы создаете свои ресурсы (главным образом, вершинные и индексные буферы и текстуры), используя D3DPOOL_MANAGED, они будут сохраняться на потерянных устройствах и не будут нуждаться в перезагрузке. Это связано с тем, что они хранятся в системной памяти, а среда выполнения DX автоматически копирует их в видеопамять. Однако из-за копирования происходит снижение производительности, и это не рекомендуется для быстрого изменения данных вершин. Конечно, вы бы сначала заполнили профиль, чтобы определить, есть ли проблемы со скоростью:-)