//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------
// MSR_NuiApi.hの前にWindows.hをインクルードする
#include <Windows.h>
#include <MSR_NuiApi.h>
#include "DxLib.h"
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
#define WINDOW_SIZE_X 640
#define WINDOW_SIZE_Y 480
void FirstDrawImage(int *GrHandle, HANDLE StreamHandle, BASEIMAGE *BaseImage){
HRESULT hr;
// カメラデータの取得
const NUI_IMAGE_FRAME *ImageFrame = NULL;
hr = NuiImageStreamGetNextFrame( StreamHandle, 0, &ImageFrame );
// 画像データの取得
KINECT_LOCKED_RECT rect;
ImageFrame->pFrameTexture->LockRect( 0, &rect, 0, 0 ); // IDirect3DTexture9 のLockメソッドと同じ?
// Dxlibで使用する画像データの構造体設定
BaseImage->GraphData = rect.pBits;
BaseImage->Pitch = rect.Pitch; // ピッチは横1ラインあたりのByte数
// カメラデータの解放
hr = NuiImageStreamReleaseFrame( StreamHandle, ImageFrame );
ImageFrame->pFrameTexture->UnlockRect(0);
// 最初の場合はグラフィックハンドルの作成と映像の転送を一度に行う
*GrHandle = CreateGraphFromBaseImage( BaseImage ) ;
}
inline void DrawImage(int GrHandle, HANDLE StreamHandle, BASEIMAGE *BaseImage){
HRESULT hr;
// カメラデータの取得
const NUI_IMAGE_FRAME *ImageFrame = NULL;
hr = NuiImageStreamGetNextFrame( StreamHandle, 0, &ImageFrame );
// 画像データの取得
KINECT_LOCKED_RECT rect;
ImageFrame->pFrameTexture->LockRect( 0, &rect, 0, 0 ); // IDirect3DTexture9 のLockメソッドと同じ?
// Dxlibで使用する画像データの構造体設定
BaseImage->GraphData = rect.pBits;
BaseImage->Pitch = rect.Pitch; // ピッチは横1ラインあたりのByte数
// カメラデータの解放
hr = NuiImageStreamReleaseFrame( StreamHandle, ImageFrame );
ImageFrame->pFrameTexture->UnlockRect(0);
// 2回目以降はグラフィックハンドルへ映像を転送
ReCreateGraphFromBaseImage( BaseImage, GrHandle ) ;
DrawExtendGraph(0,0, 640,480, GrHandle, true);
}
//---------------------------------------------------------------------------
// Main
//---------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
HRESULT hr;
// *************************
// DXライブラリ初期化
// *************************
ChangeWindowMode( true ) ; // ウインドウモードに変更
SetUseDirectDrawDeviceIndex( 1 ) ; // 使用する DirectDraw デバイスのインデックスを設定する
SetAlwaysRunFlag( true ); // ウインドウがアクティブではない状態でも処理を続行
SetWaitVSyncFlag( false ); // 垂直同期
SetGraphMode( WINDOW_SIZE_X , WINDOW_SIZE_Y , 32 ) ; // 画面モードの変更
if( DxLib_Init() == -1 ){ // DXライブラリ初期化処理
printfDx("[Dxlib]初期化に失敗しました\n");
WaitKey();
return -1;
}
SetTransColor( 0 , 0 , 0 ) ; // 透過色を変更
SetFontSize( 32 ) ; // 描画する文字列のサイズを設定
printfDx("[Dxlib]Display:%d\n",GetDirectDrawDeviceNum() );// モニタの数を取得
int VideoGrHandle = -1; // DXライブラリのグラフィックハンドル
int DepthGrHandle = -1; // DXライブラリのグラフィックハンドル
BASEIMAGE BaseVideoImage; // DXライブラリ内部で画像を扱うために使用している構造体(カラーカメラ用)
BASEIMAGE BaseDepthImage; // (深さカメラ用)
BaseVideoImage.Width = 640;
BaseVideoImage.Height = 480;
BaseDepthImage.Width = 320;
BaseDepthImage.Height = 240;
// カラーフォーマットは変化しないので最初に設定
CreateARGB8ColorData( &BaseVideoImage.ColorData ); // キネクトからのデータは8bit*4なんでCreateFullColorDataじゃ駄目っぽい
DxLib::CreateGrayColorData( &BaseDepthImage.ColorData ); // 深度データはようわからん(←
BaseDepthImage.ColorData.ColorBitDepth = 16;
BaseDepthImage.ColorData.PixelByte = 2;
BaseDepthImage.ColorData.RedWidth = 0;
BaseDepthImage.ColorData.GreenWidth = 0;
BaseDepthImage.ColorData.BlueWidth = 16;
BaseDepthImage.ColorData.RedLoc = 0;
BaseDepthImage.ColorData.GreenLoc = 0;
BaseDepthImage.ColorData.BlueLoc = 16;
/*
BaseDepthImage.ColorData.RedMask = 255;
BaseDepthImage.ColorData.GreenMask = 255;
BaseDepthImage.ColorData.BlueMask = 255;
*/
// ミップマップではないので0
BaseVideoImage.MipMapCount = 0 ;
BaseDepthImage.MipMapCount = 0 ;
enum { FPS = 30 };
long long OldTime = 0 ; // FPS計測用:1フレーム前の時間
long long NowTime = 0; // FPS計測用:現在時間
double ShowTime = 0; // FPS計測用:表示用変数
long long int FlameCount = 0; //開始からのフレームカウンタ
long long int StartTime; //開始時間
long long int Ideal = 0;
// *************************
// Kinect初期化
// *************************
int count = 0;
MSR_NUIGetDeviceCount( &count ); // Kinectの接続数を確認
printfDx( "[Kinect] Kinect count: %d\n" , count ) ;
// 宣言
HANDLE ImageEvent = ::CreateEvent( 0, TRUE, FALSE, 0 );
HANDLE SkeletonEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
HANDLE DepthEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
HANDLE VideoStreamHandle= NULL;
HANDLE DepthStreamHandle= NULL;
// 初期化 // 深さとユーザー // スケルトン // カメラ
hr = NuiInitialize( NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON | NUI_INITIALIZE_FLAG_USES_COLOR);
if( FAILED(hr) ){
printfDx("[Kinect] 初期化に失敗しました\n");
}
hr = NuiSkeletonTrackingEnable( SkeletonEvent, 0 );
if( FAILED(hr) ){
printfDx("[Kinect] トラッキング処理の初期化に失敗しました\n");
}
// カメラハンドルの取得
hr = NuiImageStreamOpen( NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0, 2, ImageEvent, &VideoStreamHandle );
if( FAILED( hr ) ){
printfDx("[Kinect] ビデオカメラハンドルの取得に失敗しました\n");
}
// 赤外線カメラハンドルの取得
hr = NuiImageStreamOpen( NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, NUI_IMAGE_RESOLUTION_320x240, 0, 2, DepthEvent, &DepthStreamHandle );
if( FAILED(hr) ){
printfDx("[Kinect] デプスハンドルの取得に失敗しました\n");
}
// 最初にグラフィックハンドルの作成を行う
WaitForSingleObject( ImageEvent, INFINITE ); // データの更新を待つ
WaitForSingleObject( DepthEvent, INFINITE );
FirstDrawImage(&VideoGrHandle, VideoStreamHandle, &BaseVideoImage);
FirstDrawImage(&DepthGrHandle, DepthStreamHandle, &BaseDepthImage);
printfDx("\nPress Any Key to Start\n");
WaitKey();
SetDrawScreen( DX_SCREEN_BACK ) ; // グラフィックの描画先を裏画面にセット
StartTime = GetNowHiPerformanceCount(); // FPS計測 開始時間
// Main loop
while(1){
// 画面に描かれているものを一回全部消す
ClsDrawScreen() ;
clsDx() ;
FlameCount++;
// データの更新を待つ
WaitForSingleObject( ImageEvent, INFINITE );
WaitForSingleObject( DepthEvent, INFINITE );
// カメラデータを描画
DrawImage(VideoGrHandle, VideoStreamHandle, &BaseVideoImage); // RGBカメラ
DrawImage(DepthGrHandle, DepthStreamHandle, &BaseDepthImage); // 深度カメラ
//トラッキング
NUI_SKELETON_FRAME SkeletonFrame;
hr = ::NuiSkeletonGetNextFrame( 0, &SkeletonFrame );
for(int i=0; i<NUI_SKELETON_COUNT; i++){
if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED ){
printfDx("found NO = %d\n",i);
NuiTransformSmooth(&SkeletonFrame, NULL); // smoothing filter to the skeleton data
float x=0,y=0;
for(int j=0; j<NUI_SKELETON_POSITION_COUNT; j++){
::NuiTransformSkeletonToDepthImageF( SkeletonFrame.SkeletonData[i].SkeletonPositions[j], &x, &y);
DrawCircle((int)(x*640), (int)(y*480), 5, 0xffffff, true);
}
}
}
NowTime = GetNowHiPerformanceCount();
// FPSカウンター
if(FlameCount%FPS == 0){
ShowTime = (double)(FPS * 1000000) / (double)(NowTime-OldTime);
OldTime = NowTime;
}
printfDx( "%f FPS\n" , ShowTime ) ;
ScreenFlip(); // 1フレーム処理結果の描画
if( ProcessMessage() < 0 ) break; // Windows 特有の面倒な処理をDXライブラリにやらせる // -1 が返ってきたらループを抜ける
if( CheckHitKey( KEY_INPUT_ESCAPE ) ) break; // もしESCキーが押されていたらループから抜ける
}
NuiShutdown(); // 終了処理
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
|