我目前正在尝试在Visual Studio 2010 C ++中使用Kinect。 我想学习如何将不同的DirectX源混合在一起。
例如,我获得BackgroundRemovalBasic(来自Kinect SDK 1.8的样本 - 从场景中提取播放器)和LocalDeformablePRT(来自DirectX9 SDK2010样本的样本 - 蝙蝠飞行)。
我目前遇到了一个问题: LocalDeformablePRT示例使用3D和DXUT,而BackgroundRemovalBasic使用2D和构造函数。
我在一个循环中混合了两个样本,它运行良好,但是在两个不同的窗口中。 我试图共享一个窗口(DXUTSetWindow(hWnd,hWnd,hWnd,TRUE);)但我得到了黑色窗口。 请解释一下,如何正确混合样本共享一个窗口? 在DirectX引擎的哪个方面,我应该将它和它混合起来?
以下是我的工作生物的主要部分(我从样本中更改的部分):
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
DXUTSetCallbackD3D9DeviceAcceptable( IsDeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnCreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnResetDevice );
DXUTSetCallbackD3D9FrameRender( OnFrameRender );
DXUTSetCallbackD3D9DeviceLost( OnLostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTCreateDevice( true, 640, 480 );
CBackgroundRemovalBasics application;
application.Run(hInstance, nCmdShow); // BackgroundRemoval by Kinect
return DXUTGetExitCode();
}
int CBackgroundRemovalBasics::Run(HINSTANCE hInstance, int nCmdShow)
{
MSG msg = {0};
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_APP));
wc.lpfnWndProc = DefDlgProcW;
wc.lpszClassName = L"BackgroundRemovalBasicsAppDlgWndClass";
if (!RegisterClassW(&wc)){return 0;}
const HANDLE hEvents[] = {m_hNextDepthFrameEvent, m_hNextColorFrameEvent, m_hNextSkeletonFrameEvent, m_hNextBackgroundRemovedFrameEvent};
HWND hWnd = CreateDialogParamW( hInstance, MAKEINTRESOURCE(IDD_APP), NULL, (DLGPROC)CBackgroundRemovalBasics::MessageRouter, reinterpret_cast<LPARAM>(this) );
// DXUTSetWindow(hWnd, hWnd, hWnd, TRUE); I tried...
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
LoadResourceImage(L"Background", L"Image", m_colorWidth * m_colorHeight * cBytesPerPixel, m_backgroundRGBX);
// MAIN LOOP
while (WM_QUIT != msg.message)
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 )
{
if( TranslateAccelerator( hWnd, NULL, &msg ) == 0)
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else // Render a frame during idle time (no messages are waiting)
{
//--- BackgroundRemoval Kinect ---
MsgWaitForMultipleObjects(_countof(hEvents), hEvents, FALSE, INFINITE, QS_ALLINPUT);
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextBackgroundRemovedFrameEvent, 0)){ComposeImage();}
if ( WAIT_OBJECT_0 == WaitForSingleObject(m_hNextDepthFrameEvent, 0) ){ProcessDepth();}
if ( WAIT_OBJECT_0 == WaitForSingleObject(m_hNextColorFrameEvent, 0) ){ProcessColor();}
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextSkeletonFrameEvent, 0) ){ProcessSkeleton();}
//--- The Bat flying -----------
DXUTRender3DEnvironment();
}
return static_cast<int>(msg.wParam);
}
非常感谢!
答案 0 :(得分:0)
好的。
您要做的是在DXUT应用程序中使用传感器。你真的不需要混合应用程序和共享纹理。您只需使用一个窗口(来自DXUT),并在DXUT渲染器中显示BackgroundRemoval纹理。
为简单起见,BackgroundRemoval示例使用2D渲染器。 LocalDeformablePRT示例使用具有透视投影的3D渲染器。它还使用了一个天空盒,它与BackgroundRemoval样本的静态图像背景不同。您想使用天空盒还是图像背景?
所以,我会说你必须从只关注Kinect传感器的BackgroundRemoval样本中提取源代码。您必须使用该代码初始化Kinect和NuiCreateBackgroundRemovedColorStream。
在您拥有此代码后,当您调用m_pBackgroundRemovalStream-&gt; GetNextFrame时:
BYTE alpha = 0;
const int alphaChannelBytePosition = 3;
for (int i = 0; i < dataLength; ++i)
{
if (i % cBytesPerPixel == 0)
{
alpha = pBackgroundRemovedColor[i + alphaChannelBytePosition];
}
if (i % cBytesPerPixel != alphaChannelBytePosition)
{
m_outputRGBX[i] = static_cast<BYTE>(( (UCHAR_MAX - alpha) * m_backgroundRGBX[i] + alpha * pBackgroundRemovedColor[i] ) / UCHAR_MAX );
}
}
用它来复制D3DTexture9中的图像并用四边形显示它。