Directx input что это
DirectInput представляет собой DirectX API для работы с устройствами ввода — клавиатурой, мышью, джойстиками, рулями, авиационными рукоятками, шлемами виртуальной реальности и даже устройствами с обратной связью. В полном соответствии с идеологией DirectX библиотека DirectInput проектировалась в первую очередь для реализации высокого быстродействия и аппаратной независимости.
Основная задача DirectInput — как можно быстрее обнаружить пользовательский ввод и доставить его приложению. Исключение составляют устройства с обратной связью; для них в DirectInput предусмотрены функции как ввода, так и вывода.
Поддерживаемые устройства
DirectInput поддерживает практически все устройства ввода, подключаемые к PC. Конечно, речь идет лишь о тех устройствах, для которых существуют драйверы DirectInput. Библиотека обеспечивает настолько исчерпывающую поддержку любых устройств ввода, что она (скорее всего) сможет поддерживать и те устройства, которые еще не изобретены.
Я не пытаюсь обсуждать все устройства, поддерживаемые DirectInput, потому что для этого потребовалась бы отдельная книга. Здесь же DirectInput рассматривается как высокопроизводительная альтернатива традиционному механизму Windows для получения данных.
Возможностей DirectInput хватает даже на обнаружение и поддержку аппаратных конфигураций, при которых к одному компьютеру подключается несколько клавиатур и/или мышей. Впрочем, данная тема тоже выходит за рамки этой главы; мы вполне обойдемся основными мышью и клавиатурой.
Быстродействие
Наверное, вас интересует, каким образом DirectInput обгоняет традиционные механизмы Windows. DirectInput однозначно приходится выбирать для устройств, не поддерживаемых Win32 API, но зачем использовать его для работы с мышью и клавиатурой?
DirectInput, как и DirectDraw, обходит традиционные механизмы Windows и обеспечивает прямой доступ к устройствам, не утрачивая аппаратной независимости. Поскольку Windows в этой схеме не используется, установленные в системе параметры устройств ввода (например, частота повтора символов для клавиатуры или чувствительность мыши) не влияют на DirectInput.
Схемы получения данных
В зависимости от потребностей вашего приложения DirectInput может использоваться для получения данных двух видов: непосредственных (immediate) и буферизованных (buffered). Непосредственные данные описывают состояние устройства ввода на момент запроса данных, а буферизованные данные используют концепцию очереди для описания изменений в состоянии устройства (например, нажатий клавиш или осевых смещений).
С помощью непосредственных данных можно, например, определить, нажата ли некоторая клавиша в данный момент. Для клавиатуры получение непосредственных данных напоминает применение функции Win32 GetAsyncKeyState(). Непосредственные данные лучше всего работают при частом опросе устройства ввода (как правило, не реже 30 раз в секунду). Редкий опрос может привести к потере данных; если за время нахождения клавиши в нажатом состоянии клавиатура не опрашивалась, то приложение не узнает о наличии ввода.
С другой стороны, буферизованные данные получают весь ввод от устройства и помещают каждое событие в очередь. Ваше приложение может в любой момент просмотреть содержимое очереди. Каждый элемент содержит порядковый номер, по которому можно определить последовательность событий (если только события не произошли одновременно, в этом случае они будут иметь одинаковые порядковые номера). Буферизация данных предотвращает их потерю (это может произойти разве что при переполнении буфера).
Каждая форма получения данных обладает своими достоинствами и недостатками, и только вы можете решить, какая из них лучше подходит для вашего приложения. В некоторых приложениях встречаются обе формы. Например, буферизованные данные применяются для меню и общего управления приложением, а непосредственные данные — в оптимизированном ядре. В этой главе непосредственные данные используются в программе Qwerty, а буферизованные — в программе Smear.
Опросы и оповещения
Независимо от конкретной схемы приложение в какой-то момент должно получить данные. Чаще всего это делается путем опроса ( polling ) устройства через подходящие промежутки времени. Например, приложение может проверять наличие новых данных (непосредственных или буферизованных) при каждом обновлении экрана.
Кроме опроса устройств существует и альтернативный вариант — оповещение ( notification ). В этом случае программный поток (thread) блокируется и ожидает поступления оповещающего события. С наступлением такого события поток автоматически активизируется. Оповещение позволяет приложению реагировать на изменения в состоянии устройства ввода без расходов процессорного времени, связанных с опросом.
Для однопоточных приложений оповещение используется редко, потому что во время ожидания события поток блокируется и не может ничего делать. Если только вся работа приложения не сводится к получению ввода от пользователя, для оповещения потребуется по крайней мере два потока. В программах этой главы оповещение не используется, однако мы встретимся с ним в главе 7.
Уровни кооперации
Чтобы приложение могло задать нужную степень контроля над устройством, в DirectInput используются уровни кооперации. DirectInput, как и DirectDraw, позволяет установить монопольный (exclusive) и совместный (nonexclusive) режим доступа для каждого устройства. Если приложение DirectInput обладает монопольным доступом к устройству ввода, то никакое другое приложение заведомо не сможет получить монопольного доступа к тому же устройству (хотя сможет получить совместный доступ).
DirectInput также позволяет задать уровень кооперации для активного (foreground) и фонового (background) режимов работы — эти два термина часто приводят к недоразумениям. Активный доступ (foreground access) означает, что приложение работает с устройством только тогда, когда обладает фокусом ввода (по аналогии с тем, как ввод с клавиатуры по умолчанию передается приложению, обладающему фокусом). Фоновый доступ (background access) означает, что приложение может обращаться к устройству независимо от того, обладает ли оно фокусом ввода. Интуитивно кажется, будто активный доступ обладает большими возможностями, но на самом деле это не так. В программах Qwerty и Smear используется совместный активный уровень кооперации.
Данные об осевых смещениях
Устройство, возвращающее информацию об осевых смещениях (например, мышь или джойстик), можно настроить так, чтобы оно возвращало относительные или абсолютные данные. Относительные осевые смещения описывают перемещение по данной оси по отношению к предыдущему положению, а абсолютные — текущую позицию по данной оси.
По умолчанию мышь возвращает относительные данные, а джойстик — абсолютные. В программе Smear для мыши используется установка по умолчанию, однако следует помнить о том, что тип данных можно изменить как для джойстика, так и для мыши.
Захват устройств
Приложение DirectDraw в случае необходимости может уступить видеопамять другому приложению и восстановить ее, когда исходное приложение снова получит фокус. В DirectInput приложение тоже может потерять устройство и восстановить контроль над ним перед тем, как продолжить работу. В таких случаях говорят, что приложение захватывает устройство (acquire) или уступает его (unacquire). Для получения данных необходимо захватить устройство. Приложение может уступить устройство по требованию (доступ к устройству передается Windows или другому приложению) или автоматически (например, если DirectInput отбирает право доступа к устройству, чтобы передать его другому приложению).
Некоторые устройства (особенно клавиатуры и мыши) регулярно захватываются и уступаются приложениями. Обычно они уступаются автоматически в тот момент, когда приложение теряет фокус. Когда ваше приложение опять получает фокус, оно должно снова захватить устройство.
Ксинпут — это API, позволяющий приложениям принимать входные данные от контроллера Xbox для Windows. В этом документе описываются различия между реализациями Ксинпут и директинпут в контроллере Xbox, а также способы поддержки устройств ксинпут и устаревших устройств директинпут.
использовать устаревшие директинпут не рекомендуется, и директинпут недоступен для приложений магазина Windows.
Новый стандарт: Ксинпут
Ксинпут теперь доступен для разработки игр. Это новый стандарт ввода для Xbox и Windows. интерфейсы api доступны в пакете SDK для DirectX, и драйвер доступен в Центр обновления Windows.
Использование Ксинпут вместо директинпутимеет несколько преимуществ.
- Ксинпут проще в использовании и требует меньше настроек, чем директинпут
- как для Xbox, так и для Windowsного программирования будут использоваться одни и те же наборы основных api, что позволяет значительно упростить программирование между различными платформами.
- Будет установлена большая база установки контроллеров Xbox.
- Устройства Ксинпут (т. е. контроллеры Xbox) будут иметь функцию вибрации только при использовании интерфейсов API Ксинпут.
- Будущие контроллеры, выпущенные для консоли Xbox (то есть колеса управления), также будут работать на Windows
Параллельная Ксинпут и Директинпут
Только поддержка Ксинпут, ваша игра не будет работать с устаревшими устройствами директинпут . Ксинпут не сможет распознать эти устройства.
Если вы хотите, чтобы ваша игра поддерживала устаревшие устройства директинпут , вы можете использовать параллельно Директинпут и ксинпут. При перечислении устройств Директинпут все устройства Директинпут будут перечисляться правильно. Все устройства Ксинпут будут отображаться как устройства Ксинпут и Директинпут, но их не следует обрабатывать с помощью Директинпут. Вам потребуется определить, какие из устройств Директинпут являются устаревшими устройствами, а какие — Ксинпут устройствами, и удалить их из перечисления Директинпут устройств.
Для этого вставьте этот код в обратный вызов перечисления Директинпут:
Немного улучшенная версия этого кода находится в примере устаревшей Директинпут джойстика .
DirectX Graphics, набор интерфейсов, ранее (до версии 8.0) делившихся на:
DirectDraw: интерфейс вывода растровой графики. (Его разработка давно прекращена)
Direct3D (D3D): интерфейс вывода трёхмерных примитивов.
DirectInput: интерфейс, используемый для обработки данных, поступающих с клавиатуры, мыши, джойстика и пр. игровых контроллеров.
DirectPlay: интерфейс сетевой коммуникации игр.
DirectSound: интерфейс низкоуровневой работы со звуком (формата Wave)
DirectMusic: интерфейс воспроизведения музыки в форматах Microsoft.
DirectShow: интерфейс, используемый для ввода/вывода аудио и/или видео данных.
DirectX Instruments — технология, позволяющая на основе мультимедийного API DirectX создавать и использовать программные синтезаторы. В отличие от DX-плагинов, такие программы могут полностью управляться по MIDI и служат главным образом не для обработки, а для синтеза звука. Технология DXi была популярна в 2001—2004 гг. , особенно в программных продуктах Cakewalk, но со временем проиграла «войну форматов» технологии VST от Steinberg.
DirectSetup: часть, ответственная за установку DirectX.
DirectX Media Objects: реализует функциональную поддержку потоковых объектов (например, кодировщики/декодировщики)
Direct2D : интерфейс вывода двухмерной графики
• С точки зрения Microsoft, DirectX – это набор низкоуровневых программных интерфейсов для создания игр и других высокопроизводительных мультимедиа-приложений. Включает поддержку высокопроизводительной 2D- и 3D-графики, звука и устройств ввода.
• С точки зрения программиста, DirectX – это набор драйверов, образующих интерфейс между программами в среде Windows и аппаратными средствами.
• С точки зрения обычного «юзера» , DirectX – это такая «ускорительная фича» , без которой игры и другие мультимедиа-приложения сильно «тормозят» .
DirectX сильно облегчает жизнь программистам, делает более комфортной жизнь геймеров и обычных пользователей.
=================================================================
– Что такое Microsoft DirectX?
– Microsoft DirectX – это Мелко-мягкий Прямой X – инструмент разработчика Билла Гейтса… =))
DirectX — это набор API-функций, разработанных для решения задач, связанных с игровым и видеопрограммированием под Microsoft Windows. Наиболее широко используется при написании компьютерных игр. Пакет средств разработки DirectX под Microsoft Windows бесплатно доступен на сайте Microsoft. Зачастую обновленные версии DirectX поставляются вместе с игровыми приложениями, так как DirectX API обновляется достаточно часто, и версия, включённая в ОС Windows, обычно является далеко не самой новой.
Любая программа без пользовательского ввода превращается в статическую картинку, а то и в слайд шоу или кино. Но ведь мы смотрим не телевизор - даешь интерактивность! Именно эту проблему мы и будем сегодня обсуждать. Для нашего обсуждения я не стал сочинять чего-нибудь необычного - я воспользовался примерами из DirectX 7 SDK. Они достаточно хорошо иллюстрируют то, с чем мы сегодня столкнемся. Для начала обговорим условия компиляции и линковки приложений - кроме используемой нами DINPUT.LIB, при линковке тебе нужно будет включить в проект DXGUID.LIB для приложений, у которых не определена INITGUID (Использование INITGUID - старый стиль включения GUID номеров в приложение, использующее COM модель).
Ну, а для начала немного теории. Для чего нужны функции DirectInput, ты уже знаешь. Чем же DirectInput API лучше, чем стандартные возможности, предоставляемые приложению ядром? Ну, конечно своей скоростью и своими возможностями:
Рассмотрим схему инициализации для DirectInput. Поскольку DirectInput как и практически все компоненты DirectX построен на основе модели COM от Microsoft, общая структура работы с API ничем не будет отличаться от работы с другими компонентами DirectX API. Первое, что должно сделать приложение, использующее DirectInput API, это получить доступ к объекту DirectInput через соответствующий интерфейс. Сделать это можно вызовом DirectInputCreate() или DirectinputCreateEx(). Во всех примерах MS кроме одного используется первый вариант. Вариант два появился в версии DirectX 7.0. Рассмотрим параметры этих функций. Для этого ты можешь воспользоваться документацией.
hInst - идентификатор экземпляра самого приложения получаемый в WinMain().
dwVer - версия объекта DirectInput. Обычно подставляется макроопределение DIRECTINPUT_VERSION заранее определенное в DINPUT.H для установленной версии DirectX SDK.
lplpDI - указатель на указатель интерфейса, который примет в себя информацию.
pU - указатель наследования или агрегирования COM. Нас он не интересует - достаточно передать NULL.
hInst - то же, что и для варианта DirectInputCreate()
dwVer - то же, что и для варианта DirectInputCreate()
ri - идентификатор требуемого интерфейса. Может принимать значения IID_IDirectInput,IID_IDirectInput2,IID_IDirectInput7.
ppO - указатель на указатель интерфейса, который примет в себя информацию. Аналогичен с последним параметром предыдущей функции.
pU - указатель наследования или агрегирования COM. Аналогичен с последним параметром предыдущей функции.
Как ты видишь — все достаточно просто. После получения указателя на интерфейс, нужно "создать" устройство от которого ты хочешь получать данные. Под устройством подразумевается все, что поддерживает DirectInput, например клавиатура, мышь, джойстики и т.п. Для создания устройств также существуют две функции - CreateDevice() и ее -Ex вариант (появился в 7 версии DirectX):
CreateDevice(REFGUID rg,LPDIRECTINPUTDEVICE *lplpDI,LPUNKNOWN pU);
rg - уникальный идентификатор устройства. Если ты еще не привык, что вся работа идет с некими Global Unique IDentifer'ами, советую поскорее привыкнуть ;). Для стандартных устройств заранее определены значения: GUID_SysKeyboard для клавиатуры; GUID_SysMouse для мыши. Остальные идентификаторы устройств (например джойстики) можно получить вызовом EnumDevices().
lplpDI - указатель на указатель интерфейса, с помощью которого мы будем впоследствии работать с устройством.
pU - все то же агрегирование.
CreateDeviceEx(REFGUID rg,REFIID ri,LPVIOD *ppO,LPUNKNOWN pU);
rg - то же, что и в первом случае.
ri - идентификатор требуемого интерфейса. Может принимать значения IID_IDirectInput,IID_IDirectInput2,IID_IDirectInput7.
ppO - указатель на указатель интерфейса, который примет в себя информацию. Аналогичен параметру lplpDI предыдущей функции.
pU - указатель наследования или агрегирования COM. Аналогичен с последним параметром предыдущей функции.
После того, как мы получили указатель на интерфейс устройства, воспользуемся им для установки формата данных для этого устройства. Функция SetDataFormat() получает всего один параметр - указатель на структуру описывающую формат данных для устройства. Для стандартных устройств заранее определены глобальные переменные: c_dfDIKeyboard, c_dfDIMouse, c_dfDIMouse2, c_dfDIJoystick, c_dfDIJoystick2. Итак - формат данных установлен - DirectInput знает тип устройства. Что же теперь? А теперь мы должны установить уровень доступа. Довольно важно определиться заранее (как и с форматом принимаемых данных) - какой доступ необходим.
Что еще полезно знать:
char cDummy = cBuff[DIK_ESCAPE];
занесет в сDummy байт данных по клавише Esc. Для определения нажата ли клавиша, достаточно проверить последний бит этого байта:
Для того, что бы установить буферизированный ввод с клавиатуры, после установки уровня кооперации нужно установить размер буфера:
где BUFFER_SIZE - размер буфера.
По умолчанию мышь возвращает относительные координаты, а джойстик абсолютные.
По завершении приложения ты должен "убрать за собой" - "уступить" все устройства, и удалить объекты DirectInput вызовом Release().
Это был лишь небольшой обзор, и в нем много чего было опущено (например, те же устройства с обратной связью (Force Feedback)). Не смотря на это, он должен был дать тебе достаточно информации для дальнейшего глубокого изучения.
DirectInput — это часть DirectX, которая обрабатывает все формы ввода от игрока. Вы можете управлять мышью, клавиатурой, джойстиками, устройствами с обратной связью и многими другими типами устройств ввода. Для каждого типа контроллера имеется связанный с ним объект устройства. Для каждого объекта устройства вы создаете его экземпляр. Все это показано на рис. 9.1.
Рис. 9.1. Объекты DirectInput
На рис. 9.1 изображен главный объект DirectInput с двумя объектами устройств. Левый объект является мышью, а правый — клавиатурой. Под мышью изображен экземпляр объекта устройства, представляющий кнопки мыши. Под клавиатурой находится экземпляр объекта устройства, представляющий клавиши клавиатуры.
Интерфейс IDirectInput8
Рабочей лошадкой DirectInput является интерфейс IDirectInput8. Это COM-объект, отвечающий за настройку среды ввода. После того, как вы создали объект DirectInput можно создавать устройства для объекта. Как же можно создать этот объект? С помощью следующего кода:
Из приведенного кода видно, что объект DirectInput создает функция DirectInput8Create(). Вот как выглядит прототип этой функции:
В первом параметре, hinst, должен передаваться дескриптор текущего экземпляра вызывающего приложения. В приведенном выше фрагменте кода я передаю глобальный указатель экземпляра с именем g_hInstance. Он содержит экземпляр приложения и инициализируется в главной функции окна.
Следующий параметр, dwVersion, содержит номер версии DirectInput, которую вы намереваетесь использовать. В приведенном выше примере я использую глобальную константу с именем DIRECTINPUT_VERSION. Ее значение равно 0x0800, и это значит, что мы намереваемся использовать DirectInput версии 8.
Третий параметр, riidltf, передает уникальный идентификатор интерфейса. Для DirectX 8 и 9 вы должны использовать идентификатор IID_IDirectInput8.
Четвертый параметр, ppvOut, содержит адрес указателя в котором будет сохранена ссылка на объект DirectInput. Для этого параметра я использую глобальный указатель с именем pDI. Тип указателя pDI — LPDIRECTINPUT8.
Последний параметр, punkOuter, используется для указания на интерфейс IUnknown COM-объекта. Я всегда передаю в этом параметре значение NULL, и вы можете поступать так же.
Если работа функции завершена успешно, она возвращает значение DI_OK.
Интерфейс IDirectInputDevice8
Объект DirectInput создает устройства в виде объектов интерфейса IDirectInputDevice8. Интерфейс IDirectInputDevice8 выполняет большую часть работы по поддержке конкретного устройства. Чтобы создать интерфейс устройства вы должны вызвать метод CreateDevice() главного объекта DirectInput. Вот как выглядит его прототип:
В первом параметре, rguid, передается GUID создаваемого устройства. Для этой цели каждый тип устройств в DirectX имеет свой собственный GUID. Если вы хотите создать интерфейс клавиатуры, передайте в этом параметре идентификатор GUID_SysKeyboard. Чтобы создать интерфейс мыши, передайте идентификатор GUID_SysMouse.
Второй параметр, lplpDirectInputDevice, представляет собой указатель на указатель на создаваемое новое устройство. В своих примерах я передаю указатель с именем pKeyboard типа LPDIRECTINPUTDEVICE8.
Последний параметр применяется для COM, и большинство людей просто передают здесь NULL.
В случае успешного завершения функция возвращает значение DI_OK.
Использование контроллера Xbox с Директинпут
Контроллер Xbox правильно перечислен в директинпути может использоваться с директинпутапис. Однако некоторые функции, предоставляемые Ксинпут, будут отсутствовать в реализации Директинпут:
- Левая и правая кнопки триггера будут действовать как одна кнопка, а не независимо друг от друга.
- Эффекты вибрации будут недоступны
- Запросы для головных устройств будут недоступны.
Сочетание левого и правого триггеров в директинпут — это проектирование. Игры всегда предполагают, что оси устройств Директинпут будут центрированы при отсутствии взаимодействия с пользователем с устройством. Однако контроллер Xbox был разработан для регистрации минимального значения, а не по центру, если триггеры не удерживаются. Поэтому более старые игры подразумевают взаимодействие с пользователем.
Решением было объединение триггеров, установка одного триггера в положительном направлении, а другое — отрицательное направление, поэтому вмешательство пользователя не директинпут , что элемент управления находится в центре.
Чтобы проверить значения триггера по отдельности, необходимо использовать Ксинпут.
Читайте также: