2

我目前正在做一个项目,我需要使用 Bumblebee2 3D 相机拍摄的图像显示 3D 图像。我正在使用 MSI AE2420 计算机,它具有支持 3D 的 AMD HD 5730。我还有一个快门玻璃以立体模式查看图像。

我正在使用 DirectX 9 库( d3dx9.h )。IDE 是 VS 2008 Express Edition。

我有示例图像(左和右),我用线条将它们连续导入程序;

pDevice->CreateOffscreenPlainSurface(IMAGE_WIDTH,IMAGE_HEIGHT,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&leftImageBuffer,NULL);
pDevice->CreateOffscreenPlainSurface(IMAGE_WIDTH,IMAGE_HEIGHT,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&rightImageBuffer,NULL);

D3DXLoadSurfaceFromFile(leftImageBuffer,NULL,NULL,"left0000.bmp",NULL,D3DX_FILTER_NONE,0,NULL)
D3DXLoadSurfaceFromFile(rightImageBuffer,NULL,NULL,"right0000.bmp",NULL,D3DX_FILTER_NONE,0,NULL)

经过一番研究,我发现 Direct3D9 不允许有源 Quad Buffer 立体声。所以我不能使用四个缓冲区(左前、左后、右前、右后)。这就是 AMD 的 Quad Buffer SDK 涉及的地方。他们表示 DirectX 9也不允许有源立体声,我需要使用 SDK 的功能。我正在使用“AtiDx9Stereo.h”,它是 SDK 中六个头文件之一(其他五个用于 DirectX 11 和 DirectX10)。

但是,经过大量的编码和测试,我终于设法启用了立体声,现在我可以在快门玻璃的左侧看到左侧图像,但在玻璃的右侧我什么都看不到。当我关闭我的对我,我只能看到左图。当我闭上左眼时,我只看到一个黑色页面(或将渲染目标清理为蓝色或其他颜色后的蓝色)。这是我的渲染代码和指针的初始化。如果有人曾在这些环境中工作过,分享一些知识可能会很棒。

初始化语句

pD3D=Direct3DCreate9(D3D_SDK_VERSION);
pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWindow,64,&d3pp,&pDevice);
pDevice->CreateOffscreenPlainSurface(10,10,(D3DFORMAT)FOURCC_AQBS,D3DPOOL_DEFAULT,&driverCommSurface,NULL);
SendStereoCommand(ATI_STEREO_ENABLESTEREO, NULL, 0, 0, 0);
SendStereoCommand(ATI_STEREO_GETLINEOFFSET, (BYTE *)(&lineOffset), sizeof(DWORD), 0, 0);

在这些语句之后,我的 render() 函数是这样的;

D3DVIEWPORT9 viewPort;

    memset(&viewPort,0,sizeof(viewPort));
    pDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backBuffer);
    viewPort.X = 0;
    viewPort.Width = WINDOW_WIDTH;
    viewPort.Height = WINDOW_HEIGHT;

    if(SUCCEEDED(pDevice->BeginScene()))        //Start the device .
    {
        pDevice->SetRenderTarget(0, backBuffer);

        // Draw Right Eye Scene

        viewPort.Y = lineOffset;
        pDevice->SetViewport(&viewPort);
        pDevice->StretchRect(rightImageBuffer,NULL,backBuffer,NULL,D3DTEXF_LINEAR);




        // Draw Left Eye Scene

        viewPort.Y = 0;
        pDevice->SetViewport(&viewPort);
        pDevice->StretchRect(leftImageBuffer,NULL,backBuffer,NULL,D3DTEXF_LINEAR);

        backBuffer->Release();
        pDevice->EndScene();
        // Present both left and right buffers to the driver which will continuously
        // alternate between them until the next present

        pDevice->Present(NULL, NULL, NULL, NULL);





        return S_OK;
    }
    return E_FAIL;

在 WINMAIN 中,我用这些语句调用 render;

MSG msg;                                                    

    while(GetMessage(&msg,NULL,0,0))
    {

        if(str.isReady)                     //If rendering fails,an error-message is shown.
        {
            str.SwitchToRightEye();
            str.pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x000000ff, 1.0f, 0.0f); 
            str.UpdateRightQuadBuffer();
            str.render();

        }

        TranslateMessage(&msg);                     //Translate and dispatch the messages for the getMessage loop.
        DispatchMessage(&msg);
    }
4

3 回答 3

1

我认为你应该尝试;

viewPort.Height = lineOffset;

代替

viewPort.Height = WINDOW_HEIGHT;
于 2011-12-08T12:43:04.870 回答
0

我使用与 AMD 文档完全不同的方法解决了这个问题。而且我认为他们的 SDK 中的功能无法正常工作。尝试遵循文档中的这些步骤对我来说完全是浪费时间。

这是该项目的链接。

http://code.google.com/p/3d-viewer-buffer

于 2011-12-13T14:04:40.270 回答
0

您应该在 StretchRect 调用 rightImageBuffer 之前和之后调用 SendStereoCommand(ATI_STEREO_SETDSTEYE,..)。

像这样的东西:

RECT destRect;

// Draw Right Eye Scene
destRect.top = lineOffset;
destRect.bottom = lineOffset + height;
viewPort.Y = lineOffset;

pDevice->SetViewport(&viewPort);

DWORD dwEye = ATI_STEREO_RIGHTEYE;
SendStereoCommand(ATI_STEREO_SETDSTEYE, NULL, 0, (BYTE *)&dwEye, sizeof(dwEye));

pDevice->StretchRect(rightImageBuffer,NULL,backBuffer,&destRect,D3DTEXF_LINEAR);    

// restore the destination
dwEye = ATI_STEREO_LEFTEYE;
SendStereoCommand(ATI_STEREO_SETDSTEYE, NULL, 0, (BYTE *)&dwEye, sizeof(dwEye)); 

// Draw Left Eye Scene
destRect.top = 0;
destRect.bottom = height;
viewPort.Y = 0;
pDevice->SetViewport(&viewPort);
pDevice->StretchRect(leftImageBuffer,NULL,backBuffer,&destRect,D3DTEXF_LINEAR);

...

并从 WINMAIN 中删除此代码:

str.SwitchToRightEye();
str.pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x000000ff, 1.0f, 0.0f); 
str.UpdateRightQuadBuffer();

更新:

我检查了 iZ3D 驱动程序中的代码,我认为您还应该根据 lineOffset 在 BackBuffer 的 StretchRect 调用中设置正确的目标矩形。这可能可以在根本不改变视口的情况下工作。

您应该检查驱动程序是否为您返回正确的 lineOffset 值(略大于后缓冲区高度)和从 SendStereoCommand() 返回的 HRESULT。

于 2011-12-08T13:25:02.437 回答