C++ 使用AMD Quad Buffer SDK查看3D图像-DirectX 9

C++ 使用AMD Quad Buffer SDK查看3D图像-DirectX 9,c++,winapi,directx,stereo-3d,C++,Winapi,Directx,Stereo 3d,我目前在一个项目上工作,我需要使用Bumblebee2 3D相机拍摄的图像显示3D图像。我在MSI AE2420计算机上工作,它有AMD HD 5730和3D支持。我还有一个快门玻璃,可以在立体模式下查看图像 我使用的是DirectX9库(d3dx9.h)。IDE是VS2008快速版 我有样本图像(左和右),我将它们与行一起成功地导入到程序中 pDevice->CreateOffscreenPlainSurface(IMAGE_WIDTH,IMAGE_HEIGHT,D3DFMT_A8R8G

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

我使用的是DirectX9库(d3dx9.h)。IDE是VS2008快速版

我有样本图像(左和右),我将它们与行一起成功地导入到程序中

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不允许有源四缓冲立体声。因此我不能使用四个缓冲区(左前、左后、右前、右后)。这就是AMD的四缓冲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);
    }

我想你应该试试

viewPort.Height = lineOffset;
而不是

viewPort.Height = WINDOW_HEIGHT;

您应该在rightImageBuffer的StretchRect调用之前和之后调用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在StretchRect调用中为BackBuffer设置正确的目标矩形。这可能在根本不更改视口的情况下工作


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

我使用与AMD的文档完全不同的方法解决了这个问题。我认为他们SDK中的函数不能正常工作。我试图在文档中遵循这些步骤完全是浪费时间

这里是该项目的链接


我也试过了。它没有改变任何东西。即使是AMD也没有提供任何合适的图像或视频立体声文档。他们的论坛只是螃蟹。他们不回答任何问题!从现在起,我将远离AMD。nVidia有很多简单的文档,他们的签名可以通过swap命令直接写入VRAM,所以用户可以这样做不需要编写额外的交换函数。我还在做这个。我试着在OpenGL上启动这个项目,但仅仅因为IZ3D不允许AMD上使用OpenGL立体声,我甚至无法启用立体声模式!我也试过了,但没有任何变化。因为我删除了Clear()声明。我不认为AMD立体声命令工作正常。因为它们不会产生任何效果。此外,这一行启用立体声;pDevice->CreateOffscreenPlainSurface(10,10(D3DFORMAT)FOURCC_AQBS,D3DPOOL_DEFAULT,&driverCommSurface,NULL);而不是SendStereoCommand(ATI_stereo_ENABLESTEREO,…)我按照您所说的方式更改了程序,但是在正确的部分,仍然没有图像。有很多if语句检查HRESULT值,看起来一切正常。但是lineOffset不是一个很大的值,它等于204。我在调试时发现了它。是的,它可以工作。但是,如果我删除ENABLE,这并不重要_正确或启用立体声语句,演示仍然在立体声模式下工作。这真的很有趣