Для того чтобы сенсор заработал нужно создать события для каждого из потоков данных, а затем инициализировать сами потоки.
События в C++ - это очень нужная и полезная вещь. Они позволяют сделать нам хорошее многопоточное приложение. Для того, чтобы не тормозить основной поток, мы из другого потока будем получать сведения о том, что кадр уже готов и просто будем забирать этот кадр, вместо того, чтобы ждать его в основном потоке. Для каждого из типов данных нам понадобится одно событие:
- Код: Выделить всё
m_hNextDepthFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // событие, которое будет сигнализировать, о том что данные глубины доступны (данные с IR камеры)
m_hNextColorFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // событие, которое будет сигнализировать, о том что данные цвета доступны (данные с видео камеры)
m_hNextSkeletonEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // событие, которое будет сигнализировать, о том что данные о скелете доступны
Инициализация потоков происходит довольно просто. При помощи флагов указываем какие данные мы хотим получать от устройства:
- Код: Выделить всё
HRESULT result = NuiInitialize(
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | //глубина и индекс фигуры человека
NUI_INITIALIZE_FLAG_USES_SKELETON | //скелет
NUI_INITIALIZE_FLAG_USES_COLOR); //видео с камеры
Как видно, мы можем получать сразу практически все данные: данные с камеры глубины + индекс игрока, скелет и цветное изображение.
Причем, любой из флагов мы можем опустить (просто не указывать) если какие то данные нам не понадобятся. Порядок указания данных тоже роли не играет. В момент инициализации нужно сразу включать все данные которые вы собираетесь использовать.
Далее, для каждого типа данных нам необходимо открыть свой поток при при помощи метода NuiImageStreamOpen:
- Код: Выделить всё
HRESULT NuiImageStreamOpen(
NUI_IMAGE_TYPE eImageType, // тип изображения, который определяет формат данных
NUI_IMAGE_RESOLUTION eResolution, // определяет размеры кадра (об этом далее)
DWORD dwImageFrameFlags_NotUsed, // пока не используется
DWORD dwFrameLimit, // количество кадров, которые будут буферизироваться. Оно не может быть больше чем NUI_IMAGE_STREAM_FRAME_LIMIT_MAXIMUM (сейчас это 4). Рекомендуют использовать значение 2
HANDLE hNextFrameEvent, // событие, которое будет сигнализировать нам о том, что новый кадр сформирован
HANDLE *phStreamHandle // указатель, в который, в случае успешного выполнения, будет записан идентификатор потока
);
Теперь подробнее о разрешении изображения. В документации приведена таблица, которая описывает размеры кадра для каждого из типов данных. Так для NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX разрешение может быть либо 80x60 либо 320x240. Для NUI_IMAGE_TYPE_DEPTH - уже может быть до 640x480. А для NUI_IMAGE_TYPE_COLOR - либо 640x480 либо 1280x1024.
Затем в самой программе мы в цикле будем прокручивать опрос созданных событий и при получении какого либо кадра выводить его, но обо всем этом дальше.
Наверное пока почти ничего не понятно, но дальше, когда мы будем разбирать готовый, рабочий код, надеюсь все встанет на свои места.