Просмотр 3D-изображения с помощью AMD Quad Buffer SDK - DirectX 9 - PullRequest
2 голосов
/ 05 декабря 2011

В настоящее время я работаю над проектом, и мне нужно отобразить 3D-изображение, используя изображения, снятые 3D-камерой Bumblebee2. Я работаю на компьютере MSI AE2420, и у него есть AMD HD 5730 с поддержкой 3D. У меня также есть стекло затвора для просмотра изображений в стереорежиме.

Я использую библиотеки 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. Поэтому я не могу использовать четыре буфера (левый передний, левый задний, правый передний, правый задний). Вот где используется SDK для четырехъядерных буферов AMD. Они указывают что 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);
    }

Ответы [ 3 ]

1 голос
/ 08 декабря 2011

Я думаю, вы должны попробовать;

viewPort.Height = lineOffset;

вместо

viewPort.Height = WINDOW_HEIGHT;
0 голосов
/ 13 декабря 2011

Я решил проблему, используя совершенно другой метод из документации AMD. И я думаю, что функции в их SDK не работают должным образом.Для меня это была пустая трата времени, чтобы попытаться выполнить эти шаги в документации.

Вот ссылка на проект.

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

0 голосов
/ 08 декабря 2011

Вы должны вызвать SendStereoCommand (ATI_STEREO_SETDSTEYE, ..) до и после вызова StretchRect для rightImageBuffer.

Примерно так:

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, и я думаю, что вам также следует установить правильный прямоугольник назначения в вызовах StretchRect для BackBuffer в соответствии с lineOffset.Это, вероятно, могло бы работать вообще без изменения области просмотра.

Вы должны убедиться, что драйвер возвращает правильное значение для lineOffset (немного больше, чем высота буфера) и HRESULT, возвращаемое из SendStereoCommand ().

...