如何正确混合DirectX应用程序的输出?

时间:2015-11-17 11:11:42

标签: directx kinect

我目前正在尝试在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);
}

非常感谢!

1 个答案:

答案 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中的图像并用四边形显示它。